در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

استفاده از تاریخ شمسی در سی شارپ

با سلام به همه ی همراهان Itpro

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

ما در این برنامه از کلاس PersianCalendar استفاده می کنیم که این کلاس به طور پیش فرض در کتابخانه System.Globalization; در فریمورک دات نت وجود دارد. برای پیاده سازی این روش کلاس زیر را در برنامه ایجاد می کنیم:

using System;
    using System.Globalization;
    using System.Reflection;
    using System.Threading;

    public class Cultures
    {
        public static void InitializePersianCulture()
        {
            InitializeCulture("fa-ir", new[] { "ی", "د", "س", "چ", "پ", "ج", "ش" },
                              new[] { "یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه" },
                              new[]
                                  {
                                      "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی",
                                      "بهمن", "اسفند", ""
                                  },
                              new[]
                                  {
                                      "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی",
                                      "بهمن", "اسفند", ""
                                  }, "ق.ظ. ", "ب.ظ. ", "yyyy/MM/dd", new PersianCalendar());
        }

        public static void InitializeCulture(string culture, string[] abbreviatedDayNames, string[] dayNames,
                                             string[] abbreviatedMonthNames, string[] monthNames, string amDesignator,
                                             string pmDesignator, string shortDatePattern, Calendar calendar)
        {
            var calture = new CultureInfo(culture);
            var info = calture.DateTimeFormat;
            info.AbbreviatedDayNames = abbreviatedDayNames;
            info.DayNames = dayNames;
            info.AbbreviatedMonthNames = abbreviatedMonthNames;
            info.MonthNames = monthNames;
            info.AMDesignator = amDesignator;
            info.PMDesignator = pmDesignator;
            info.ShortDatePattern = shortDatePattern;
            info.FirstDayOfWeek = DayOfWeek.Saturday;
            var cal = calendar;
            var type = typeof(DateTimeFormatInfo);
            var fieldInfo = type.GetField("calendar", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
            if (fieldInfo != null)
                fieldInfo.SetValue(info, cal);
            var field = typeof(CultureInfo).GetField("calendar", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
            if (field != null)
                field.SetValue(calture, cal);
            Thread.CurrentThread.CurrentCulture = calture;
            Thread.CurrentThread.CurrentUICulture = calture;
            CultureInfo.CurrentCulture.DateTimeFormat = info;
            CultureInfo.CurrentUICulture.DateTimeFormat = info;
        }
    }

فقط همین!!

حال برای این که مُد تاریخ در سیستم تغییر کند نقطه شروع برنامه را پیدا می کنیم. این نقطه در برنامه های ویندوزی #C فایل program.cs و تابع main می باشد و همچنین نقطه شروع در برنامه های تحت وب فایل global.asax می باشد. بعد از پیدا کردن نقطه شروع برنامه قطعه کد زیر را در ابتدای برنامه قرار می دهیم.

Cultures.InitializePersianCulture();

این عمل باعث می شود که culture برنامه به فارسی تغییر پیدا کند. حال برای این که از تاریخ شمسی جاری کنونی در برنامه استفاده کنیم از کد

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

نویسنده: مهدی عادلی فر

منبع انجمن تخصصی فناوری اطلاعات ایران

هرگونه نشر و کپی برداری با ذکر نام نویسنده و منبع بلامانع است.

#تاریخ_شمسی_در_دات_نت #کد_تبدیل_تاریخ_میلادی_به_شمسی #تاریخ_شمسی_در_سی_شارپ #نمایش_تاریخ_شمسی_در_برنامه_های_سی_شارپ #تبدیل_تاریخ_میلادی_به_شمسی
16 نظر
mahdi211

*<center>

با سلام و احترام

مطلبتون واقعا عالی بود یعنی بهتر از این نمیشه

دستتون درد نکنه

<center>*

علی رحیمی

با سلام.

آیا در سال کبیسه مشکلی پیش نمی آید؟

مهدی عادلی فر

سلام دوست عزیز نه مشکلی پیش نمیاد

علی رحیمی

حال اگر بخواهیم در یک گرید یک ستون شمسی باشد، یک ستون دیگر میلادی؟

DatePicker منطبق نمی شود.

محمدرضا زارعی

این روش خیلی عالی بود. کار منو که کاملاً راه انداخت. خیلی ممنون.

forhaddadi

با این روش آیا میشه از dateTimePicker برای گرفتن تاریخ استفاده کرد؟ من میخوام از ShDateTimePicker اسفاده کنم که کاربر تاریخ شمسی انتخاب کنه

علی موذن صفایی

فکر می کنم باید به جای DateTime.UtcNow باید از همان DateTime.Now استفاده شود. چون ساعت بازگشت داده شده توسط این دو متد متفاوت می باشد.

به نظرم در متن باید اصلاح شود.

(البته من روی ویندوز 10 و تاریخ شمسی استفاده کردم و این دو متد باهم نتایج متفاوتی ارائه می داد)

مهدی عادلی فر

با تشکر از دوست عزیز

Now تاریخ جاری سیستم را برمی گرداند و UtcNow تاریخ جاری سیستم را بدون در نظر گرفتن اختلاق منطقه زمانی به ما می دهد برای مثال اگر ما در ایران باشیم 3:30+ با گرینویچ اختلاف زمانی داریم که UtcNow زمان گرینویچ را به ما میدهد. این قسمت در متن اصلاح شد.

mehrdad3296

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

من این کلاس رو که گفتید ساختم و توی فایل program.cs متد Cultures.InitializePersianCulture() رو فراخوانی کردم.

برنامه برای لود کردن فیلد تاریخ مشکلی نداره یعنی مقدار فیلد تاریخ رو که بصورت میلادی در دیتابیس ذخیره شده رو بصورت شمسی در datagrid و یا textbox نشان میده . ولی وقتی میخوایم از یه textbox مقدار تاریخ به شمسی نوشته رو بخونم و توسط دستور sql اینسرت در دیتا بیس ذخیره کنم دقیقا همون مقدار تاریخ شمسی رو ذخیره میکنه چون من دقیق مقدار خاصیت text تکتس باکس رو میخونم و بوسیله دستور insert into در دیتابیس قرار میدم. بنابراین دقیقا همون متن تاریخ شمسی که در تکتس باکس هست در دیتابیس ذخیره میشه .

به نظر شما راه حل برای ذخیره تاریخ بصورت میلادی در دیتابیس چی هست ؟

مهدی عادلی فر

راه حل این کار این هستش که شما مقدار داخل تکست باکس رو بخونید و سپس با استفاده از کد زیر آن را به تاریخ تبدیل کنید و سپس ذخیره نمایید

var d=DateTime.Parse(text);
mehrdad3296

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

var d=DateTime.Parse(text);

objCommand.CommandText = "insert into TestDate (Name,Date1) VALUES ('mehrdad','"+d.ToString() +"')";

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

مهدی عادلی فر

از کد زیر برای میلادی کردن استفاده کنید

DateTime.Now.ToString("d", new CultureInfo("en-GB")) ;
mehrdad3296

مرسی دستتون درد نکنه درست شد . البته تاریخ رو برعکس میده ولی یه جوری درستش میکنم

Jahanara96

سلام به من تو این دوتا خط بهم ارور میده خواهش میکنم کمک کنین

Var calture=new caltureinfo(calendar)

روی catureinfo ارور میده میگه نیم اسپیس catureinfo رو پیدا نمیکنم.

روی خط ترد اولم ارور میده که تایپ استرینگ رو نمیشه به system.globalization.catureinfo تبدیل کرد

reza_5180

سلام. خیلی عالی بود. در تاریخ مشکلی نیست. اما چرا وقتی دستور DateTime.Now.DayOfWeek رو استفاده میکنیم بجای اینکه اسم روز رو به فارسی بده ، همون انگلیسی مینویسه؟

حتی با این دستور هم روز رو به انگلیسی مینویسه :

persianCalendar.GetDayOfWeek(DateTime.Now)
nima_1221

سلام.چرا این خط از برنامه من پیغام خطا میده؟

MessageBox.Show(Convert.ToDateTime("2017//12//31").ToString())

خطا :

System.FormatException: 'String was not recognized as a valid DateTime

وقتی 31 رو به 29 تغییر میدم خطا نمیده

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

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

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