public DateTime?ConvertFromLocalizedString(string dateString, string timeString, DateLocalizationOptions options = null) { options = options ?? new DateLocalizationOptions(); var hasDate = dateString != null && dateString != options.NullText; var hasTime = timeString != null && timeString != options.NullText; if (!hasDate && !hasTime) { return(null); } var parts = new DateTimeParts( hasDate ? _dateFormatter.ParseDate(dateString) : DateParts.MinValue, hasTime ? _dateFormatter.ParseTime(timeString) : TimeParts.MinValue ); DateTime dateValue; if (hasDate && options.EnableCalendarConversion && !(CurrentCalendar is GregorianCalendar)) { dateValue = ConvertFromSiteCalendar(parts); } else { dateValue = parts.ToDateTime(new GregorianCalendar()); } if (hasTime && options.EnableTimeZoneConversion) { // If there is no date component (technically the date component is that of DateTime.MinValue) // then we must employ some trickery. With an undefined date it does not make sense // to consider DST variations throughout the year, so we will use an arbitrary (but fixed) // non-DST date for the conversion to ensure DST is never applied during conversion. The // date part is usually DateTime.MinValue which we should not use because time zone // conversion cannot wrap DateTime.MinValue around to the previous day, resulting in // an undefined result. Instead we convert the date to a hard-coded date of 2000-01-01 // before the conversion, and back to the original date after. if (!hasDate) { dateValue = new DateTime(2000, 1, 1, dateValue.Hour, dateValue.Minute, dateValue.Second, dateValue.Millisecond, dateValue.Kind); } dateValue = ConvertFromSiteTimeZone(dateValue); if (!hasDate) { dateValue = new DateTime(DateTime.MinValue.Year, DateTime.MinValue.Month, DateTime.MinValue.Day, dateValue.Hour, dateValue.Minute, dateValue.Second, dateValue.Millisecond, dateValue.Kind); } } if (options.EnableTimeZoneConversion) { dateValue = DateTime.SpecifyKind(dateValue, DateTimeKind.Utc); } return(dateValue); }
public DateTime?ConvertFromLocalizedString(string dateString, string timeString, DateLocalizationOptions options = null) { options = options ?? new DateLocalizationOptions(); var hasDate = dateString != null && dateString != options.NullText; var hasTime = timeString != null && timeString != options.NullText; if (!hasDate && !hasTime) { return(null); } var parts = new DateTimeParts( hasDate ? _dateFormatter.ParseDate(dateString) : DateParts.MinValue, hasTime ? _dateFormatter.ParseTime(timeString) : TimeParts.MinValue ); DateTime dateValue; if (hasDate && options.EnableCalendarConversion && !(CurrentCalendar is GregorianCalendar)) { dateValue = ConvertFromSiteCalendar(parts); } else { dateValue = parts.ToDateTime(new GregorianCalendar()); } if (hasTime && options.EnableTimeZoneConversion) { // If there is no date component (technically the date component is that of DateTime.MinValue) then // we must employ some trickery, for two reasons: // * DST can be active or not dependeng on the time of the year. We want the conversion to always act as if the time represents today, but we don't want that date stored. // * Time zone conversion cannot wrap DateTime.MinValue around to the previous day, resulting in undefined result. // Therefore we convert the date to today's date before the conversion, and back to DateTime.MinValue after. if (!hasDate) { var now = _clock.UtcNow; dateValue = new DateTime(now.Year, now.Month, now.Day, dateValue.Hour, dateValue.Minute, dateValue.Second, dateValue.Millisecond, dateValue.Kind); } dateValue = ConvertFromSiteTimeZone(dateValue); if (!hasDate) { dateValue = new DateTime(DateTime.MinValue.Year, DateTime.MinValue.Month, DateTime.MinValue.Day, dateValue.Hour, dateValue.Minute, dateValue.Second, dateValue.Millisecond, dateValue.Kind); } } if (options.EnableTimeZoneConversion) { dateValue = DateTime.SpecifyKind(dateValue, DateTimeKind.Utc); } return(dateValue); }