اسکریپت تاریخ

تاریخ، یکی از ارکان ورودی اطلاعات و نمایش زمان است، شاید برای افرادی که با تاریخ میلادی کار میکنند، خیلی مورد نیاز نباشد، ولی برای فارسی زبانان، مورد مهمی است، در این سند، سعی بر آن شده ارکان تاریخ و فرهنگ درج توصیح داده شود.

اطلاعات فرهنگ چیست؟

اطلاعات فرهنگ یا همان CultureInfo مجموعه ای از تنظیمات است که به فریم ورک نحوه نمایش اعداد، تاریخ و متون را مشخص میکند.
در حقیقت اطلاعات فرهنگ یک کلاس حاوی اطلاعات زیر است.

interface IWNCultureInfo { readonly displayName: string; readonly englishName: string; readonly threeLetterISOLanguageName: string; readonly twoLetterISOLanguageName: string; readonly DateTimeFormat: { readonly amDesignator: string; readonly abbreviatedDayNames: string[]; readonly abbreviatedMonthNames: { [Calendar: string]: string[] }; readonly dateSeparator: string; readonly dayNames: string[]; readonly firstDayOfWeek: number readonly fullDateTimePattern: string; readonly longDatePattern: string; readonly longTimePattern: string; readonly monthDayPattern: string; readonly monthNames: { [Calendar: string]: string[] }; readonly pmDesignator: string; readonly shortDatePattern: string; readonly shortTimePattern: string; readonly shortestDayNames: string[]; readonly timeSeparator: string; readonly yearMonthPattern: string; readonly holiday: number; }, readonly NumberFormat: { readonly currencyDecimalDigits: number; readonly currencyDecimalSeparator: string; readonly currencyGroupSeparator: string; readonly currencyGroupSizes: number[]; readonly currencyNegativePattern: number; readonly currencyPositivePattern: number; readonly currencySymbol: string; readonly nanSymbol: string; readonly nativeDigits: string[]; readonly negativeInfinitySymbol: string; readonly negativeSign: string; readonly numberDecimalDigits: number; readonly numberDecimalSeparator: string; readonly numberGroupSeparator: string; readonly numberGroupSizes: number[]; readonly numberNegativePattern: number; readonly perMilleSymbol: string; readonly percentDecimalDigits: number; readonly percentDecimalSeparator: string; readonly percentGroupSeparator: string; readonly percentGroupSizes: number[]; readonly percentNegativePattern: number; readonly percentPositivePattern: number; readonly percentSymbol: string; readonly positiveInfinitySymbol: string; readonly positiveSign: string; }, readonly TextInfo: { readonly ansiCodePage: number; readonly cultureName: string; readonly ebcdicCodePage: number; readonly isRightToLeft: boolean; readonly lcid: number; readonly listSeparator: string; readonly macCodePage: number; readonly oemCodePage: number; } }

با ساخت یک کلاس از این جنس، شما میتوانید فرهنگ مد نظر خود را بسازید، ما به طور پیش فرض دو فرهنگ انگلیسی آمریکایی و پارسی ایرانی را به شکل زیر تعریف کردیم.

class WNCultureInfo_fa_IR implements IWNCultureInfo { readonly displayName = 'پارسی'; readonly englishName = 'Persian'; readonly threeLetterISOLanguageName = 'fas'; readonly twoLetterISOLanguageName = 'fa'; readonly DateTimeFormat = { amDesignator: 'ق.ظ', abbreviatedDayNames: ["يكش", "دوش", "س.ش", "چ.ش", "پنج", "جمع", "شنب"], abbreviatedMonthNames: { "WNPersianCalendar": ["فرو", "ارد", "خرد", "تیر", "مرد", "شهر", "مهر", "آبا", "آذر", "دی", "بهم", "اسف", ""], "WNGregorianCalendar": ["ژان", "فور", "مار", "آپر", "می", "جون", "جول", "آگو", "سپت", "اکت", "نوا", "دسا", ""], "WNJulianCalendar": ["ژان", "فور", "مار", "آپر", "می", "جون", "جول", "آگو", "سپت", "اکت", "نوا", "دسا", ""], "WNHijriCalendar": ["محر", "صفر", "راول", "رثانی", "جاول", "جثانی", "رجب", "شعب", "رمض", "شوا", "ذقعده", "ذحجه", ""], }, dateSeparator: '/', dayNames: ["يكشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه"], firstDayOfWeek: 6, fullDateTimePattern: 'dddd, d MMMM yyyy hh:mm:ss tt', longDatePattern: 'dddd, d MMMM yyyy', longTimePattern: 'h:mm:ss tt', monthDayPattern: 'd MMMM', monthNames: { "WNPersianCalendar": ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", ""], "WNGregorianCalendar": ["ژانویه", "فوریه", "مارچ", "آپریل", "می", "جون", "جولای", "آگوست", "سپتامبر", "اکتبر", "نوامبر", "دسامبر", ""], "WNJulianCalendar": ["ژانویه", "فوریه", "مارچ", "آپریل", "می", "جون", "جولای", "آگوست", "سپتامبر", "اکتبر", "نوامبر", "دسامبر", ""], "WNHijriCalendar": ["محرم", "صفر", "ربیع الاول", "ربیع الثانی", "جمادی الاول", "جمادی الثانی", "رجب", "شعبان", "رمضان", "شوال", "ذوالقعده", "ذوالحجه", ""], }, pmDesignator: 'ب.ظ', shortDatePattern: "dd/MM/yyyy", shortTimePattern: "hh:mm tt", shortestDayNames: ["ی", "د", "س", "چ", "پ", "ج", "ش"], timeSeparator: ':', yearMonthPattern: 'MMMM, yyyy', holiday: 5 }; readonly NumberFormat = { currencyDecimalDigits: 2, currencyDecimalSeparator: "/", currencyGroupSeparator: ",", currencyGroupSizes: [3], currencyNegativePattern: 6, currencyPositivePattern: 1, currencySymbol: "ريال", nanSymbol: "ناعدد", nativeDigits: ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"], negativeInfinitySymbol: "-∞", negativeSign: "-", numberDecimalDigits: 2, numberDecimalSeparator: "/", numberGroupSeparator: ",", numberGroupSizes: [3], numberNegativePattern: 1, perMilleSymbol: "‰", percentDecimalDigits: 2, percentDecimalSeparator: "/", percentGroupSeparator: ",", percentGroupSizes: [3], percentNegativePattern: 1, percentPositivePattern: 1, percentSymbol: "%", positiveInfinitySymbol: "∞", positiveSign: "+" }; readonly TextInfo = { ansiCodePage: 1256, cultureName: "fa-IR", ebcdicCodePage: 20420, isRightToLeft: true, lcid: 1065, listSeparator: "؛", macCodePage: 10004, oemCodePage: 720 }; }

در کلاس بالا تقریبا همه موارد روشن و هویدا است، ولیکن چند مورد وجود دارد که قابل توضیح است.

در قسمت DateTimeFormat بایستی، نام بروج را درج کنید، ولیکن هر نوع فرهنگ، از ساختار نوشتاری خود بهره میبرد، برای مثال، اسامی برج ها در فرهنگ انگلیسی بایستی به انگلیسی بوده و در فارسی بایستی به فارسی نمایش داده شود، اگر شما میخواهید فرهنگ عربی بسازید، بایستی اسامی بروج به عربی باشد.

بروج از آرایه 13 عنصری تشکیل شده است، زیرا در برخی از تقویم ها، 13 برج وجود دارد، مانند تقویم اسکندری، اگر تقویم شما 12 برج دارد، فقط 12 گزینه را تعیین کنید و آخری را خالی بگذارید.

برای معرفی اسامی روزها، از ابتدای روز میلادی در نظر گرفته شده است، یعنی یکشنبه، پس اسامی را بر این اساس تنظیم کنید یعنی یکشنبه در آن زبان چه میباشد. در خصوصیت firstDayOfWeek مشخص میکنید، اولین روز هفته در آن فرهنگ از چندمین روز هفته میلادی شروع میشود، برای تشخیص کافیست، طبق ورود اسامی، از صفر شمارده و عددش را مشخص کنید.

در صورتیکه یک فرهنگ جدید ساختید، آنرا برای گسترش بیشتر این فریم ورک برای ما ارسال کنید.

فرهنگ و تقویم پیش فرض

فریم ورک پس از بارگذاری صفحه، به طور خودکار، تقویم و اطلاعات فرهنگ را بر اساس تنظیمات صفحه و مرورگر تعیین میکند، هر چند شما نیز میتوانید، آنها را مشخص کنید.

wnConfig.cultureInfo
اطلاعات فرهنگ پیش فرض، در این متغییر در سطح عمومی معرفی میشود.

wnConfig.calendar
تقویم پیش فرض، در این متغییر در سطح عمومی معرفی میشود.

اگر زبان پیش فرض صفحه یا زبان مرورگر fa باشد، فرهنگ پیش فرض WNCultureInfo_fa_IR انتخاب شده و تقویم WNPersianCalendar.
در غیر اینصورت، فرهنگ WNCultureInfo_en_US و تقویم WNGregorianCalendar انتخاب میشود.


در ادامه به معرفی تقویم و نحوه ساخت دیگر تقویم ها اشاره خواهیم کرد.

تقویم

تقویم روشی برای تبدیل تعداد روزها از ابتدای سال ژولین است، برای مثال اولین روز تاریخ شمسی 1948320 روز با اولین روز ژولین فاصله دارد. برای اطلاع بیشتر میتوانید اینجا را مطالعه کنید.

چگونه یک تقویم بسازیم؟

برای ساخت یک تقویم کافیست کلاسی به خصوصیات زیر بسازید

class WN(CalendarName] { constructor() { this.Name = "[CalendarName]"; this.LeapMonth = 12; this.monthsInYear = 12; } getDayOfWeek(Year, Month, Day) { return x; } getDayOfYear(Year, Month, Day) { return x; } getDaysInMonth(Year, Month) { return x; } getDaysInYear(Year) { return this.isLeapYear(Year) ? 366 : 365; } getWeekOfYear(Year, Month, Day) { return x; } isLeapDay(Year, Month, Day) { return this.isLeapMonth(Year, Month) && Day === 30; } isLeapMonth(Year, Month) { return this.isLeapYear(Year) && Month === this.LeapMonth; } isLeapYear(Year) { return x; } getDaysFromBase(Year, Month, Day) { return x; } getYearMonthDayFromDays(jd) { return { Year: year, Month: month, Day: day }; } }

بدیهی است برای گسترش تقویم خود، توابع دیگری نیاز داشته باشید که بخواهید اضافه کنید، ولیکن این توابع به صورت اجباری بایستی پیاده سازی شود.

Name
نام تقویم به صورت متنی، معمولا با نام کلاس یکی است.

LeapMonth
چه برجی از سال، میتواند کبیسه باشد.

MonthsInYear
در سال چند برج وجود دارد.

getDayOfWeek
getDayOfWeek(Year: number, Month: number, Day: number): number
شماره روز هفته را بر اساس سال، برج و روز بر میگرداند، برای مثال 1400، 02، 27 روز دوشنبه است پس مقدار 1 را برمیگرداند.

getDayOfYear
getDayOfYear(Year: number, Month: number, Day: number): number
تاریخ مد نظر، چندمین روز از ابتدای سال است.برای مثال 1400، 02، 27 روز 58 از ابتدای سال است.

getDaysInMonth
getDaysInMonth(Year: number, Month: number): number
در سال و برج مورد نظر، چند روز وجود دارد، تابع بایستی تعداد روز برجی که در سال کبیسه است را نیز در نظر بگیرد.

getDaysInYear
getDaysInYear(Year: number): number
در سال مشخص شده چند روز وجود دارد، اگر سال کبیسه باشد، بایستی مشخص شود.

getWeekOfYear
getWeekOfYear(Year: number, Month: number, Day: number): number
تاریخ گفته شده، هفته چندم از ابتدای سال است.

isLeapDay
isLeapDay(Year: number, Month: number, Day: number): boolean
آیا تاریخ مشخص شده روز سال کبیسه است یا خیر.

isLeapMonth
isLeapMonth(Year: number, Month: number): boolean
آیا برج مشخص شده، برج کبیسه است یا خیر.

isLeapYear
isLeapYear(Year: number): boolean
آیا سال مشخص شده کبیسه است یا خیر.

getDaysFromBase
getDaysFromBase(Year: number, Month: number, Day: number): number
یکی از مهمترین توابع است، وظیفه آن محاسبه تعداد روزهای گذشته از ابتدای سال ژولین است.

getYearMonthDayFromDays
getYearMonthDayFromDays(mNum: number): { Year: number, Month: number, Day: number }
این تابع برعکس تابع بالاست، یعنی این تعداد روز گذشته از ابتدای تاریخ ژولین، چه تاریخی در این تقویم است.

تقویم های پیاده سازی شده

در این فریم ورک، تقویم های زیر به صورت پیش فرض و با اسامی کلاس های زیر تعریف شده است.

نحوه استفاده

در ابتدا بگوییم، تمامی خروجی های تاریخی به صورت تاریخ استاندارد میلادی است، فقط توابع قابلیت تبدیل و نمایش و محاسبات خاص را بر روی تقویم انتخاب شده دارند.

برای استفاده از تقویم ها و اعمال محاسبات بر روی آنها بایستی متغییری از جنس wnDate بسازید و از توابع، رخداد ها و خصوصیات آن استفاده کنید. در زیر به آنها اشاره میشود.

برای ساخت متغییر چند ویزگی وجود دارد.
new WNDate()
نوع فرهنگ از wnConfig.cultureInfo گرفته میشود و تقویم از wnConfig.calendar همچنین مقدار پیش فرض صفر در نظر گرفته میشود.
new WNDate(wnDate)
یک تاریخ جدید بر اساس تنظیمات فرهنگ و تقویم و مقدار آن میسازد.
new WNDate(wnCultureInfo,wnCalendar)
یک تاریخ بر اساس فرهنگ و تقویم مد نظر میسازد.
new WNDate(wnCultureInfo,wnCalendar,Date)
یک تاریخ بر اساس فرهنگ و تقویم و مقدار تاریخ استاندارد مد نظر میسازد.

توابع

addDays(value)
به مقدار مشخص روز، به تاریخ اضافه میکند.

addMonths(value)
به مقدار مشخص برج، به تاریخ اضافه میکند.

addYears(value)
به مقدار مشخص سال، به تاریخ اضافه میکند.

addWeeks(value)
به مقدار مشخص هفته، به تاریخ اضافه میکند. در حقیقت این تابع همان تابع اضافه کردن روز است که عدد هفته در 7 ضرب میشود.

addHours(value)
به مقدار مشخص ساعت، به تاریخ اضافه میکند.

addMinutes(value)
به مقدار مشخص دقیقه، به تاریخ اضافه میکند.

addSeconds(value)
به مقدار مشخص ثانیه، به تاریخ اضافه میکند.

addMilliseconds(value)
به مقدار مشخص میلی ثانیه، به تاریخ اضافه میکند.

setDate(Date)
بر اساس تاریخ استاندارد میلادی، تبدیلات را انجام داده و تاریخ را تنظیم میکند.

setDateYMD(Year, Month, Day, Hour, Minute, Second, Millisecond)
بر اساس ورودی ها تاریخ را تنظیم میکند، مقدار ساعت، دقیقه، ثانیه و میلی ثانیه به صورت اختیاری است و مقدار پیش فرض صفر است.

setDateNumber(jd)
مقدار تاریخ را بر اساس روزهای گذشته از ابتدای تاریخ ژولین محاسبه و تنظیم میکند. این تابع برای تبدیل بین تقویم ها بسیار کاربردی است.

setDateString(string)
اگر تاریخ به صورت متنی است، آنرا تبدیل به تاریخ میکند، ترتیب ورودی، سال، ماه، روز، ساعت، دقیقه، ثانیه و میلی ثانیه است. اگر به هر دلیلی تعداد روزها بیشتر 31 بود، جای سال و روز خودکار تغییر میکند.

Set(wnDate)
بر اساس، یک تاریخ، این تاریخ را تنظیم میکند، اگر تقویم ها یکسان نباشند نیز تبدیلات انجام شده و سپس تنظیم میگردد.

toDateTime()
تاریخ تنظیم شده را به صورت تاریخ استاندارد بر میگرداند.

toNumber()
تاریخ تنظیم شده را به صورت تعداد روزها از ابتدای تاریخ ژولین بر میگرداند.

toNumberDate()
تاریخ تنظیم شده را به صورت تعداد روزها از ابتدای تاریخ ژولین بدون مقدار ساعت روز بر میگرداند.

toNumberYMD(Year, Month, Day)
تعداد روزهای سپری شده از ابتدای تاریخ ژولین، بر اساس سال، ماه و روز داده شده محاسبه کرده و عدد آنرا برمیگرداند.

toString(format, nativeDigit)
تاریخ را به صورت رشته برمیگرداند.
مقدار پارامتر format اختیاری است و به صورت پیش فرض از فرهنگ CultureInfo.DateTimeFormat.fullDateTimePattern گرفته میشود. اگر میخواهید فرمت خاصی داشته باشد، بر اساس استاندارد فورمت تاریخ، آنرا وارد کنید.
پارامتر nativeDigit، تعیین میکند، تبدیل اعداد بر اساس عدد مندرج در فرهنگ باشد یا خیر، این مقدار اختیاری است و از متغییر WNDefaultNativeDigit تنظیم میگردد.
برای مثال اعداد نمایشی برای فارسی عبارتند از"۰۱۲۳۴۵۶۷۸۹" در صورتیکه در محیط وب اعداد به این گونه شناخته میشود "0123456789" توجه داشته باشید، برای محاسبات این تبدیل قابل برگشت و محاسبه نیست و فقط برای نمایش کاربرد دارد.

برای اطلاع بیشتر در خصوص انواع فورمت خروجی برای نمایش تاریخ میتوانید اینجا را مطالعه فرمایید.

toLongDateString(WNDefaultNativeDigit)
تبدیل تاریخ به رشته به صورت فرمت CultureInfo.DateTimeFormat.longDatePattern

toShortDateString(WNDefaultNativeDigit)
تبدیل تاریخ به رشته به صورت فرمت CultureInfo.DateTimeFormat.shortDatePattern

toLongTimeString(WNDefaultNativeDigit)
تبدیل تاریخ به رشته به صورت فرمت CultureInfo.DateTimeFormat.longTimePattern

toShortTimeString(WNDefaultNativeDigit)
تبدیل تاریخ به رشته به صورت فرمت CultureInfo.DateTimeFormat.shortTimePattern

fixedDate
اگر به هر دلیلی، توازن تاریخی بهم ریهخته باشد، برای مثال تعداد روزها بیشتر از روزهای یک برج باشند، این تابع آن توازن را برقرار کرده و تعداد روزهای اضافی را به برج بعدی منتقل میکند.

توابع مقایسه ای

lessThan(wnDate)
تاریخ جاری از تاریخ داده شده کوچکتر است یا خیر.

lessThanEqual(wnDate)
تاریخ جاری از تاریخ داده شده کوچکتر یا مساوی است یا خیر.

greaterThan(wnDate)
تاریخ جاری از تاریخ داده شده بزرگتر است یا خیر.

greaterThanEqual(wnDate)
تاریخ جاری از تاریخ داده شده بزرگتر یا مساوی است یا خیر.

equal(wnDate)
تاریخ جاری از تاریخ داده شده برابر است یا خیر.

notEqual(wnDate)
تاریخ جاری از تاریخ داده شده برابر نیست یا خیر.

lessThanExact(wnDate)
تاریخ و ساعت جاری از تاریخ و ساعت داده شده کوچکتر است یا خیر.

lessThanEqualExact(wnDate)
تاریخ و ساعت جاری از تاریخ و ساعت داده شده کوچکتر یا مساوی است یا خیر.

greaterThanExact(wnDate)
تاریخ و ساعت جاری از تاریخ و ساعت داده شده بزرگتر است یا خیر.

greaterThanEqualExact(wnDate)
تاریخ و ساعت جاری از تاریخ و ساعت داده شده بزرگتر یا مساوی است یا خیر.

equalExact(wnDate)
تاریخ و ساعت جاری از تاریخ و ساعت داده شده برابر است یا خیر.

notEqualExact(wnDate)
تاریخ و ساعت جاری از تاریخ و ساعت داده شده برابر نیست یا خیر.

خصوصیات

Year
تنظیم یا دریافت سال در تقویم تنظیم شده.

Month
تنظیم یا دریافت برج در تقویم تنظیم شده.

Day
تنظیم یا دریافت روز در تقویم تنظیم شده.

Hour
تنظیم یا دریافت ساعت در تقویم تنظیم شده.

Minute
تنظیم یا دریافت دقیقه در تقویم تنظیم شده.

Second
تنظیم یا دریافت ثانیه در تقویم تنظیم شده.

Milliseconds
تنظیم یا دریافت میلی ثانیه در تقویم تنظیم شده.

DayOfWeek
دریافت روز هفته تاریخ تنظیم شده.

DayOfYear
دریافت تعداد روزهای گذشته از ابتدای سال تقویم جاری.

DaysInMonth
تعداد روزهای موجود در سال و برج تنظیم شده.

DaysInYear
تعداد روزهای سال تنظیم شده.

isLeapYear
سال تنظیم شده کبیسه است یا خیر.

isLeapMonth
برج تنظیم شده، برج کبیسه است یا خیر.

isLeapDay
سال، برج و روز تنظیم شده، روز کبیسه است یا خیر.

MonthsInYear
تعداد برجهای موجود در یک سال.

LeapMonth
برج کبیسه کدام برج است.

WeekOfYear
تاریخ تنظیم شده، چندمین هفته سال است.

Value
تنظیم مقدار تاریخی، که بر اساس نوع وروی، تنظیمات انجام میشود. مقدار عددی از ابتدای سال ژولین برگردانده میشود.

مثال تاریخ امروز

Julian:
Gregorian:
Persian:
Hijri:
ژولین:
میلادی:
پارسی، جلالی، هجری شمسی:
هجری قمری:
توجه داشته باشید در تاریخ هجری قمری، ممکن است تا 2 روز اختلاف باشد که با تنظیم خصوصیت hijriAdjustment در تقویم هجری قمری، این اختلاف حل میشود. برای عدم تکرار تنظیم نیز میتوانید با تنظیم متغییر wnConfig.hijriAdjustment از تکرار آن جلوگیری کنید.