Is it possible to represent non gregorian dates as DateTime in .NET?
Asked Answered
B

2

6

I'm having trouble representing Persian (Solar Hijri Calendar) dates as DateTime in C#, specifically on certain days of particular months, for example 31/04 where in the Gregorian calendar such a date is meaningless:

System.Globalization.PersianCalendar p = new System.Globalization.PersianCalendar();
DateTime date = new DateTime(2013,7,22);
int year = p.GetYear(date);
int month = p.GetMonth(date);
int day = p.GetDayOfMonth(date);
DateTime d1 = new DateTime(year, month, day);

The above code will result in an ArgumentOutOfRangeException saying: Year, Month, and Day parameters describe an un-representable DateTime.

Which is expected.

How can I represent Persian Dates as DateTimes in .NET taking into accounts dates such as 30/02 and 31/04?

Bandoleer answered 31/7, 2013 at 6:58 Comment(2)
I'm just guessing here, but obviously those dates still corresponds to dates in the gregorian calendar. You're probably going to have to represent them in the gregorian calendar in DateTime, and do a conversion to and from everywhere. I don't know if this is supported in Noda-Time, but have you checked it?Mccutcheon
You mean I'll have to live with representing all dates as Gregorian dates and then writing some extension method to convert them to strings (this is what I'm doing now)? Also what is Noda-Time?Bandoleer
A
3

The above code will result in an ArgumentOutOfRangeException saying: Year, Month, and Day parameters describe an un-representable DateTime.

Yes, because unless you specify a calendar, the DateTime arguments are expected to be Gregorian. You can specify a calendar though:

DateTime d1 = new DateTime(year, month, day, p);

Note that if you now take d1.Year, you'll get back 2013, not year... DateTime is always Gregorian, basically. However, if you use a culture which has the Persian calendar as the default calendar, that will convert the values appropriately when you format a DateTime into a string. EDIT: Unfortunately, as per the documentation:

Currently, the PersianCalendar class is not an optional calendar for any culture supported by the CultureInfo class and consequently cannot be a default calendar.

As a comment has mentioned Noda Time, I can address that: it doesn't support the Persian calendar yet. It supports the lunar Hijri calendar, but not the solar one :( I could look into adding that into a future release...

Alkalify answered 31/7, 2013 at 7:4 Comment(9)
@MohammadSepahvand: That's exactly what I said: that's how you create a DateTime value from year/month/day values in a different calendar, but DateTime itself is fundamentally Gregorian.Alkalify
so basically, its impossible?Bandoleer
It's impossible to get DateTime to be anything but gregorian, but you can get help from the framework to do the conversion to and from.Mccutcheon
Thanks, yea it'd be great if a future release included the Solar calender.Bandoleer
@MohammadSepahvand: I'll look into it - it partly depends on how predictable it is. If it's an observation-based calendar, that makes it significantly harder. We'll see though :) (It's also hard for me to test well, with no experience of the calendar myself.)Alkalify
Leap years in .NET's implementation are so: "A leap year is a year that, when divided by 33, has a remainder of 1, 5, 9, 13, 17, 22, 26, or 30. [...] There are approximately eight leap years in every 33-year cycle." This is nonsense, of course, since by their rule they make exactly eight leap years per 33 years, which leads to the astronomical not entirely exact 365.2424242424 days per year. In the true Persian calendar, the day (according to Persian standard meridian, longitude 52.5°E) of the vernal equinox is the first day of the year. This needs to be looked up in an astronomical table.Blent
@JeppeStigNielsen: Thanks for the detail. Do you think it's fair to say that implementing it the same way as .NET would be better than not implementing it at all? Those are likely to be the alternatives :)Alkalify
Not sure. I believe the next time we will have trouble, is in about 82 years from now. The .NET implementation claims 1473 A.H. is not a leap year, while fourmilab.ch/documents/calendar says it is a leap year. I haven't checked years in the past. Because 365 + 8/33 is a really good approximation of the number of days in a year, most of the time the leap years will reapeat in a 33-year cycle, but sometimes they have to break the 33-year rule, of course.Blent
@JeppeStigNielsen: That sounds good enough to me, to be honest. Aside from anything else, being inconsistent with the .NET framework would make interoperability trickier. Will document the inaccuracy though.Alkalify
C
1

From MSDN;

Each DateTime member implicitly uses the Gregorian calendar to perform its operation, with the exception of constructors that specify a calendar, and methods with a parameter derived from IFormatProvider, such as System.Globalization.DateTimeFormatInfo, that implicitly specifies a calendar.

Also from PersianCalendar Class

Currently, the PersianCalendar class is not an optional calendar for any culture supported by the CultureInfo class and consequently cannot be a default calendar.

What you want seems not possible to me.

Collegium answered 31/7, 2013 at 7:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.