diff --git a/src/Orchard.Web/Modules/Orchard.Tokens/Providers/DateTokens.cs b/src/Orchard.Web/Modules/Orchard.Tokens/Providers/DateTokens.cs index 317bd200b..8418947cb 100644 --- a/src/Orchard.Web/Modules/Orchard.Tokens/Providers/DateTokens.cs +++ b/src/Orchard.Web/Modules/Orchard.Tokens/Providers/DateTokens.cs @@ -45,8 +45,8 @@ namespace Orchard.Tokens.Providers { .Token("Since", DateTimeRelative) .Chain("Since", "Date", DateTimeRelative) // {Date.Local} - .Token("Local", d => _dateServices.ConvertToLocal(d)) - .Chain("Local", "Date", d => _dateServices.ConvertToLocal(d)) + .Token("Local", d => _dateServices.ConvertToSiteTimeZone(d)) + .Chain("Local", "Date", d => _dateServices.ConvertToSiteTimeZone(d)) // {Date.ShortDate} .Token("ShortDate", d => d.ToString(_dateTimeLocalization.ShortDateFormat, _cultureInfo.Value)) // {Date.ShortTime} diff --git a/src/Orchard/Localization/Services/DefaultDateLocalizationServices.cs b/src/Orchard/Localization/Services/DefaultDateLocalizationServices.cs index cd6e1fa22..5e0a6dff1 100644 --- a/src/Orchard/Localization/Services/DefaultDateLocalizationServices.cs +++ b/src/Orchard/Localization/Services/DefaultDateLocalizationServices.cs @@ -1,15 +1,16 @@ using System; using System.Globalization; using Orchard.ContentManagement; +using Orchard.Framework.Localization.Models; using Orchard.Settings; namespace Orchard.Localization.Services { - public class DefaultDateLocalizationServices : IDateLocalizationServices { + public class DefaultDateLocalizationServices : IDateLocalizationServices { private readonly IWorkContextAccessor _workContextAccessor; - private readonly IDateTimeFormatProvider _dateTimeLocalization; - private readonly ICalendarManager _calendarManager; + private readonly IDateTimeFormatProvider _dateTimeLocalization; + private readonly ICalendarManager _calendarManager; public DefaultDateLocalizationServices( IWorkContextAccessor workContextAccessor, @@ -20,154 +21,179 @@ namespace Orchard.Localization.Services { _calendarManager = calendarManager; } - public virtual DateTime? ConvertToLocal(DateTime date) { - return ConvertToLocal(ToNullable(date)); - } + public virtual DateTime? ConvertToSiteTimeZone(DateTime date) { + return ConvertToSiteTimeZone(ToNullable(date)); + } - public virtual DateTime? ConvertToLocal(DateTime? date) { - if (!date.HasValue) { - return null; - } + public virtual DateTime? ConvertToSiteTimeZone(DateTime? date) { + if (!date.HasValue) { + return null; + } var workContext = _workContextAccessor.GetContext(); return TimeZoneInfo.ConvertTimeFromUtc(date.Value, workContext.CurrentTimeZone); - } + } - public virtual string ConvertToLocalString(DateTime date, string nullText = null) { - return ConvertToLocalString(ToNullable(date), _dateTimeLocalization.LongDateTimeFormat, nullText); - } + public virtual DateTime? ConvertFromSiteTimeZone(DateTime date) { + return ConvertFromSiteTimeZone(ToNullable(date)); + } - public virtual string ConvertToLocalString(DateTime date, string format, string nullText = null) { - return ConvertToLocalString(ToNullable(date), format, nullText); - } - - public virtual string ConvertToLocalString(DateTime? date, string format, string nullText = null) { - var localDate = ConvertToLocal(date); - if (!localDate.HasValue) { - return nullText; - } - - // If the configured current calendar is different from the default calendar - // of the configured current culture we must override the conversion process. - // We do this by using a custom CultureInfo modified to use GregorianCalendar - // (means no calendar conversion will be performed as part of the string - // formatting) and instead perform the calendar conversion ourselves. - - var cultureInfo = CurrentCulture; - var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); - if (!usingCultureCalendar) { - cultureInfo = (CultureInfo)CurrentCulture.Clone(); - cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); - var calendar = CurrentCalendar; - localDate = new DateTime(calendar.GetYear(localDate.Value), calendar.GetMonth(localDate.Value), calendar.GetDayOfMonth(localDate.Value), calendar.GetHour(localDate.Value), calendar.GetMinute(localDate.Value), calendar.GetSecond(localDate.Value)); - } - - return localDate.Value.ToString(format, cultureInfo); - } - - public virtual string ConvertToLocalDateString(DateTime date, string nullText = null) { - return ConvertToLocalDateString(ToNullable(date), nullText); - } - - public virtual string ConvertToLocalDateString(DateTime? date, string nullText = null) { - return ConvertToLocalString(date, _dateTimeLocalization.ShortDateFormat, nullText); - } - - public virtual string ConvertToLocalTimeString(DateTime date, string nullText = null) { - return ConvertToLocalTimeString(ToNullable(date), nullText); - } - - public virtual string ConvertToLocalTimeString(DateTime? date, string nullText = null) { - return ConvertToLocalString(date, _dateTimeLocalization.ShortTimeFormat, nullText); - } - - public virtual DateTime? ConvertFromLocal(DateTime date) { - return ConvertFromLocal(ToNullable(date)); - } - - public virtual DateTime? ConvertFromLocal(DateTime? date) { - if (!date.HasValue) { - return null; - } + public virtual DateTime? ConvertFromSiteTimeZone(DateTime? date) { + if (!date.HasValue) { + return null; + } var workContext = _workContextAccessor.GetContext(); - return TimeZoneInfo.ConvertTimeToUtc(date.Value, workContext.CurrentTimeZone); - } + return TimeZoneInfo.ConvertTimeToUtc(date.Value, workContext.CurrentTimeZone); + } - public virtual DateTime? ConvertFromLocalString(string dateString) { - if (String.IsNullOrWhiteSpace(dateString)) { - return null; - } + public virtual DateTimeParts? ConvertToSiteCalendar(DateTime? date) { + if (!date.HasValue){ + return null; + } + var calendar = CurrentCalendar; + return new DateTimeParts( + calendar.GetYear(date.Value), + calendar.GetMonth(date.Value), + calendar.GetDayOfMonth(date.Value), + calendar.GetHour(date.Value), + calendar.GetMinute(date.Value), + calendar.GetSecond(date.Value), + Convert.ToInt32(calendar.GetMilliseconds(date.Value))); + } - // If the configured current calendar is different from the default calendar - // of the configured current culture we must override the conversion process. - // We do this by using a custom CultureInfo modified to use GregorianCalendar - // (means no calendar conversion will be performed as part of the string - // parsing) and instead perform the calendar conversion ourselves. + public virtual DateTime? ConvertFromSiteCalendar(DateTimeParts? parts) { + if (!parts.HasValue) { + return null; + } + var calendar = CurrentCalendar; + return new DateTime(parts.Value.Date.Year, parts.Value.Date.Month, parts.Value.Date.Day, parts.Value.Time.Hour, parts.Value.Time.Minute, parts.Value.Time.Second, parts.Value.Time.Millisecond, calendar); + } - var cultureInfo = CurrentCulture; - var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); - if (!usingCultureCalendar) { - cultureInfo = (CultureInfo)CurrentCulture.Clone(); - cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); - } - var localDate = DateTime.Parse(dateString, CurrentCulture); - if (!usingCultureCalendar) { - var calendar = CurrentCalendar; - localDate = calendar.ToDateTime(localDate.Year, localDate.Month, localDate.Day, localDate.Hour, localDate.Minute, localDate.Second, localDate.Millisecond); - } + public virtual string ConvertToLocalString(DateTime date, string nullText = null) { + return ConvertToLocalString(ToNullable(date), _dateTimeLocalization.LongDateTimeFormat, nullText); + } - return ConvertFromLocal(localDate); - } + public virtual string ConvertToLocalString(DateTime date, string format, string nullText = null) { + return ConvertToLocalString(ToNullable(date), format, nullText); + } - public virtual DateTime? ConvertFromLocalString(string dateString, string timeString) { - if (String.IsNullOrWhiteSpace(dateString) && String.IsNullOrWhiteSpace(timeString)) { - return null; - } + public virtual string ConvertToLocalString(DateTime? date, string format, string nullText = null) { + var localDate = ConvertToSiteTimeZone(date); + if (!localDate.HasValue) { + return nullText; + } - // If the configured current calendar is different from the default calendar - // of the configured current culture we must override the conversion process. - // We do this by using a custom CultureInfo modified to use GregorianCalendar - // (means no calendar conversion will be performed as part of the string - // parsing) and instead perform the calendar conversion ourselves. + // If the configured current calendar is different from the default calendar + // of the configured current culture we must override the conversion process. + // We do this by using a custom CultureInfo modified to use GregorianCalendar + // (means no calendar conversion will be performed as part of the string + // formatting) and instead perform the calendar conversion ourselves. - var cultureInfo = CurrentCulture; - var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); - if (!usingCultureCalendar) { - cultureInfo = (CultureInfo)CurrentCulture.Clone(); - cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); - } + var cultureInfo = CurrentCulture; + var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); + if (!usingCultureCalendar) { + cultureInfo = (CultureInfo)CurrentCulture.Clone(); + cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); + var calendar = CurrentCalendar; + localDate = new DateTime(calendar.GetYear(localDate.Value), calendar.GetMonth(localDate.Value), calendar.GetDayOfMonth(localDate.Value), calendar.GetHour(localDate.Value), calendar.GetMinute(localDate.Value), calendar.GetSecond(localDate.Value)); + } - var localDate = !String.IsNullOrWhiteSpace(dateString) ? DateTime.Parse(dateString, cultureInfo) : new DateTime(1980, 1, 1); - var localTime = !String.IsNullOrWhiteSpace(timeString) ? DateTime.Parse(timeString, cultureInfo) : new DateTime(1980, 1, 1, 12, 0, 0); - var localDateTime = new DateTime(localDate.Year, localDate.Month, localDate.Day, localTime.Hour, localTime.Minute, localTime.Second); + return localDate.Value.ToString(format, cultureInfo); + } - if (!usingCultureCalendar) { - var calendar = CurrentCalendar; - localDateTime = calendar.ToDateTime(localDateTime.Year, localDateTime.Month, localDateTime.Day, localDateTime.Hour, localDateTime.Minute, localDateTime.Second, localDateTime.Millisecond); - } + public virtual string ConvertToLocalDateString(DateTime date, string nullText = null) { + return ConvertToLocalDateString(ToNullable(date), nullText); + } - return ConvertFromLocal(localDateTime); - } + public virtual string ConvertToLocalDateString(DateTime? date, string nullText = null) { + return ConvertToLocalString(date, _dateTimeLocalization.ShortDateFormat, nullText); + } - protected virtual CultureInfo CurrentCulture { - get { + public virtual string ConvertToLocalTimeString(DateTime date, string nullText = null) { + return ConvertToLocalTimeString(ToNullable(date), nullText); + } + + public virtual string ConvertToLocalTimeString(DateTime? date, string nullText = null) { + return ConvertToLocalString(date, _dateTimeLocalization.ShortTimeFormat, nullText); + } + + public virtual DateTime? ConvertFromLocalString(string dateString) { + if (String.IsNullOrWhiteSpace(dateString)) { + return null; + } + + // If the configured current calendar is different from the default calendar + // of the configured current culture we must override the conversion process. + // We do this by using a custom CultureInfo modified to use GregorianCalendar + // (means no calendar conversion will be performed as part of the string + // parsing) and instead perform the calendar conversion ourselves. + + var cultureInfo = CurrentCulture; + var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); + if (!usingCultureCalendar) { + cultureInfo = (CultureInfo)CurrentCulture.Clone(); + cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); + } + + var localDate = DateTime.Parse(dateString, CurrentCulture); + + if (!usingCultureCalendar) { + var calendar = CurrentCalendar; + localDate = calendar.ToDateTime(localDate.Year, localDate.Month, localDate.Day, localDate.Hour, localDate.Minute, localDate.Second, localDate.Millisecond); + } + + return ConvertFromSiteTimeZone(localDate); + } + + public virtual DateTime? ConvertFromLocalString(string dateString, string timeString) { + if (String.IsNullOrWhiteSpace(dateString) && String.IsNullOrWhiteSpace(timeString)) { + return null; + } + + // If the configured current calendar is different from the default calendar + // of the configured current culture we must override the conversion process. + // We do this by using a custom CultureInfo modified to use GregorianCalendar + // (means no calendar conversion will be performed as part of the string + // parsing) and instead perform the calendar conversion ourselves. + + var cultureInfo = CurrentCulture; + var usingCultureCalendar = CurrentCulture.DateTimeFormat.Calendar.GetType().IsInstanceOfType(CurrentCalendar); + if (!usingCultureCalendar) { + cultureInfo = (CultureInfo)CurrentCulture.Clone(); + cultureInfo.DateTimeFormat.Calendar = new GregorianCalendar(); + } + + var localDate = !String.IsNullOrWhiteSpace(dateString) ? DateTime.Parse(dateString, cultureInfo) : new DateTime(1980, 1, 1); + var localTime = !String.IsNullOrWhiteSpace(timeString) ? DateTime.Parse(timeString, cultureInfo) : new DateTime(1980, 1, 1, 12, 0, 0); + var localDateTime = new DateTime(localDate.Year, localDate.Month, localDate.Day, localTime.Hour, localTime.Minute, localTime.Second); + + if (!usingCultureCalendar) { + var calendar = CurrentCalendar; + localDateTime = calendar.ToDateTime(localDateTime.Year, localDateTime.Month, localDateTime.Day, localDateTime.Hour, localDateTime.Minute, localDateTime.Second, localDateTime.Millisecond); + } + + return ConvertFromSiteTimeZone(localDateTime); + } + + protected virtual CultureInfo CurrentCulture { + get { var workContext = _workContextAccessor.GetContext(); - return CultureInfo.GetCultureInfo(workContext.CurrentCulture); - } - } + return CultureInfo.GetCultureInfo(workContext.CurrentCulture); + } + } - protected virtual Calendar CurrentCalendar { - get { + protected virtual Calendar CurrentCalendar { + get { var workContext = _workContextAccessor.GetContext(); - if (!String.IsNullOrEmpty(workContext.CurrentCalendar)) - return _calendarManager.GetCalendarByName(workContext.CurrentCalendar); - return CurrentCulture.Calendar; - } - } + if (!String.IsNullOrEmpty(workContext.CurrentCalendar)) + return _calendarManager.GetCalendarByName(workContext.CurrentCalendar); + return CurrentCulture.Calendar; + } + } - protected virtual DateTime? ToNullable(DateTime date) { - return date == DateTime.MinValue ? new DateTime?() : new DateTime?(date); - } - } + protected virtual DateTime? ToNullable(DateTime date) { + return date == DateTime.MinValue ? new DateTime?() : new DateTime?(date); + } + } } \ No newline at end of file diff --git a/src/Orchard/Localization/Services/IDateLocalizationServices.cs b/src/Orchard/Localization/Services/IDateLocalizationServices.cs index 020e86556..f9df310f7 100644 --- a/src/Orchard/Localization/Services/IDateLocalizationServices.cs +++ b/src/Orchard/Localization/Services/IDateLocalizationServices.cs @@ -1,4 +1,5 @@ using System; +using Orchard.Framework.Localization.Models; namespace Orchard.Localization.Services { @@ -10,18 +11,48 @@ namespace Orchard.Localization.Services { public interface IDateLocalizationServices : IDependency { /// - /// Converts a non-nullable date from Gregorian calendar UTC to the Orchard configured calendar and time zone. + /// Converts a non-nullable date from UTC to the Orchard configured time zone. /// - /// The non-nullable UTC date to convert. DateTime.MinValue is translated to null. + /// The non-nullable UTC date to convert. DateTime.MinValue is translated to null. /// - DateTime? ConvertToLocal(DateTime date); + DateTime? ConvertToSiteTimeZone(DateTime dateUtc); /// - /// Converts a nullable date from Gregorian calendar UTC to the Orchard configured calendar and time zone. + /// Converts a nullable date from UTC to the Orchard configured time zone. /// - /// The nullable UTC date to convert. + /// The nullable UTC date to convert. /// - DateTime? ConvertToLocal(DateTime? date); + DateTime? ConvertToSiteTimeZone(DateTime? dateUtc); + + /// + /// Converts a non-nullable date from the Orchard configured time zone to UTC. + /// + /// The non-nullable local date to convert. DateTime.MinValue is translated to null. + /// + DateTime? ConvertFromSiteTimeZone(DateTime dateLocal); + + /// + /// Converts a nullable date from the Orchard configured time zone to UTC. + /// + /// The nullable local date to convert. + /// + DateTime? ConvertFromSiteTimeZone(DateTime? dateLocal); + + /// + /// Converts a date from Gregorian calendar to the Orchard configured calendar. + /// + /// The Gregorian calendar date to convert. + /// Null if the supplied date parameter was null. Otherwise a DateTimeParts instance representing the converted date. + DateTimeParts? ConvertToSiteCalendar(DateTime? date); + + /// + /// Converts a date from the Orchard configured calendar to Gregorian calendar. + /// + /// A DateTimeParts instance representing the Orchard configured calendar date to convert. + /// Null if the supplied parts parameter was null. Otherwise the converted Gregorian calendar date. + DateTime? ConvertFromSiteCalendar(DateTimeParts? parts); + + /// /// Converts a non-nullable date from Gregorian calendar UTC to the Orchard configured calendar and time zone and formats it using the default long date and time format string. @@ -81,20 +112,6 @@ namespace Orchard.Localization.Services { /// string ConvertToLocalTimeString(DateTime? date, string nullText = null); - /// - /// Converts a non-nullable date to Gregorian calendar UTC from the Orchard configured calendar and time zone. - /// - /// The non-nullable UTC date to convert. DateTime.MinValue is translated to null. - /// - DateTime? ConvertFromLocal(DateTime date); - - /// - /// Converts a nullable date from Gregorian calendar UTC to the Orchard configured calendar and time zone. - /// - /// The nullable UTC date to convert. - /// - DateTime? ConvertFromLocal(DateTime? date); - /// /// Parses a date and time string using the Orchard configured culture and converts it to Gregorian calendar UTC from the Orchard configured calendar and time zone. ///