/// <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)); }
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); }
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()); }
/// <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(); } } } }
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)); }
[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)); }
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); }