ISODate.cpp (1878B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "mozilla/Assertions.h" 6 #include "mozilla/intl/calendar/ISODate.h" 7 8 #include <array> 9 #include <stdint.h> 10 11 namespace mozilla::intl::calendar { 12 13 // Copied from js/src/builtin/temporal/Calendar.cpp 14 15 static int32_t DayFromYear(int32_t year) { 16 return 365 * (year - 1970) + FloorDiv(year - 1969, 4) - 17 FloorDiv(year - 1901, 100) + FloorDiv(year - 1601, 400); 18 } 19 20 static constexpr bool IsISOLeapYear(int32_t year) { 21 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)); 22 } 23 24 static constexpr int32_t ISODaysInMonth(int32_t year, int32_t month) { 25 MOZ_ASSERT(1 <= month && month <= 12); 26 27 constexpr uint8_t daysInMonth[2][13] = { 28 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 29 {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; 30 31 return daysInMonth[IsISOLeapYear(year)][month]; 32 } 33 34 static constexpr auto FirstDayOfMonth(int32_t year) { 35 // The following array contains the day of year for the first day of each 36 // month, where index 0 is January, and day 0 is January 1. 37 std::array<int32_t, 13> days = {}; 38 for (int32_t month = 1; month <= 12; ++month) { 39 days[month] = days[month - 1] + ISODaysInMonth(year, month); 40 } 41 return days; 42 } 43 44 static int32_t ISODayOfYear(const ISODate& isoDate) { 45 const auto& [year, month, day] = isoDate; 46 47 // First day of month arrays for non-leap and leap years. 48 constexpr decltype(FirstDayOfMonth(0)) firstDayOfMonth[2] = { 49 FirstDayOfMonth(1), FirstDayOfMonth(0)}; 50 51 return firstDayOfMonth[IsISOLeapYear(year)][month - 1] + day; 52 } 53 54 int32_t MakeDay(const ISODate& date) { 55 return DayFromYear(date.year) + ISODayOfYear(date) - 1; 56 } 57 58 } // namespace mozilla::intl::calendar