Persian calendar

Topics: Core
Nov 17, 2013 at 5:38 PM
hi guys
recently I modified the core project to put some code regarding to Persian calendar, is it possible to put these code inside of the Orchard.Core Project?

Here is the changes:
Orchard.Core.Shapes.DateTimeShapes :
[Shape]
        public IHtmlString DateTime(DateTime DateTimeUtc, LocalizedString CustomFormat)
        {
            //using a LocalizedString forces the caller to use a localizable format

            if (CustomFormat == null || String.IsNullOrWhiteSpace(CustomFormat.Text))
            {
                return DateTime(DateTimeUtc, _dateTimeLocalization.LongDateTimeFormat);
            }

            if (_cultureInfo.Value.Name == "fa-IR") return new MvcHtmlString(ConvertToPersianTime(ConvertToDisplayTime(DateTimeUtc)));
            return new MvcHtmlString(ConvertToDisplayTime(DateTimeUtc).ToString(CustomFormat.Text, _cultureInfo.Value));
        }


        /// <summary>
        /// Converts gregorian date to persian date (Jalali Calendar).
        /// </summary>
        /// <param name="displayDateTime">The Gregorian date.</param>
        /// <returns>The Persian date.</returns>
        private string ConvertToPersianTime(DateTime displayDateTime)
        {
            PersianCalendar p = new PersianCalendar();
            int year = p.GetYear(displayDateTime);
            int month = p.GetMonth(displayDateTime);
            int day = p.GetDayOfMonth(displayDateTime);
            return string.Format("{0}/{1}/{2} {3}", year, month, day, displayDateTime.TimeOfDay.ToString());
        }
Developer
Nov 17, 2013 at 8:01 PM
Edited Nov 17, 2013 at 8:02 PM
It doesn't feel right to hard-code support for one particular calendar in Core. Either there should be a generic way in .NET Framework to do this, or we should build a generic mechanism that can support all supported calendars, not only PersianCalendar.

The above point notwithstanding, it seems especially wrong to hard code the string format. At the very least one should do something like this instead:
var p = new PersianCalendar();
var year = p.GetYear(displayDateTime);
var month = p.GetMonth(displayDateTime);
var day = p.GetDayOfMonth(displayDateTime);
var hour = p.GetHour(displayDateTime);
var minute = p.GetMinute(displayDateTime);
var second = p.GetSecond(displayDateTime);
var persianDateTime = new DateTime(year, month, day, hour, minute, second);
return new MvcHtmlString(persianDateTime.ToString(_cultureInfo.Value)); // Format using CultureInfo for fa-IR which is hopefully configured.
Developer
Nov 17, 2013 at 8:13 PM
Edited Nov 17, 2013 at 8:16 PM
Actually, I just realized, a generic way to do this might be to use the CultureInfo.DefaultCalendar property.
var c = _cultureInfo.DefaultCalendar;
var year = c.GetYear(displayDateTime);
var month = c.GetMonth(displayDateTime);
var day = c.GetDayOfMonth(displayDateTime);
var hour = c.GetHour(displayDateTime);
var minute = c.GetMinute(displayDateTime);
var second = c.GetSecond(displayDateTime);
var cultureCalendarDateTime = new DateTime(year, month, day, hour, minute, second);
return new MvcHtmlString(cultureCalendarDateTime.ToString(_cultureInfo.Value));
This would take care of all calendars depending on configured culture - not just Persian.

So, one good way to add this support to Orchard would be to add a setting named something like "Use default calendar for configured culture when displaying dates and times". If this setting is enabled, we employ the above logic. If not (default, current behavior) Gregorian would always be used.
Nov 18, 2013 at 5:10 PM
Thanks Decorum,
Yours is better, so is it possible to put this patch in the source of orchard?
Coordinator
Nov 18, 2013 at 5:37 PM
Open a bug if there isn't one already, then make a pull request.
Developer
Nov 19, 2013 at 6:40 PM
There is already an open issue to this effect:
https://orchard.codeplex.com/workitem/19392