تقویم فارسی و فارسی ساز تاریخ در .NET

جمعه 14 تیر 1392

تقویم فارسی و فارسی ساز تاریخ در .NET <br/> تقویم فارسی در اکثر کشورهای فارسی زبان استفاده می شود، گرجه در بعضی مناطق از اسامی متفاوتی برای نام ماهها استفاده می شود. تقویم فارسی، تقویم رسمی ایران و افغانستان و یکی از تقویمهای جایگزین در مناطقی از قبیل قزاقستان و تاجیکستان است.

مقدمه

تقویم فارسی در اکثر کشورهای فارسی زبان استفاده می شود، گرجه در بعضی مناطق از اسامی متفاوتی برای نام ماهها استفاده می شود. تقویم فارسی، تقویم رسمی ایران و افغانستان و یکی از تقویمهای جایگزین در مناطقی از قبیل قزاقستان و تاجیکستان است. تقویم فارسی بر اساس سال خورشیدی است و تقریباً 365 روز است. هر سال دارای 4 فصل است و سال جدید زمانی شروع می شود که خورشید ظاهراً از نیم کره ((hemisphere جنوبی به نیم کره شمالی، هنگام نگاه از مرکز زمین، از استوا رد می شود. سال جدید با اولین روز ماه فروردین که اولین روز بهار در نیم کره شمالی است شروع می شود.

هر یک از 6 ماه نخستین 31 روز، 5 ماه بعدی 30 روز و ماه آخر در سال معمولی 29 و در سال کبیسه 30 روز هستند. سال کبیسه سالی است که وقتی بر 33 تقسیم می شود، باقیمانده اش 1، 5، 9، 13، 17، 22، 26، یا 30 می شود. به عنوان مثال، سال 1370، سال کبیسه است؛ زیرا اگر آنرا بر 33 تقسیم کنیم، باقیمانده 17 می شود. تقریباً 8 سال کبیسه در هر چرخه 33 ساله وجود دارد.

از آنجاییکه .NET Framework هیج نوع تقویم فارسی را ساپورت نمی کنند، و تقویم فارسی در .Net FrameWork 2 دارای Bug و بی فایده است، در اینجا من قصد دارم چگونگی نوشتن DataType لازم و کنترلهای GUI را برای کار کردن با این نوع داده ای (DataType) نشان دهم.
کلاس تقویم فارسی

به نظر می رسد که مایکرسافت فراموش کرده که تقویم فارسی را در.NET 1.1 ساپورت کند، ولی در حالی که کلاسی را برای این نوع مخصوص از تقویم در نسخه دوم Framework مهیا کرده است، اما تا حدودی در محاسبه دچار اشتباه شده است. ما قصد داریم یک تقویم فارسی به علاوه یک DataType که جایگزین کلاس DateTime استاندارد شود، بنویسیم؛ در حالی که همان ساختار را حفظ کنیم. لازم است که DateTime استاندارد را به PersianDate تبدیل کنیم. من یک کلاس تبدیل کننده نیز در اختیار خواهم گذاشت. از آنجاییکه استفاده از این کلاسها، زمانی که با کنترلهای GUI ترکیب می شوند، به حداکثر می رسد، من یک MonthView و یک کنترل DatePicker نیز در اختیار خواهم گذاشت.
زمان طراحیIntegration

من کمی Integration زمان طراحی را تغییر داده ام. ار آنجاییکه بعصی از برنامه نویسان به استفاده از کلاسهای PersianTime و بعضی به DateTime برای کار کردن با این libraries علاقه دارند، من از هر دوی این خصوصیات تحت عنوان SelectedDate و SelectedDateTime نام میبرم. برای SelectedDate که دارای نوع PersianDate است، یک TypeConverter جهت تبدیل Text به مثالهای PersianDate زمان طراحی وجود دارد.
ساپورت پوسته (Theme)

من از .NET 2.0 VisualStyleRenderer, که یک wrapper تنظیم شده برای styleهای XP است استفاده می کنم. به علاوه، کلاسهای دیگری جهت شبیه سازی rendering آفیس 2003 وجود دارد. همچنین، یک style برای آفیس 2000 تیز موجود است. اگر سیستم عام (theming) را ساپورت نکند و یا آن را غیر فعال کند، rendering را با استفاده از آقیس 2000 کنترل میکند.

clip_image002

Popup و سایه ها (Shadow)

کنترلهای popup باید سایه داشته باشند. در کنترلهای RTL، سایه ها باید درپایین سمت چپ کنترلها باشند. تمامی stringهایی که در کنترلها بکار می روند، از یک کلاس localizer manager استفاده می کنند که stringها را بر اساس شمارش StringID پایه ریزی می کند. جهت استفاده از نسخه محلی شده (localized)، باید سرنخهای thread)) culture جاری و خصوصیات CultureUI را به یکی از culture های تعریف شده تغییر دهید: (AR-SA برای Culture عرب، و FA-IR برای Culture فارسی، و InvariantCulture برای culture انگلیسی و خنثی. در زیر چگونگی انچام این کار در متد اصلی برنامه نشان داده شده:

 

//
// The main entry point for the application.
//
[STAThread]
static void Main()
{
Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo("fa-IR");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

 



در زیر چگونگی رفتار صحیح کنترلهای popup با stringهای استاندارد و نسخه محلی شده(localized) برای FA-IR culture آورده شده است.

clip_image001clip_image002[6]

استفاده از Cultureهای عربی و خنثی

قبلاً من از culture AR-AE برای عربی استفاده می کردم، ولی در نسخه 1.3.1.0، مجبور بودم آنرا به AR-SA تغییر دهم. دلیلش هم این است که تقویم هجری، تقویم پیش فرض culture AR-AE نیست؛ در حالی که در culture برای AR-SA، تقویم پیش فرض است. حالا کنترل، وقتی که culture را روی عربی تنظیم می کنید، به طور صحیح کشیده می شود.

حالا Render کردن در culture خنثی در جهت چپ به راست انجام می شود. عموماً کنترل، بر اساس جهت خواندن culture حاضر، تصمیم به render کردن در RTL یا LTR می کند.

clip_image003

استفاده از کد

میتوان از کلاس PersianDate همان قدر که در DateTime استفاده میشود، استفاده کرد. در زیر نمونه هایی آورده شده است:

 

 

//
// Use of Persian date class
//
PersianDate pd1 = PersianDate.Now.ToString(); // prints 1385/01/13
// constructs a new instance with the specified vales
PersianDate pd2 = new PersianDate(1386, 4, 26);

// You can use operator overloading, too!
if(pd1 >= pd2)
MessageBox.Show("Date is greater or equal");

// Use of normal DateTime and Conversion
PersianDate pd3 = PersianDateConverter.ToPersianDate(DateTime.Now);
DateTime dt1 = PersianDateConverter.ToGregorianDate(PersianDate.Now);



 
نکته های جالب

اگر پیشنهاد، نظر یا بازخوردی (feedback) دارید، لطفاً به آدرس email یا Forum انتهای صفحه بفرستید. جهت کسب اطلاعات بیشتر میتوانید از سایت من نیز دیدن کنید.
ساپورت .NET 1.1 و VisualStudio .NET 2003

این library روی VS.NET 2005 و .NET Framework نسخه 2 تست شده است. پس روی VS.NET 2003 اجرا نخواهد شد. اگر واقعاً تیاز به این کار دارید، باید آنرا به VS.NET 2003 تبدیل کنید و قسمت رسم کننده (Drawing) کد را تغییر دهید، زیرا واقعاً از کلاسهای صبقه بندی شده .NET 2.0 جهت رسم (draw) در ویندوز XP استفاده می کند. باید از یک wrapper در Theme API استفاده کنید تا این کار را برای شما انجام دهد. (یک پروژه در codeproject وجود دارد) جهت آسانتر کردن porting، می توانید تمامی drawingها را در ویندوز XP وStyle آفیس 2003 کات (cut) کنید و به themeهای قدیمی و خوب آفیس 2000 که از کلاسهای GDI+ استفاده می کنند متوسل شوید.
نسخه WPF

نسخه WPF از رده خارج است. می توانید نگاهی به بخش Vista در سایت Codeproject بیاندازید.
سابقه
نسخه 1.9.0.0

    ثابت: bugهایی که ناشی از mapping اشتباه روزهای هفته فارسی/عربی یا گریگوری بودند، که منجر به نمایش اشتباه روزهای هفته در تقویم گریگوری شدند.
    اضافه شده: handling بهتر modeهای چند انتخابی (multi-selection). میتوان خصوصیت SelectedDateRange را اضافه یا حذف کرد، و تغییرات روی UI منعکس می شوند.
    اضافه شده: شمارش PersianDayOfWeek با ترتیب صحیح روزها.
    اضافه شده: خصوصیت DayOfWeek به کلاس PersianDate، جهت بازگشت به روز صحیح هفته.

نسخه 1.6.0.0

    ثابت: بعضی bugها از طریق feedback پست شدند.
    اضافه شده: کنترل MessageBox با viewهای RTL و LTR و قابلیت یادآوری مقدار انتخاب شده، همراه با دکمه های MessageBox استاندارد و دلخواه.
    اضافه شده: فرمت دلخواه متد PersianDate.ToString() (مثل کنترل DateTime)، که قابلیت بازگشت به string فرمت شده را می دهد؛ مانند: Long Date, Long Time, DateTime, و غیره.
    اضافه شده: draw دلخواه هر روزی که ترجیح داده شده، که میتوان جهت draw کردن بعضی روزها در فرمت غیرفعال استفاده کرد همراه با اتفاق (event) SelectedDateTimeChanging.

نسخه 1.5.0.0

    ثابت: استثناهای کنترل FAMonthView موقع انتخاب یک تاریخ قبل از MinValue و بیشتر از MaxValue.
    ثابت: دامنه (range) کلاسهای PersianDate MinValue و MaxValue را گسترش داد.
    ثابت: MonthNameهای culture یکسان (Invariant)، یک index بر پایه صفر است. نام ماه اول در Invariant ، Culture مشکلی ندارد.
    ثابت: چک کردن مقادیر (values) سال، ماه،روز روی تنظیمات PersianDate.
    ثابت: چک کردن مقادیر null روی =! و اپراتورهای == PersianDate.
    ثابت: خصوصیات مضاعف DateTime و PersianDate و وقایع کنترلهای GUI را حذف کرد. می توان نمونه های DateTime را مستیقیماً به PersianDate تبدیل کرد.
    ثابت: فرایند اعتبار دهی (validation) به DatePicker.
    اضافه شده: قابلیت استفاده از cultureها و تقویم های دیگر با کنترلها.
    اضافه شده: تبدیل مجازی DateTime و PersianDate
    اضافه شده: خصوصیت اضافه شده Millisecond به کلاس PersianDate برای دقت بیشتر.
    اضافه شده: کلاس PersianDate حالا قابل سریال بندی (serializable) است و interfaceهای زیر را تکمیل می کند:
    ICloneable , IComparable , IComparable<T>, IComparer , IComparer<T>, IEquatable<T>.
    اضافه شده: قابلیت انتخاب scrolling feature در FAMonthView. میتوان روزها، ماهها و سالها را مرور کرد.
    اضافه شده: کلاسهای FAThemeManager که themeهای انتخاب شده همه کنترلها را handle میکند. جهت تغییر جهانی theme، غفط نیاز به تنظیم خصوصیت (propert) این کلاس Theme دارید.
    اضافه شده: کلاس FALocalizeManager که cultureهای دیگر را handle می کند. حالا می توانید stringها را در هر culture محلی کنید، (localize)
    اضافه شده: ساپورت ToolStrip. حالا میتوان کنترلها را در ToolStrip, MenuStrip و غیره یکسان کرد.
    اضافه شده: ساپورت ستون دلخواه DataGridView Microsoft و editor.

نسخه 1.4.0.0

    اضاقه شده: تست و demo کارکردهایی را که توسط library، با کد source تکمیل کنید.
    اضافه شده: سند سازی (documentation)
    اضافه شده: نمودار (diagram) باری سلسله مراتب (hierarchy) PopupForms, Controls و کلاسهای Painter.
    احساس و ظاهر تکمیل شده و صحیح در آفیس 2003 روی کنترلهای ComboBox
    View زیبا و صحیح RTL و LTRاز FADatePickerConverter
    Bug Fix: کنترل FADa<code>tePicker، popupهای تقویم را مطابق با theme خودش نمایش می دهد.
    Bug Fix: جهت صحیح کنترلها در حالت RTL و LTR
    Bug Fix: مکان صحیح سایه کنترل popupها در حالت RTL و LTR
    Bug Fix: کنترل FADatePicker خصوصیات متن را صحیح نمایش نمیدهد.
    تغییرات: جابجایی namespaceها.
    مسایل شناخته شده: محلی کردن (localization) stringها در زبان عربی. ( کسی میتواند اینجا کمکم کند؟)

نسخه 1.3.1.0

    تکمیل drawingهای ویندوز 2000 در کامپوترهایی که ویندوز XP نداشتند، یا زمانی که visual styleها غیر فعال هستند.
    Drawing بهتر ویندوز XP و styleهای آفیس 2003
    Drawing کنترلها بر اساس culture کاربر. در حال حاضر، cultureهای زیر مجاز هستند: خنثی (تقویم گریگوری)، AR-SA (تقویم هجری) و FA-IR (تقویم فارسی).
    Localization بهتر. میتوان از کلاس Localizer جهت update کردن stringها استفاده کرد.
    ساپورت از تقویم گریگوری (culture خنثی) و تقویم هجری
    Rendering چپ به راست برای cultureهایی که راست به چپ نیستند. (مثلاً cultureهای خنثی و culture انگلیسی و غیره.)
    کنترلهای جدید DatePickerConverter که تاریخ منتخب را با فشار یک دکمه تغییر می دهند.

 

 

 

 

MohammadJavad

نویسنده 86 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید