From 2a2d44c226328c65aa99dd4b4f055589f70a4c6b Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Fri, 9 Mar 2012 16:09:49 -0800 Subject: [PATCH] #18388, #18502: Fixing DateTime localization and time zones Work Items: 18502, 18388 --HG-- branch : 1.x --- .hgsubstate | 2 +- .../Common/DateEditor/DateEditorDriver.cs | 30 +++-- .../Views/Parts.Common.Date.Edit.cshtml | 4 + src/Orchard.Web/Core/Orchard.Core.csproj | 1 + src/Orchard.Web/Core/Shapes/DateTimeShapes.cs | 6 +- .../Localization/DateTimeLocalization.cs | 126 ++++++++++++++++++ .../Drivers/ArchiveLaterPartDriver.cs | 27 ++-- .../ArchiveLater.Metadata.SummaryAdmin.cshtml | 2 +- .../Drivers/PublishLaterPartDriver.cs | 33 +++-- .../EditorTemplates/Parts/PublishLater.cshtml | 10 +- .../PublishLater.Metadata.SummaryAdmin.cshtml | 2 +- .../Orchard.jQuery/Orchard.jQuery.csproj | 6 + .../Views/DatePickerLocalization.cshtml | 51 +++++++ 13 files changed, 268 insertions(+), 32 deletions(-) create mode 100644 src/Orchard.Web/Core/Shapes/Localization/DateTimeLocalization.cs create mode 100644 src/Orchard.Web/Modules/Orchard.jQuery/Views/DatePickerLocalization.cshtml diff --git a/.hgsubstate b/.hgsubstate index 8c2116b46..50ae3ea11 100644 --- a/.hgsubstate +++ b/.hgsubstate @@ -5,4 +5,4 @@ dab42f20280f46c25c6c78ef13870f9a063bd026 src/Orchard.Web/Modules/Orchard.TaskLea 661c71dfa0dc833f01aa5244227e9e9bd14d11f3 src/Orchard.Web/Modules/Orchard.Tokens 88a640948e19a1a9dd79b859856375e292d53f2f src/orchard.web/Modules/Orchard.Alias 480597bb5f37f5506eaa580b91d1d8daa1f83d29 src/orchard.web/Modules/Orchard.Projections -973c38f5c22119102df509f0f3209278a9721f71 src/orchard.web/modules/Orchard.Fields +4bd0508bbbed49bc73f064d65583283c4e3ab2d0 src/orchard.web/modules/Orchard.Fields diff --git a/src/Orchard.Web/Core/Common/DateEditor/DateEditorDriver.cs b/src/Orchard.Web/Core/Common/DateEditor/DateEditorDriver.cs index 0b34c1dee..c4421ccc6 100644 --- a/src/Orchard.Web/Core/Common/DateEditor/DateEditorDriver.cs +++ b/src/Orchard.Web/Core/Common/DateEditor/DateEditorDriver.cs @@ -3,17 +3,24 @@ using System.Globalization; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; using Orchard.Core.Common.Models; +using Orchard.Core.Shapes.Localization; using Orchard.Localization; namespace Orchard.Core.Common.DateEditor { public class DateEditorDriver : ContentPartDriver { - private const string DatePattern = "M/d/yyyy"; - private const string TimePattern = "h:mm:ss tt"; + private readonly IDateTimeLocalization _dateTimeLocalization; + + private readonly Lazy _cultureInfo; public DateEditorDriver( - IOrchardServices services) { + IOrchardServices services, + IDateTimeLocalization dateTimeLocalization) { + _dateTimeLocalization = dateTimeLocalization; T = NullLocalizer.Instance; Services = services; + + // initializing the culture info lazy initializer + _cultureInfo = new Lazy(() => CultureInfo.GetCultureInfo(Services.WorkContext.CurrentCulture)); } public Localizer T { get; set; } @@ -52,8 +59,11 @@ namespace Orchard.Core.Common.DateEditor { theDatesHaveNotBeenModified; if (theEditorShouldBeBlank == false) { - model.CreatedDate = part.CreatedUtc.Value.ToLocalTime().ToString(DatePattern, CultureInfo.InvariantCulture); - model.CreatedTime = part.CreatedUtc.Value.ToLocalTime().ToString(TimePattern, CultureInfo.InvariantCulture); + // date and time are formatted using the same patterns as DateTimePicker is, preventing other cultures issues + var createdLocal = TimeZoneInfo.ConvertTimeFromUtc(part.CreatedUtc.Value, Services.WorkContext.CurrentTimeZone); + + model.CreatedDate = createdLocal.ToString(_dateTimeLocalization.ShortDateFormat.Text); + model.CreatedTime = createdLocal.ToString(_dateTimeLocalization.ShortTimeFormat.Text); } } @@ -62,11 +72,15 @@ namespace Orchard.Core.Common.DateEditor { if (!string.IsNullOrWhiteSpace(model.CreatedDate) && !string.IsNullOrWhiteSpace(model.CreatedTime)) { DateTime createdUtc; + string parseDateTime = String.Concat(model.CreatedDate, " ", model.CreatedTime); + var dateTimeFormat = _dateTimeLocalization.ShortDateFormat + " " + _dateTimeLocalization.ShortTimeFormat; - // use an english culture as it is the one used by jQuery.datepicker by default - if (DateTime.TryParse(parseDateTime, CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.AssumeLocal, out createdUtc)) { - part.CreatedUtc = createdUtc.ToUniversalTime(); + // use current culture + if (DateTime.TryParseExact(parseDateTime, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out createdUtc)) { + + // the date time is entered locally for the configured timezone + part.CreatedUtc = TimeZoneInfo.ConvertTimeToUtc(createdUtc, Services.WorkContext.CurrentTimeZone); } else { updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime)); diff --git a/src/Orchard.Web/Core/Common/Views/Parts.Common.Date.Edit.cshtml b/src/Orchard.Web/Core/Common/Views/Parts.Common.Date.Edit.cshtml index 431db9271..ba2036213 100644 --- a/src/Orchard.Web/Core/Common/Views/Parts.Common.Date.Edit.cshtml +++ b/src/Orchard.Web/Core/Common/Views/Parts.Common.Date.Edit.cshtml @@ -15,6 +15,10 @@ @Html.EditorFor(m => DateEditor.CreatedTime) @using(Script.Foot()) { + + @* generates the localization script *@ + @Display(New.DatePickerLocalization()) +