예제 #1
0
        /// <summary>
        /// Checks that each day from the given start year to the end year (inclusive) is equal
        /// between the BCL and the Noda Time calendar. Additionally, the number of days in each month and year
        /// and the number of months (and leap year status) in each year is checked.
        /// </summary>
        internal static void AssertEquivalent(Calendar bcl, CalendarSystem noda, int fromYear, int toYear)
        {
            // We avoid asking the BCL to create a DateTime on each iteration, simply
            // because the BCL implementation is so slow. Instead, we just check at the start of each month that
            // we're at the date we expect.
            DateTime bclDate = bcl.ToDateTime(fromYear, 1, 1, 0, 0, 0, 0);
            for (int year = fromYear; year <= toYear; year++)
            {
                Assert.AreEqual(bcl.GetDaysInYear(year), noda.GetDaysInYear(year), "Year: {0}", year);
                Assert.AreEqual(bcl.GetMonthsInYear(year), noda.GetMonthsInYear(year), "Year: {0}", year);
                for (int month = 1; month <= noda.GetMonthsInYear(year); month++)
                {
                    // Sanity check at the start of each month. Even this is surprisingly slow.
                    // (These three tests make up about 20% of the total execution time for the test.)
                    Assert.AreEqual(year, bcl.GetYear(bclDate));
                    Assert.AreEqual(month, bcl.GetMonth(bclDate));
                    Assert.AreEqual(1, bcl.GetDayOfMonth(bclDate));

                    Assert.AreEqual(bcl.GetDaysInMonth(year, month), noda.GetDaysInMonth(year, month),
                        "Year: {0}; Month: {1}", year, month);
                    Assert.AreEqual(bcl.IsLeapYear(year), noda.IsLeapYear(year), "Year: {0}", year);
                    for (int day = 1; day <= noda.GetDaysInMonth(year, month); day++)
                    {
                        LocalDate nodaDate = new LocalDate(year, month, day, noda);
                        Assert.AreEqual(bclDate, nodaDate.ToDateTimeUnspecified(),
                            "Original calendar system date: {0:yyyy-MM-dd}", nodaDate);
                        Assert.AreEqual(nodaDate, LocalDate.FromDateTime(bclDate, noda));
                        Assert.AreEqual(year, nodaDate.Year);
                        Assert.AreEqual(month, nodaDate.Month);
                        Assert.AreEqual(day, nodaDate.Day);
                        bclDate = bclDate.AddDays(1);
                    }
                }
            }
        }
            internal override ParseResult <LocalDate> CalculateValue(PatternFields usedFields)
            {
                // This will set Year if necessary
                ParseResult <LocalDate> failure = DetermineYear(usedFields);

                if (failure != null)
                {
                    return(failure);
                }
                // This will set MonthOfYearNumeric if necessary
                failure = DetermineMonth(usedFields);
                if (failure != null)
                {
                    return(failure);
                }

                int day = IsFieldUsed(usedFields, PatternFields.DayOfMonth) ? DayOfMonth : templateValue.Day;

                if (day > Calendar.GetDaysInMonth(Year, MonthOfYearNumeric))
                {
                    return(ParseResult <LocalDate> .DayOfMonthOutOfRange(day, MonthOfYearNumeric, Year));
                }

                LocalDate value = new LocalDate(Year, MonthOfYearNumeric, day, Calendar);

                if (IsFieldUsed(usedFields, PatternFields.DayOfWeek) && DayOfWeek != value.DayOfWeek)
                {
                    return(ParseResult <LocalDate> .InconsistentDayOfWeekTextValue);
                }

                return(ParseResult <LocalDate> .ForValue(value));
            }
예제 #3
0
        public void MaxDate(CalendarSystem calendar)
        {
            // Construct the largest LocalDate we can, and validate that all the properties can be fetched without
            // issues.
            int year  = calendar.MaxYear;
            int month = calendar.GetMaxMonth(year);
            int day   = calendar.GetDaysInMonth(year, month);

            ValidateProperties(year, month, day, calendar);
        }
예제 #4
0
        public static Instant GetMonthEndInstant(this LocalDate forDate, DateTimeZone timeZone)
        {
            ZonedDateTime  zonedStartDateTime = timeZone.AtStartOfDay(forDate);
            CalendarSystem calendar           = zonedStartDateTime.Calendar;
            int            daysInMonth        = calendar.GetDaysInMonth(zonedStartDateTime.Year, zonedStartDateTime.Month);
            ZonedDateTime  zonedEndDateTime   =
                timeZone.AtStartOfDay(new LocalDate(zonedStartDateTime.Year, zonedStartDateTime.Month, daysInMonth));

            return(zonedEndDateTime.ToInstant());
        }
예제 #5
0
        /// <summary>
        /// Checks that each day from the given start year to the end year (inclusive) is equal
        /// between the BCL and the Noda Time calendar. Additionally, the number of days in each month and year
        /// and the number of months (and leap year status) in each year is checked.
        /// </summary>
        internal static void AssertEquivalent(Calendar bcl, CalendarSystem noda, int fromYear, int toYear)
        {
            // We avoid asking the BCL to create a DateTime on each iteration, simply
            // because the BCL implementation is so slow. Instead, we just check at the start of each month that
            // we're at the date we expect.
            DateTime bclDate = bcl.ToDateTime(fromYear, 1, 1, 0, 0, 0, 0);

            for (int year = fromYear; year <= toYear; year++)
            {
                Assert.AreEqual(bcl.GetDaysInYear(year), noda.GetDaysInYear(year), "Year: {0}", year);
                Assert.AreEqual(bcl.GetMonthsInYear(year), noda.GetMonthsInYear(year), "Year: {0}", year);
                for (int month = 1; month <= noda.GetMonthsInYear(year); month++)
                {
                    // Sanity check at the start of each month. Even this is surprisingly slow.
                    // (These three tests make up about 20% of the total execution time for the test.)
                    Assert.AreEqual(year, bcl.GetYear(bclDate));
                    Assert.AreEqual(month, bcl.GetMonth(bclDate));
                    Assert.AreEqual(1, bcl.GetDayOfMonth(bclDate));

                    Assert.AreEqual(bcl.GetDaysInMonth(year, month), noda.GetDaysInMonth(year, month),
                                    "Year: {0}; Month: {1}", year, month);
                    Assert.AreEqual(bcl.IsLeapYear(year), noda.IsLeapYear(year), "Year: {0}", year);
                    for (int day = 1; day <= noda.GetDaysInMonth(year, month); day++)
                    {
                        LocalDate nodaDate = new LocalDate(year, month, day, noda);
                        Assert.AreEqual(bclDate, nodaDate.ToDateTimeUnspecified(),
                                        "Original calendar system date: {0:yyyy-MM-dd}", nodaDate);
                        Assert.AreEqual(nodaDate, LocalDate.FromDateTime(bclDate, noda));
                        Assert.AreEqual(year, nodaDate.Year);
                        Assert.AreEqual(month, nodaDate.Month);
                        Assert.AreEqual(day, nodaDate.Day);
                        bclDate = bclDate.AddDays(1);
                    }
                }
            }
        }
        /// <summary>
        /// Converts each day in a full leap cycle (for coverage of different scenarios) to the ISO
        /// calendar and back. This exercises fetching the number of days since the epoch and getting
        /// a year/month/day *from* a number of days.
        /// </summary>
        private static void TestLeapCycle(CalendarSystem calendar)
        {
            for (int year = 5400; year < 5419; year++)
            {
#if !V1
                int maxMonth = calendar.GetMonthsInYear(year);
#else
                int maxMonth = calendar.GetMaxMonth(year);
#endif
                for (int month = 1; month <= maxMonth; month++)
                {
                    int maxDay = calendar.GetDaysInMonth(year, month);
                    for (int day = 1; day <= maxDay; day++)
                    {
                        var date = new LocalDate(year, month, day, calendar);
                        date.WithCalendar(CalendarSystem.Iso).WithCalendar(calendar).Consume();
                    }
                }
            }
        }
        /// <summary>
        /// Converts each day in a full leap cycle (for coverage of different scenarios) to the ISO
        /// calendar and back. This exercises fetching the number of days since the epoch and getting
        /// a year/month/day *from* a number of days.
        /// </summary>
        private static void TestLeapCycle(CalendarSystem calendar)
        {
            for (int year = 5400; year < 5419; year++)
            {
#if !V1
                int maxMonth = calendar.GetMonthsInYear(year);
#else
                int maxMonth = calendar.GetMaxMonth(year);
#endif
                for (int month = 1; month <= maxMonth; month++)
                {
                    int maxDay = calendar.GetDaysInMonth(year, month);
                    for (int day = 1; day <= maxDay; day++)
                    {
                        var date = new LocalDate(year, month, day, calendar);
                        date.WithCalendar(CalendarSystem.Iso).WithCalendar(calendar).Consume();
                    }
                }
            }
        }
예제 #8
0
            internal override ParseResult <LocalDate> CalculateValue(PatternFields usedFields, string text)
            {
                if (usedFields.HasAny(PatternFields.EmbeddedDate))
                {
                    return(ParseResult <LocalDate> .ForValue(new LocalDate(Year, MonthOfYearNumeric, DayOfMonth, Calendar)));
                }
                // This will set Year if necessary
                ParseResult <LocalDate> failure = DetermineYear(usedFields, text);

                if (failure != null)
                {
                    return(failure);
                }
                // This will set MonthOfYearNumeric if necessary
                failure = DetermineMonth(usedFields, text);
                if (failure != null)
                {
                    return(failure);
                }

                int day = usedFields.HasAny(PatternFields.DayOfMonth) ? DayOfMonth : TemplateValue.Day;

                if (day > Calendar.GetDaysInMonth(Year, MonthOfYearNumeric))
                {
                    return(ParseResult <LocalDate> .DayOfMonthOutOfRange(text, day, MonthOfYearNumeric, Year));
                }

                LocalDate value = new LocalDate(Year, MonthOfYearNumeric, day, Calendar);

                if (usedFields.HasAny(PatternFields.DayOfWeek) && DayOfWeek != value.DayOfWeek)
                {
                    return(ParseResult <LocalDate> .InconsistentDayOfWeekTextValue(text));
                }

                // FIXME: If we got an era, check that the resulting date really lies within that era.
                return(ParseResult <LocalDate> .ForValue(value));
            }
예제 #9
0
        [Test, Timeout(300000)] // Can take a long time under NCrunch.
        public void BclThroughHistory()
        {
            Calendar       bcl  = new PersianCalendar();
            CalendarSystem noda = CalendarSystem.GetPersianCalendar();

            for (int year = 1; year < 9378; year++)
            {
                for (int month = 1; month < 13; month++)
                {
                    Assert.AreEqual(bcl.GetDaysInMonth(year, month), noda.GetDaysInMonth(year, month),
                                    "Year: {0}; Month: {1}", year, month);
                    for (int day = 1; day < bcl.GetDaysInMonth(year, month); day++)
                    {
                        DateTime  bclDate  = new DateTime(year, month, day, bcl);
                        LocalDate nodaDate = new LocalDate(year, month, day, noda);
                        Assert.AreEqual(bclDate, nodaDate.AtMidnight().ToDateTimeUnspecified());
                        Assert.AreEqual(nodaDate, LocalDateTime.FromDateTime(bclDate).WithCalendar(noda).Date);
                        Assert.AreEqual(year, nodaDate.Year);
                        Assert.AreEqual(month, nodaDate.Month);
                        Assert.AreEqual(day, nodaDate.Day);
                    }
                }
            }
        }
        public void GetDaysInMonth()
        {
            // Just check that we've got the long/short the right way round...
            CalendarSystem calendar = CalendarSystem.GetIslamicCalendar(IslamicLeapYearPattern.HabashAlHasib, IslamicEpoch.Civil);

            Assert.AreEqual(30, calendar.GetDaysInMonth(7, 1));
            Assert.AreEqual(29, calendar.GetDaysInMonth(7, 2));
            Assert.AreEqual(30, calendar.GetDaysInMonth(7, 3));
            Assert.AreEqual(29, calendar.GetDaysInMonth(7, 4));
            Assert.AreEqual(30, calendar.GetDaysInMonth(7, 5));
            Assert.AreEqual(29, calendar.GetDaysInMonth(7, 6));
            Assert.AreEqual(30, calendar.GetDaysInMonth(7, 7));
            Assert.AreEqual(29, calendar.GetDaysInMonth(7, 8));
            Assert.AreEqual(30, calendar.GetDaysInMonth(7, 9));
            Assert.AreEqual(29, calendar.GetDaysInMonth(7, 10));
            Assert.AreEqual(30, calendar.GetDaysInMonth(7, 11));
            // As noted before, 7 isn't a leap year in this calendar
            Assert.AreEqual(29, calendar.GetDaysInMonth(7, 12));
            // As noted before, 8 is a leap year in this calendar
            Assert.AreEqual(30, calendar.GetDaysInMonth(8, 12));
        }
예제 #11
0
        public static Instant NextValid(
            this Instant instant,
            Month month     = Month.Every,
            Week week       = Week.Every,
            Day day         = Day.Every,
            WeekDay weekDay = WeekDay.Every,
            Hour hour       = Hour.Zeroth,
            Minute minute   = Minute.Zeroth,
            Second second   = Second.Zeroth,
            [CanBeNull] CalendarSystem calendarSystem = null,
            [CanBeNull] DateTimeZone timeZone         = null)
        {
            // Never case, if any are set to never, we'll never get a valid date.
            if ((month == Month.Never) ||
                (week == Week.Never) ||
                (day == Day.Never) ||
                (weekDay == WeekDay.Never) ||
                (hour == Hour.Never) ||
                (minute == Minute.Never) ||
                (second == Second.Never))
            {
                return(Instant.MaxValue);
            }

            if (calendarSystem == null)
            {
                calendarSystem = CalendarSystem.Iso;
            }
            if (timeZone == null)
            {
                timeZone = DateTimeZone.Utc;
            }
            Debug.Assert(calendarSystem != null);
            Debug.Assert(timeZone != null);

            // Move to next second.
            instant = instant.CeilingSecond();

            // Every second case.
            if ((month == Month.Every) &&
                (day == Day.Every) &&
                (weekDay == WeekDay.Every) &&
                (hour == Hour.Every) &&
                (minute == Minute.Every) &&
                (second == Second.Every) &&
                (week == Week.Every))
            {
                return(instant);
            }

            // Get days and months.
            int[] days   = Days(day).OrderBy(dy => dy).ToArray();
            int[] months = month.Months().ToArray();

            // Remove months where the first day isn't in the month.
            int firstDay = days.First();

            if (firstDay > 28)
            {
                // 2000 is a leap year, so February has 29 days.
                months = months.Where(mn => calendarSystem.GetDaysInMonth(2000, mn) >= firstDay).ToArray();
                if (months.Length < 1)
                {
                    return(Instant.MaxValue);
                }
            }

            // Get zoned date time.
            ZonedDateTime zdt = new ZonedDateTime(instant, timeZone, calendarSystem);
            int           y   = zdt.Year;
            int           m   = zdt.Month;
            int           d   = zdt.Day;
            int           h   = zdt.Hour;
            int           n   = zdt.Minute;
            int           s   = zdt.Second;

            int[] weeks = week.Weeks().ToArray();

            IsoDayOfWeek[] weekDays = weekDay.WeekDays().ToArray();
            int[]          hours    = hour.Hours().OrderBy(i => i).ToArray();
            int[]          minutes  = minute.Minutes().OrderBy(i => i).ToArray();
            int[]          seconds  = second.Seconds().ToArray();

            do
            {
                foreach (int currentMonth in months)
                {
                    if (currentMonth < m)
                    {
                        continue;
                    }
                    if (currentMonth > m)
                    {
                        d = 1;
                        h = n = s = 0;
                    }
                    m = currentMonth;
                    foreach (int currentDay in days)
                    {
                        if (currentDay < d)
                        {
                            continue;
                        }
                        if (currentDay > d)
                        {
                            h = n = s = 0;
                        }
                        d = currentDay;

                        // Check day is valid for this month.
                        if (d > calendarSystem.GetDaysInMonth(y, m))
                        {
                            break;
                        }

                        // We have a potential day, check week and week day
                        zdt = timeZone.AtLeniently(new LocalDateTime(y, m, d, h, n, s, calendarSystem));
                        if ((week != Week.Every) &&
                            (!weeks.Contains(zdt.WeekOfWeekYear)))
                        {
                            continue;
                        }
                        if ((weekDay != WeekDay.Every) &&
                            (!weekDays.Contains(zdt.IsoDayOfWeek)))
                        {
                            continue;
                        }

                        // We have a date match, check time.
                        foreach (int currentHour in hours)
                        {
                            if (currentHour < h)
                            {
                                continue;
                            }
                            if (currentHour > h)
                            {
                                n = s = 0;
                            }
                            h = currentHour;
                            foreach (int currentMinute in minutes)
                            {
                                if (currentMinute < n)
                                {
                                    continue;
                                }
                                if (currentMinute > n)
                                {
                                    s = 0;
                                }
                                n = currentMinute;
                                foreach (int currentSecond in seconds)
                                {
                                    if (currentSecond < s)
                                    {
                                        continue;
                                    }
                                    return
                                        (timeZone.AtLeniently(
                                             new LocalDateTime(y, m, d, h, n, currentSecond, calendarSystem)).ToInstant());
                                }
                                n = s = 0;
                            }
                            h = n = s = 0;
                        }
                        d = 1;
                    }
                    d = 1;
                    h = n = s = 0;
                }
                y++;

                // Don't bother checking max year.
                if (y >= calendarSystem.MaxYear)
                {
                    return(Instant.MaxValue);
                }

                // Start next year
                m = d = 1;
                h = n = s = 0;
            } while (true);
        }