PersianDateTime جایگزینی برای System.DateTime
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: سه دقیقه

همانطور که در توضیح پروژه PersianDateTime آمده است، کلاس PersianDateTime جایگزینی است برای System.DateTime برای استفاده در پروژه‌هایی که احتیاج به تاریخ شمسی و ساعت رسمی ایران یا سایر کشورهای فارسی‌زبان، مستقل از Time Zone سیستم و در نظر گرفتن Daylight Saving Time، دارند. این کلاس شامل اکثر متدها، پراپرتی‌ها و عملگرهای متداول  System.DateTime است.

دسترسی به تاریخ و ساعت فعلی :
PersianDateTime now = PersianDateTime.Now;

string persianDateTime = now.ToString(); // 1392/03/09 23:37:57
string persianDate = now.ToString(PersianDateTimeFormat.Date); // 1392/03/09
string persianFullDateTime = now.ToString("dddd d MMMM yyyy ساعت hh:mm:ss tt"); // پنج شنبه 9 خرداد 1392 ساعت 11:37:57 ب.ظ

TimeSpan persianTime = now.TimeOfDay; // 23:37:57.4641984


نحوه محاسبه PersianDateTime.Now بر اساس فیلد استاتیک PersianDateTime.Mode است که مقدار پیش‌فرض آن PersianDateTimeMode.UtcOffset است.
PersianDateTime.Mode را می‌توان یکی از سه مقدار زیر قرار داد :
  • System : بر اساس تاریخ و زمان سیستم (Time Zone فعلی سیستم)
  • PersianTimeZoneInfo : بر اساس Time Zone تعیین شده در فیلد استاتیک PersianDateTime.PersianTimeZoneInfo (مستقل از Time Zone سیستم)
  • UtcOffset : بر اساس اختلاف ساعت با UTC، مشخص شده در فیلد استاتیک PersianDateTime.OffsetFromUtc (مستقل از Time Zone سیستم)

مقدار پیش‌فرض PersianDateTime.PersianTimeZoneInfo برابر Iran Standard Time Zone است. توجه داشته باشید که در این حالت از DaylightSavingTime تعیین شده در Time Zone استفاده خواهد شد که مثلا برای ایران با زمان واقعی آن اختلاف دارد و باید آنرا اصلاح کرد .

مقدار پیش‌فرض PersianDateTime.OffsetFromUtc برابر 3 ساعت و نیم است. در این حالت DaylightSavingTime با توجه به مقادیر سه فیلد استاتیک DaylightSavingTimeStart ،DaylightSavingTimeEnd و DaylightSavingTime تعیین می‌شود که به صورت پیش‌فرض برابر ساعت 24 اول فروردین، ساعت 24 سی‌ام شهریور و یک ساعت است.

تمام فیلدهای استاتیک ذکر شده به صورت public تعریف شده‌اند تا برنامه‌نویسان سایر کشورهای فارسی‌زبان بتوانند به دلخواه خود آنرا تغییر دهند.

نحوه کار با مقادیر رشته‌ای تاریخ شمسی هم اینگونه است :
PersianDateTime persianDate1 = PersianDateTime.Parse("1392/03/02");
PersianDateTime persianDate2 = PersianDateTime.Parse("1392/03/02", "23:32:56");

چند سازنده هم وجود دارد برای کسانی که تاریخ را به صورت int و ساعت را int یا short (بدون ثانیه) ذخیره می‌کنند :
PersianDateTime persianDate1 = new PersianDateTime(13920310);
PersianDateTime persianDate2 = new PersianDateTime(13920310, 233256);
PersianDateTime persianDate3 = new PersianDateTime(13920310, (short)2332);

تبدیل تاریخ میلادی به شمسی :
DateTime miladiDate = new DateTime(2013, 5, 31);
PersianDateTime persianDate = new PersianDateTime(miladiDate);

تبدیل تاریخ شمسی به میلادی :
PersianDateTime persianDate = PersianDateTime.Parse("1392/03/02");
DateTime miladiDate = persianDate.ToDateTime();


علاوه بر متد ToString معمولی، دو overload دیگر از این متد برای نمایش فرمت‌های مختلف PersianDateTime وجود دارد :

public string ToString(PersianDateTimeFormat format);

public string ToString(string format);
که اولی برای فرمت‌های معمول و دومی برای هر نوع فرمت دلخواه قابل استفاده است که چند نمونه آنرا در قسمت تعیین تاریخ و ساعت فعلی دیدید.

برخی از خصوصیات کلاس PersianDateTime :
  • Year : سال
  • Month : ماه
  • Day : روز
  • TimeOfDay : زمان سپری شده از ابتدای روز
  • TimeOfWeek :زمان سپری شده از ابتدای هفته
  • TimeOfMonth : زمان سپری شده از ابتدای ماه
  • TimeOfYear : زمان سپری شده از ابتدای سال
  • DaysInYear : تعداد روز سال
  • DaysInMonth : تعداد روز ماه
  • DayOfWeek : چندمین روز هفته
  • DayOfYear : چندمین روز سال
  • DayName : نام روز
  • MonthName : نام ماه
  • Date : تاریخ بدون زمان
  • FirstDayOfWeek : اولین روز هفته
  • LastDayOfWeek : آخرین روز هفته
  • FirstDayOfMonth : اولین روز ماه
  • LastDayOfMonth : آخرین روز ماه
  • FirstDayOfYear : اولین روز سال
  • LastDayOfYear : آخرین روز سال

برخی دیگر از متدهای کلاس PersianDateTime :

public PersianDateTime Add(TimeSpan value);
public PersianDateTime AddDays(double value);
public PersianDateTime AddMonths(int months);
public PersianDateTime AddYears(int value);
public PersianDateTime AddHours(double value);
public PersianDateTime AddMinutes(double value);
public PersianDateTime AddSeconds(double value);
همچنین تمام عملگرهای +، -، >، <، =>، =<، ==، و =! قابل استفاده هستند.
  • #
    ‫۱۰ سال و ۸ ماه قبل، دوشنبه ۲۱ بهمن ۱۳۹۲، ساعت ۱۴:۰۱
    با سلام .
    اگه تاریخ شمسی را مثلا با این فرمت
     string persianFullDateTime = now.ToString( "dddd d MMMM yyyy ساعت hh:mm:ss tt" ); //
    در دیتابیس ذخیره کنیم. بعد برای sort کردن برحسب تاریخ به مشکل بر نمی‌خوریم؟
    • #
      ‫۱۰ سال و ۸ ماه قبل، دوشنبه ۲۱ بهمن ۱۳۹۲، ساعت ۱۴:۱۵
      این فرمت خاص کاربرد نمایشی داره بیشتر.
  • #
    ‫۱۰ سال و ۷ ماه قبل، سه‌شنبه ۱۳ اسفند ۱۳۹۲، ساعت ۱۲:۵۷
    با سلام یه فیلد تاریخ دارم وقتی با code first وseeed به این فیلد مقدار میدم پایگاه داده آپدیت نمی‌شود
    و در متد up این فیلد تعریف نشده چطوری این فیلد را تعریف کنم
    • #
      ‫۱۰ سال و ۷ ماه قبل، سه‌شنبه ۱۳ اسفند ۱۳۹۲، ساعت ۱۳:۰۲
      از کتابخانه PersianDateTime استفاده کردید؟ چه خطایی گرفتید؟ PersianDateTime به عنوان نوع خاصیت تعریف شده؟ معادلی نداره سمت بانک اطلاعاتی.
      • #
        ‫۱۰ سال و ۷ ماه قبل، سه‌شنبه ۱۳ اسفند ۱۳۹۲، ساعت ۱۳:۱۰
        ممنون
         بعد از اجرای add-migration initial در اجرای دستورupdate-database خطای زیر را داد
        An error occurred while preparing the command definition. See the inner exception for detail 
         
        و در کلاس initial در متد UP تعریفی برای این فیلد وجود ندارد
         public PersianDateTime EnrollmentDate { get; set; }
        • #
          ‫۱۰ سال و ۷ ماه قبل، سه‌شنبه ۱۳ اسفند ۱۳۹۲، ساعت ۱۳:۲۵
          تعریفی نداره چون معادلی نداره در بانک اطلاعاتی. EF فیلد شما را باید بتونه به یک نوع خاص در بانک اطلاعاتی نگاشت کنه. چنین نوعی در سمت بانک اطلاعاتی وجود خارجی نداره. البته در SQL Server میشه نوع جدید تعریف کرد. بعد از تعریف، این طرف با Column typeName باید مشخص بشه.
  • #
    ‫۱۰ سال و ۳ ماه قبل، جمعه ۳۰ خرداد ۱۳۹۳، ساعت ۱۴:۱۷
    using (var db = new DBTestEntities())
                {
                    dataGridView1.DataSource =(from t in db.test
                                                  select  new
                                                  { 
                                                      Id= t.Id,
                                                      time = new PersianDateTime( DateTime.Parse(t.ResponseDate.ToString())).ToString(PersianDateTimeFormat.DateShortTime)
                                                  }).ToList();                
                }

    برای ذخیره اطلاعات در بانک این کلاس خوب کار میکند و مشکلی نیست . ولی برای نمایش در برنامه ویندوزی کد بالا عمل نمیکند و هیچ چیزی نشان نمی‌دهد . یک جدول ساده دارم که شامل دو فیلد  Id  و datetime  است .
      • #
        ‫۱۰ سال و ۳ ماه قبل، جمعه ۳۰ خرداد ۱۳۹۳، ساعت ۲۰:۰۶
        این تمام کد برنامه است :
        using System;
        using System.Linq;
        using System.Windows.Forms;
        
        namespace WindowsFormsApplication2
        {
            public partial class Form1 : Form
            {
                public Form1()
                {
                    InitializeComponent();
                }
        
                private void button1_Click(object sender, EventArgs e)
                {
                    //  این قسمت برای ورود اطلاعات به بانک است و با کمک کتابخانه پرژن دات نت  تاریخ شمسی را به میلادی تبدیل و ذخیره میکنم
                    using(var db = new h7Entities())
                    {
                        var t = new test
                        {
                            ResponseDate = PersianDateTime.Parse(textBox1.Text).ToDateTime()
                        };
                        db.test.Add(t);
                        db.SaveChanges();
                    }
                }
        
                private void Form1_Load(object sender, EventArgs e)
                {
                    // این قسمت هم فقط اطلاعات واکشی شده را در گرید نمایش میدهد . بدون هیچ شرطی ، یک سلکت ساده . . فقط از پرژن دانت نت برای تبدیل میلادی به شمسی کمک میگیرم
                    using (var db = new h7Entities())
                    {
                        dataGridView1.DataSource =(from t in db.test
                                                      select  new
                                                      { 
                                                          Id= t.Id,
                                                          time = new PersianDateTime(DateTime.Parse(t.ResponseDate.ToString())).ToString(PersianDateTimeFormat.DateShortTime)
                                                      }).ToList();                
                    }
        
                }
            }
        }

        کتابخانه PersianDateTime  را از نیوگت دریافت کردم .
        ولی چیزی در گرید نمایش نمیدهد .

        مدل برنامه هم :

         public partial class test
            {
                public int Id { get; set; }
                public Nullable<System.DateTime> ResponseDate { get; set; }
            }


        سوال دیگه اینکه وقتی تبدیلی انجام نمی‌شود ، خروجی زیر را دارم :


        حالا چطور از فیلدی که تاریخ را نمایش میدهد فقط آن را تبدیل به شمسی و نمایش دهد ؟ شبیه این  1365/02/02    ؟
        تشکر
        • #
          ‫۱۰ سال و ۳ ماه قبل، جمعه ۳۰ خرداد ۱۳۹۳، ساعت ۲۱:۳۷
          کلاس PersianDateTime سازنده‌های متعددی دارد. از سازنده‌ای که نوع DateTime را مستقیما دریافت می‌کند، استفاده کنید:
          new PersianDateTime(t.ResponseDate.Value).ToString(PersianDateTimeFormat.DateShortTime)
          یعنی با وجود این سازنده، نیازی به ToString و سپس DateTime.Parse آن نیست:
              /// <summary>
              /// Initializes a new instance of the PersianDateTime class to a specified dateTime.
              /// </summary>
              /// <param name="dateTime">A date and time in the Gregorian calendar.</param>
              public PersianDateTime(DateTime dateTime)
              {
                  _dateTime = dateTime;
              }
  • #
    ‫۱۰ سال و ۳ ماه قبل، یکشنبه ۱۵ تیر ۱۳۹۳، ساعت ۱۷:۴۴
    با سلام و تشکر
    چگونه یک تاریخ معتبر را بررسی کنیم؟
  • #
    ‫۸ سال و ۶ ماه قبل، یکشنبه ۱ فروردین ۱۳۹۵، ساعت ۰۴:۱۸
    برای تاریخ  1395/1/1 خطا میدهد ولی اگه بصورت 1395/01/01 نوشته بشه درست کار میکنه .
  • #
    ‫۷ سال و ۴ ماه قبل، شنبه ۳۰ اردیبهشت ۱۳۹۶، ساعت ۱۷:۱۷
    برای متد PersianDateTime.Parse   امکان استفاده تاریخ و ساعت به صورت یک رشته وجود ندارد؟ 
    PersianDateTime persianDate2 = PersianDateTime.Parse("1392/03/02 23:32:56");

    • #
      ‫۷ سال و ۴ ماه قبل، شنبه ۳۰ اردیبهشت ۱۳۹۶، ساعت ۱۷:۳۹
      روش دوم
      از کتابخانه‌ی DNTPersianUtils.Core استفاده کنید (با NET 4.x. و همچنین NET Core. سازگار است):
      "1395/11/3 7:30".ToGregorianDateTime()
    • #
      ‫۵ سال و ۲ ماه قبل، یکشنبه ۲۳ تیر ۱۳۹۸، ساعت ۱۸:۳۴
      var dateTime = PersianDateTime.Parse(date, $"{hours.ToString("00")}:{minutes.ToString("00")}:{seconds.ToString("00")}").ToDateTime();
  • #
    ‫۵ سال و ۲ ماه قبل، یکشنبه ۱۶ تیر ۱۳۹۸، ساعت ۱۴:۰۷
    چطور میشه از این ابزار در autoMapper که در فرم lambda نوشته میشه استفاده کرد؟