예제 #1
0
        public void EqualsTest02() {
            var target = new DateTimeParts(2014, 5, 31, 10, 0, 0, 0, DateTimeKind.Unspecified, offset: TimeSpan.Zero);
            var other = new DateTimeParts(2014, 5, 31, 10, 0, 0, 1, DateTimeKind.Unspecified, offset: TimeSpan.Zero);

            var result = target.Equals(other);

            Assert.IsFalse(result);
        }
 public virtual DateTime ConvertFromSiteCalendar(DateTimeParts parts) {
     return new DateTime(
         parts.Date.Year,
         parts.Date.Month, 
         parts.Date.Day,
         parts.Time.Hour, 
         parts.Time.Minute,
         parts.Time.Second, 
         parts.Time.Millisecond,
         CurrentCalendar,
         parts.Time.Kind);
 }
 public void ConvertFromSiteCalendarTest02() {
     var container = TestHelpers.InitializeContainer(null, "PersianCalendar", TimeZoneInfo.Utc);
     var dateTimePartsPersian = new DateTimeParts(1376, 10, 25, 21, 0, 0, 0, DateTimeKind.Utc, TimeSpan.Zero);
     var target = container.Resolve<IDateLocalizationServices>();
     var result = target.ConvertFromSiteCalendar(dateTimePartsPersian);
     var expected = new DateTime(1998, 1, 15, 21, 0, 0, DateTimeKind.Utc);
     Assert.AreEqual(expected, result);
 }
 public virtual string FormatDateTime(DateTimeParts parts) {
     return FormatDateTime(parts, _dateTimeFormatProvider.ShortDateTimeFormat);
 }
        public virtual string FormatDateTime(DateTimeParts parts, string format) {
            var useMonthNameGenitive = GetUseGenitiveMonthName(format);

            var replacements = GetDateFormatReplacements(useMonthNameGenitive).Concat(GetTimeFormatReplacements()).ToDictionary(item => item.Key, item => item.Value);
            var formatString = ConvertToFormatString(format, replacements);
            var calendar = CurrentCalendar;

            int twoDigitYear, hour12, offsetHours, offsetMinutes;
            bool isPm;
            string monthName, monthNameShort, monthNameGenitive, monthNameShortGenitive, dayName, dayNameShort, eraName, eraNameShort, amPm, amPmShort, timeZone, offsetSign, fraction1Zero, fraction2Zero, fraction3Zero, fraction1Digit, fraction2Digit, fraction3Digit;
            GetDateFormatValues(parts.Date, calendar, out twoDigitYear, out monthName, out monthNameShort, out monthNameGenitive, out monthNameShortGenitive, out dayName, out dayNameShort, out eraName, out eraNameShort);
            GetTimeFormatValues(parts.Time, out isPm, out hour12, out amPm, out amPmShort, out timeZone, out offsetSign, out offsetHours, out offsetMinutes, out fraction1Zero, out fraction2Zero, out fraction3Zero, out fraction1Digit, out fraction2Digit, out fraction3Digit);

            return String.Format(formatString, parts.Date.Year, twoDigitYear, parts.Date.Month, monthName, monthNameShort, monthNameGenitive, monthNameShortGenitive, parts.Date.Day, dayName, dayNameShort, eraName, eraNameShort, parts.Time.Hour, hour12, parts.Time.Minute, parts.Time.Second, fraction1Zero, fraction2Zero, fraction3Zero, fraction1Digit, fraction2Digit, fraction3Digit, amPm, amPmShort, timeZone, offsetSign, offsetHours, offsetMinutes);
        }
        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;
        }
        public void FormatDateTimeTest04() {
            var allCases = new ConcurrentBag<string>();
            var failedCases = new ConcurrentDictionary<string, Exception>();
            var maxFailedCases = 0;

            var options = new ParallelOptions();
            if (Debugger.IsAttached) {
                options.MaxDegreeOfParallelism = 1;
            }

            var allCultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
            Parallel.ForEach(allCultures, options, culture => { // All cultures on the machine.
                var container = TestHelpers.InitializeContainer(culture.Name, "GregorianCalendar", TimeZoneInfo.Utc);
                var formats = container.Resolve<IDateTimeFormatProvider>();
                var target = container.Resolve<IDateFormatter>();

                foreach (var dateTimeFormat in formats.AllDateTimeFormats) { // All date/time formats supported by the culture.
                    foreach (var millisecond in new[] { 0, 10, 500, 990, 999 }) { // Enough values to cover all fraction rounding cases.

                        DateTime dateTime = new DateTime(1998, 1, 1, 10, 30, 30, millisecond);
                        DateTimeParts dateTimeParts = new DateTimeParts(1998, 1, 1, 10, 30, 30, millisecond, DateTimeKind.Unspecified, offset: TimeSpan.Zero);

                        // Print reference string using Gregorian calendar to avoid calendar conversion.
                        var cultureGregorian = (CultureInfo)culture.Clone();
                        cultureGregorian.DateTimeFormat.Calendar = cultureGregorian.OptionalCalendars.OfType<GregorianCalendar>().First();

                        var caseKey = String.Format("{0}___{1}___{2}", culture.Name, dateTimeFormat, dateTimeParts);
                        allCases.Add(caseKey);
                        //Debug.WriteLine(String.Format("{0} cases tested so far. Testing case {1}...", allCases.Count, caseKey));

                        try {
                            var result = target.FormatDateTime(dateTimeParts, dateTimeFormat);
                            var expected = dateTime.ToString(dateTimeFormat, cultureGregorian);
                            if (result != expected) {
                                // The .NET date formatting logic contains a bug that causes it to recognize 'd' and 'dd'
                                // as numerical day specifiers even when they are embedded in literals. Our implementation
                                // does not contain this bug. If we encounter an unexpected result and the .NET reference
                                // result contains the genitive month name, replace it with the non-genitive month name
                                // before asserting.
                                var numericalDayPattern = @"(\b|[^d])d{1,2}(\b|[^d])";
                                var containsNumericalDay = Regex.IsMatch(dateTimeFormat, numericalDayPattern);
                                if (containsNumericalDay) {
                                    var monthName = formats.MonthNames[0];
                                    var monthNameGenitive = formats.MonthNamesGenitive[0];
                                    expected = expected.Replace(monthNameGenitive, monthName);
                                }
                            }
                            Assert.AreEqual(expected, result);
                        }
                        catch (Exception ex) {
                            failedCases.TryAdd(caseKey, ex);
                        }
                    }
                }
            });

            if (failedCases.Count > maxFailedCases) {
                throw new AggregateException(String.Format("Format tests failed for {0} of {1} cases. Expected {2} failed cases or less.", failedCases.Count, allCases.Count, maxFailedCases), failedCases.Values);
            }
        }