mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Changed implementation of DateTokens to use localization abstractions. Added more tokens. Beefed up unit tests to cover all tokens.
This commit is contained in:
@@ -2,27 +2,27 @@
|
||||
|
||||
namespace Orchard.AuditTrail.Helpers {
|
||||
public static class DateTimeExtensions {
|
||||
public static DateTime? Earliest(this DateTime? value) {
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
return Earliest(value.Value);
|
||||
}
|
||||
|
||||
public static DateTime Earliest(this DateTime value) {
|
||||
public static DateTime StartOfDay(this DateTime value) {
|
||||
return new DateTime(value.Year, value.Month, value.Day, 0, 0, 0, 0, value.Kind);
|
||||
}
|
||||
|
||||
public static DateTime? Latest(this DateTime? value) {
|
||||
public static DateTime? StartOfDay(this DateTime? value) {
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
return StartOfDay(value.Value);
|
||||
}
|
||||
|
||||
public static DateTime EndOfDay(this DateTime value) {
|
||||
return new DateTime(value.Year, value.Month, value.Day, 23, 59, 59, 999, value.Kind);
|
||||
}
|
||||
|
||||
public static DateTime? EndOfDay(this DateTime? value) {
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
var v = value.Value;
|
||||
return new DateTime(v.Year, v.Month, v.Day, 23, 59, 59, 999, v.Kind);
|
||||
}
|
||||
|
||||
public static DateTime Latest(this DateTime value) {
|
||||
return new DateTime(value.Year, value.Month, value.Day, 23, 59, 59, 999, value.Kind);
|
||||
}
|
||||
}
|
||||
}
|
@@ -206,7 +206,7 @@ namespace Orchard.AuditTrail.Services {
|
||||
}
|
||||
|
||||
public IEnumerable<AuditTrailEventRecord> Trim(TimeSpan retentionPeriod) {
|
||||
var dateThreshold = (_clock.UtcNow.Latest() - retentionPeriod);
|
||||
var dateThreshold = (_clock.UtcNow.EndOfDay() - retentionPeriod);
|
||||
var query = _auditTrailRepository.Table.Where(x => x.CreatedUtc <= dateThreshold);
|
||||
var records = query.ToArray();
|
||||
|
||||
|
@@ -18,8 +18,8 @@ namespace Orchard.AuditTrail.Services {
|
||||
public override void Filter(QueryFilterContext context) {
|
||||
var userName = context.Filters.Get("username");
|
||||
var category = context.Filters.Get("category");
|
||||
var from = GetDateFromFilter(context.Filters, "From", "from").Earliest();
|
||||
var to = GetDateFromFilter(context.Filters, "To", "to").Latest();
|
||||
var from = GetDateFromFilter(context.Filters, "From", "from").StartOfDay();
|
||||
var to = GetDateFromFilter(context.Filters, "To", "to").EndOfDay();
|
||||
var query = context.Query;
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(userName)) {
|
||||
@@ -57,13 +57,12 @@ namespace Orchard.AuditTrail.Services {
|
||||
}
|
||||
|
||||
private DateTime? GetDateFromFilter(Filters filters, string fieldName, string prefix) {
|
||||
var dateString = filters.Get(prefix + ".Date");
|
||||
try {
|
||||
var dateString = filters.Get(prefix + ".Date");
|
||||
var timeString = filters.Get(prefix + ".Time");
|
||||
return _dateLocalizationServices.ConvertFromLocalizedString(dateString, timeString);
|
||||
return _dateLocalizationServices.ConvertFromLocalizedDateString(dateString);
|
||||
}
|
||||
catch (FormatException ex) {
|
||||
filters.UpdateModel.AddModelError(prefix, T(@"Error parsing ""{0}"" date: {1}", fieldName, ex.Message));
|
||||
filters.UpdateModel.AddModelError(prefix, T(@"Error parsing '{0}' date string '{1}': {2}", fieldName, dateString, ex.Message));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Localization.Models;
|
||||
using Orchard.Localization.Services;
|
||||
using Orchard.Mvc.Html;
|
||||
using Orchard.Services;
|
||||
@@ -8,66 +9,79 @@ using Orchard.Services;
|
||||
namespace Orchard.Tokens.Providers {
|
||||
public class DateTokens : ITokenProvider {
|
||||
private readonly IClock _clock;
|
||||
private readonly IDateTimeFormatProvider _dateTimeLocalization;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly Lazy<CultureInfo> _cultureInfo;
|
||||
private readonly IDateTimeFormatProvider _dateTimeFormats;
|
||||
private readonly IDateFormatter _dateFormatter;
|
||||
private readonly IDateLocalizationServices _dateLocalizationServices;
|
||||
|
||||
//private readonly Lazy<CultureInfo> _cultureInfo;
|
||||
|
||||
public DateTokens(
|
||||
IClock clock,
|
||||
IDateTimeFormatProvider dateTimeLocalization,
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IDateLocalizationServices dateServices) {
|
||||
IDateTimeFormatProvider dateTimeFormats,
|
||||
IDateFormatter dateFormatter,
|
||||
IDateLocalizationServices dateLocalizationServices) {
|
||||
_clock = clock;
|
||||
_dateTimeLocalization = dateTimeLocalization;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_cultureInfo = new Lazy<CultureInfo>(() => CultureInfo.GetCultureInfo(_workContextAccessor.GetContext().CurrentCulture));
|
||||
_dateLocalizationServices = dateServices;
|
||||
_dateTimeFormats = dateTimeFormats;
|
||||
_dateFormatter = dateFormatter;
|
||||
_dateLocalizationServices = dateLocalizationServices;
|
||||
|
||||
//_cultureInfo = new Lazy<CultureInfo>(() => CultureInfo.GetCultureInfo(_workContextAccessor.GetContext().CurrentCulture));
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public void Describe(DescribeContext context) {
|
||||
context.For("Date", T("Date/time"), T("Current date/time tokens"))
|
||||
context.For("Date", T("Date/Time"), T("Current date/time tokens"))
|
||||
.Token("Since", T("Since"), T("Relative to the current date/time."), "Date")
|
||||
.Token("Local", T("Local"), T("Based on the configured time zone and calendar."), "Date")
|
||||
.Token("Short", T("Short Date and Time"), T("Short date and time format."))
|
||||
.Token("ShortDate", T("Short Date"), T("Short date format."))
|
||||
.Token("ShortTime", T("Short Time"), T("Short time format."))
|
||||
.Token("Long", T("Long Date and Time"), T("Long date and time format."))
|
||||
.Token("Format:*", T("Format:<date format>"), T("Optional format specifier (e.g. yyyy/MM/dd). See format strings at <a target=\"_blank\" href=\"http://msdn.microsoft.com/en-us/library/az4se3k1.aspx\">Standard Formats</a> and <a target=\"_blank\" href=\"http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx\">Custom Formats</a>"), "DateTime");
|
||||
.Token("LongDate", T("Long Date"), T("Long date format."))
|
||||
.Token("LongTime", T("Long Time"), T("Long time format."))
|
||||
.Token("Format:*", T("Format:<formatString>"), T("Optional custom date/time format string (e.g. yyyy/MM/dd). For reference see <a target=\"_blank\" href=\"http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx\">Custom Date and Time Format Strings</a>"), "DateTime");
|
||||
}
|
||||
|
||||
public void Evaluate(EvaluateContext context) {
|
||||
context.For("Date", () => _clock.UtcNow)
|
||||
// {Date.Since}
|
||||
.Token("Since", DateTimeRelative)
|
||||
.Chain("Since", "Date", DateTimeRelative)
|
||||
// {Date.Local}
|
||||
.Token("Local", d => _dateLocalizationServices.ConvertToSiteTimeZone(d))
|
||||
.Token("Local", d => _dateLocalizationServices.ConvertToLocalizedString(d))
|
||||
.Chain("Local", "Date", d => _dateLocalizationServices.ConvertToSiteTimeZone(d))
|
||||
// {Date.Short}
|
||||
.Token("Short", d => _dateLocalizationServices.ConvertToLocalizedString(d, _dateTimeFormats.ShortDateTimeFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false }))
|
||||
// {Date.ShortDate}
|
||||
.Token("ShortDate", d => d.ToString(_dateTimeLocalization.ShortDateFormat, _cultureInfo.Value))
|
||||
.Token("ShortDate", d => _dateLocalizationServices.ConvertToLocalizedString(d, _dateTimeFormats.ShortDateFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false }))
|
||||
// {Date.ShortTime}
|
||||
.Token("ShortTime", d => d.ToString(_dateTimeLocalization.ShortTimeFormat, _cultureInfo.Value))
|
||||
.Token("ShortTime", d => _dateLocalizationServices.ConvertToLocalizedString(d, _dateTimeFormats.ShortTimeFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false }))
|
||||
// {Date.Long}
|
||||
.Token("Long", d => d.ToString(_dateTimeLocalization.LongDateTimeFormat, _cultureInfo.Value))
|
||||
.Token("Long", d => _dateLocalizationServices.ConvertToLocalizedString(d, _dateTimeFormats.LongDateTimeFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false }))
|
||||
// {Date.LongDate}
|
||||
.Token("LongDate", d => _dateLocalizationServices.ConvertToLocalizedString(d, _dateTimeFormats.LongDateFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false }))
|
||||
// {Date.LongTime}
|
||||
.Token("LongTime", d => _dateLocalizationServices.ConvertToLocalizedString(d, _dateTimeFormats.LongTimeFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false }))
|
||||
// {Date}
|
||||
.Token(
|
||||
token => token == String.Empty ? String.Empty : null,
|
||||
(token, d) => d.ToString(_dateTimeLocalization.ShortDateFormat + " " + _dateTimeLocalization.ShortTimeFormat, _cultureInfo.Value))
|
||||
// {Date.Format:<formatstring>}
|
||||
(token, d) => _dateLocalizationServices.ConvertToLocalizedString(d, new DateLocalizationOptions() { EnableTimeZoneConversion = false }))
|
||||
// {Date.Format:<formatString>}
|
||||
.Token(
|
||||
token => token.StartsWith("Format:", StringComparison.OrdinalIgnoreCase) ? token.Substring("Format:".Length) : null,
|
||||
(token, d) => d.ToString(token, _cultureInfo.Value));
|
||||
(token, d) => _dateLocalizationServices.ConvertToLocalizedString(d, token, new DateLocalizationOptions() { EnableTimeZoneConversion = false }));
|
||||
}
|
||||
|
||||
private string DateTimeRelative(DateTime dateTimeUtc) {
|
||||
var time = _clock.UtcNow - dateTimeUtc.ToUniversalTime();
|
||||
|
||||
if (time.TotalDays > 7)
|
||||
return dateTimeUtc.ToString(T("'on' MMM d yyyy 'at' h:mm tt").ToString(), _cultureInfo.Value);
|
||||
return _dateFormatter.FormatDateTime(DateTimeParts.FromDateTime(dateTimeUtc), T("'on' MMM d yyyy 'at' h:mm tt").ToString());
|
||||
if (time.TotalHours > 24)
|
||||
return T.Plural("1 day ago", "{0} days ago", time.Days).ToString();
|
||||
if (time.TotalMinutes > 60)
|
||||
|
@@ -6,6 +6,7 @@ using Orchard.Localization.Services;
|
||||
using Orchard.Services;
|
||||
using Orchard.Tokens.Implementation;
|
||||
using Orchard.Tokens.Providers;
|
||||
using Orchard.Localization.Models;
|
||||
|
||||
namespace Orchard.Tokens.Tests {
|
||||
[TestFixture]
|
||||
@@ -13,6 +14,9 @@ namespace Orchard.Tokens.Tests {
|
||||
private IContainer _container;
|
||||
private ITokenizer _tokenizer;
|
||||
private IClock _clock;
|
||||
private IDateTimeFormatProvider _dateTimeFormats;
|
||||
private IDateLocalizationServices _dateLocalizationServices;
|
||||
private IDateFormatter _dateFormatter;
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
@@ -22,39 +26,107 @@ namespace Orchard.Tokens.Tests {
|
||||
builder.RegisterType<Tokenizer>().As<ITokenizer>();
|
||||
builder.RegisterType<DateTokens>().As<ITokenProvider>();
|
||||
builder.RegisterType<StubClock>().As<IClock>();
|
||||
builder.RegisterType<CultureDateTimeFormatProvider>().As<IDateTimeFormatProvider>();
|
||||
builder.RegisterType<DefaultDateFormatter>().As<IDateFormatter>();
|
||||
builder.RegisterType<DefaultDateLocalizationServices>().As<IDateLocalizationServices>();
|
||||
builder.RegisterType<StubWorkContextAccessor>().As<IWorkContextAccessor>();
|
||||
builder.RegisterType<SiteCalendarSelector>().As<ICalendarSelector>();
|
||||
builder.RegisterType<DefaultCalendarManager>().As<ICalendarManager>();
|
||||
builder.RegisterType<CultureDateTimeFormatProvider>().As<IDateTimeFormatProvider>();
|
||||
builder.RegisterType<DefaultDateFormatter>().As<IDateFormatter>();
|
||||
builder.RegisterType<DefaultDateLocalizationServices>().As<IDateLocalizationServices>();
|
||||
|
||||
_container = builder.Build();
|
||||
_tokenizer = _container.Resolve<ITokenizer>();
|
||||
_clock = _container.Resolve<IClock>();
|
||||
_dateTimeFormats = _container.Resolve<IDateTimeFormatProvider>();
|
||||
_dateLocalizationServices = _container.Resolve<IDateLocalizationServices>();
|
||||
_dateFormatter = _container.Resolve<IDateFormatter>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateTokens() {
|
||||
var dateTimeLocalization = _container.Resolve<IDateTimeFormatProvider>();
|
||||
var culture = CultureInfo.GetCultureInfo(_container.Resolve<IOrchardServices>().WorkContext.CurrentCulture);
|
||||
|
||||
var dateTimeFormat = dateTimeLocalization.ShortDateFormat + " " + dateTimeLocalization.ShortTimeFormat;
|
||||
|
||||
Assert.That(_tokenizer.Replace("{Date}", null), Is.EqualTo(_clock.UtcNow.ToString(dateTimeFormat, culture)));
|
||||
Assert.That(_tokenizer.Replace("{Date}", new { Date = new DateTime(1978, 11, 15, 0, 0, 0, DateTimeKind.Utc) }), Is.EqualTo(new DateTime(1978, 11, 15, 0, 0, 0, DateTimeKind.Utc).ToString(dateTimeFormat, culture)));
|
||||
public void TestDate() {
|
||||
Assert.That(_tokenizer.Replace("{Date}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, new DateLocalizationOptions() { EnableTimeZoneConversion = false })));
|
||||
Assert.That(_tokenizer.Replace("{Date}", new { Date = new DateTime(1978, 11, 15, 0, 0, 0, DateTimeKind.Utc) }), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(new DateTime(1978, 11, 15, 0, 0, 0, DateTimeKind.Utc), new DateLocalizationOptions() { EnableTimeZoneConversion = false })));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFormat() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Format:yyyy}", null), Is.EqualTo(_clock.UtcNow.ToString("yyyy")));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSince() {
|
||||
var date = _clock.UtcNow.Subtract(TimeSpan.FromHours(25));
|
||||
public void TestDateSince() {
|
||||
var date = _clock.UtcNow.AddHours(-25);
|
||||
Assert.That(_tokenizer.Replace("{Date.Since}", new { Date = date }), Is.EqualTo("1 day ago"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateShort() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Short}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.ShortDateTimeFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false })));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateShortDate() {
|
||||
Assert.That(_tokenizer.Replace("{Date.ShortDate}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.ShortDateFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false })));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateShortTime() {
|
||||
Assert.That(_tokenizer.Replace("{Date.ShortTime}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.ShortTimeFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false })));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLong() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Long}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.LongDateTimeFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false })));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLongDate() {
|
||||
Assert.That(_tokenizer.Replace("{Date.LongDate}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.LongDateFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false })));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLongTime() {
|
||||
Assert.That(_tokenizer.Replace("{Date.LongTime}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.LongTimeFormat, new DateLocalizationOptions() { EnableTimeZoneConversion = false })));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateFormat() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Format:yyyyMMdd}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, "yyyyMMdd", new DateLocalizationOptions() { EnableTimeZoneConversion = false })));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLocal() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Local}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow)));
|
||||
Assert.That(_tokenizer.Replace("{Date.Local}", new { Date = new DateTime(1978, 11, 15, 0, 0, 0, DateTimeKind.Utc) }), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(new DateTime(1978, 11, 15, 0, 0, 0, DateTimeKind.Utc))));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLocalShort() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Local.Short}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.ShortDateTimeFormat)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLocalShortDate() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Local.ShortDate}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.ShortDateFormat)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLocalShortTime() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Local.ShortTime}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.ShortTimeFormat)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLocalLong() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Local.Long}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.LongDateTimeFormat)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLocalLongDate() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Local.LongDate}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.LongDateFormat)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLocalLongTime() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Local.LongTime}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, _dateTimeFormats.LongTimeFormat)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDateLocalFormat() {
|
||||
Assert.That(_tokenizer.Replace("{Date.Local.Format:yyyyMMdd}", null), Is.EqualTo(_dateLocalizationServices.ConvertToLocalizedString(_clock.UtcNow, "yyyyMMdd")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ namespace Orchard.Tokens.Tests {
|
||||
_initMethod(this);
|
||||
}
|
||||
|
||||
_contextDictonary["CurrentTimeZone"] = TimeZoneInfo.Local;
|
||||
_contextDictonary["CurrentTimeZone"] = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
|
||||
_contextDictonary["CurrentCulture"] = "en-US";
|
||||
_contextDictonary["CurrentCalendar"] = null;
|
||||
}
|
||||
|
@@ -1,53 +1,12 @@
|
||||
DateTime? ConvertToSiteTimeZone(DateTime? date)
|
||||
DateTime? ConvertFromSiteTimeZone(DateTime? date)
|
||||
- Also provides overloads with non-nullable DateTime parameters for compatibility with existing callers.
|
||||
- Does only time zone conversion. No calendar conversion.
|
||||
|
||||
DateTimeParts? ConvertToSiteCalendar(DateTime? date)
|
||||
DateTime? ConvertFromSiteCalendar(Parts? dateParts)
|
||||
- Does only calendar conversion. No time zone conversion.
|
||||
- Instantiates the site calendar and does "manual" conversion.
|
||||
- Uses a custom storage structure DateTimeParts for non-gregorian representation.
|
||||
|
||||
string ConvertToLocalizedDateString(DateTime? date, DateLocalizationOptions options = DateLocalizationOptions.Default)
|
||||
string ConvertToLocalizedTimeString(DateTime? date, DateLocalizationOptions options = DateLocalizationOptions.Default)
|
||||
string ConvertToLocalizedString(DateTime? date, DateLocalizationOptions options)
|
||||
string ConvertToLocalizedString(DateTime? date, string format, DateLocalizationOptions options)
|
||||
- Also provides overloads with non-nullable DateTime parameters for compatibility with existing callers.
|
||||
- By default performs the full conversion (time zone, calendar and formatting). Can be overridden by DateLocalizationOptions.
|
||||
- If NOT ConvertCalendar, uses DateTime.ToString() with an cloned CultureInfo using GregorianCalendar of type Localized.
|
||||
- If ConvertCalendar and UNSUPPORTED non-default calendar, uses ConvertToSiteCalendar() and Mahsa's custom formatting.
|
||||
- If ConvertCalendar and SUPPORTED non-default calendar, uses DateTime.ToString() with cloned CultureInfo using an optional calendar instance, which does both calendar conversion and formatting.
|
||||
- Otherwise uses DateTime.ToString() with configured CultureInfo which does both calendar conversion and formatting.
|
||||
|
||||
DateTime? ConvertFromLocalizedDateString(string dateString, DateLocalizationOptions options = DateLocalizationOptions.Default)
|
||||
DateTime? ConvertFromLocalizedTimeString(string timeString, DateLocalizationOptions options = DateLocalizationOptions.Default)
|
||||
DateTime? ConvertFromLocalizedString(string dateTimeString, DateLocalizationOptions options = DateLocalizationOptions.Default)
|
||||
DateTime? ConvertFromLocalizedString(string dateString, string timeString, DateLocalizationOptions options = DateLocalizationOptions.Default)
|
||||
- By default performs the full conversion (parsing, calendar and time zone). Can be overridden by DateLocalizationOptions.
|
||||
- ConvertFromLocalizedDateString() returns a DateTime? with the time component set to 00:00:00. ConvertTimeZone is ignored.
|
||||
- ConvertFromLocalizedTimeString() returns a DateTime? with the date component set to DateTime.MinValue. ConvertCalendar is ignored.
|
||||
- If NOT ConvertCalendar, uses DateTime.Parse() with an cloned CultureInfo using GregorianCalendar of type Localized.
|
||||
- If ConvertCalendar and UNSUPPORTED non-default calendar, uses Mahsa's custom parsing and ConvertToSiteCalendar().
|
||||
- If ConvertCalendar and SUPPORTED non-default calendar, uses DateTime.Parse() with cloned CultureInfo using an optional calendar instance, which does both parsing and calendar conversion.
|
||||
- Otherwise uses DateTime.Parse() with configured CultureInfo which does both parsing and calendar conversion.
|
||||
- ConvertFromLocalizedString() with dateString or timeString set to null is the same as ConvertFromLocalizedTimeString() and ConvertFromLocalizedDateString() respectively.
|
||||
- Checks if the parsed string matches NullText, and if so returns null.
|
||||
|
||||
struct DateLocalizationOptions {
|
||||
bool ConvertTimeZone;
|
||||
bool ConvertCalendar;
|
||||
string NullText;
|
||||
}
|
||||
|
||||
TODO:
|
||||
* Test for proper handling of fraction (f) format specifier - suspect it does not work properly in current state
|
||||
* Add formatting and parsing of time zone information (add timezone properties to TimeParts structure)
|
||||
* Write unit tests for DefaultDateLocalizationServices
|
||||
* Add warning message when saving unsupported combination in settings
|
||||
* Add support for the different Gregorian calendar types
|
||||
* Go over date conversion logic in audit trail filtering to make sure it's correct
|
||||
* Go over date conversion logic in DateTokens to make sure it's correct
|
||||
* Improve DateTimeField:
|
||||
- Surface the field mode (date, time or both)
|
||||
- Do not perform time-zone conversion in date-only mode
|
||||
* Test for proper handling of fraction (f) format specifier - suspect it does not work properly in current state
|
||||
* Add formatting and parsing of time zone information (add timezone properties to TimeParts structure)
|
||||
* Write unit tests for DefaultDateLocalizationServices
|
||||
* Add warning message when saving unsupported combination in settings
|
||||
* Add support for the different Gregorian calendar types
|
||||
* Improve DateTimeField:
|
||||
- Surface the field mode (date, time or both)
|
||||
- Do not perform time-zone conversion in date-only mode
|
||||
|
||||
BREAKING:
|
||||
* DateTokens "Date.Format:<formatString>" and "Date.Local.Format:<formatString>" only supports custom date/time format strings.
|
Reference in New Issue
Block a user