{"version":3,"sources":["../src/internal/date.ts"],"names":[],"mappings":"AA2CA,QAAA,MAAM,eAAe,KAAK,CAAC","file":"date.d.ts","sourcesContent":["/*!\r\n   Copyright 2019 Ron Buckton\r\n\r\n   Licensed under the Apache License, Version 2.0 (the \"License\");\r\n   you may not use this file except in compliance with the License.\r\n   You may obtain a copy of the License at\r\n\r\n       http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n   Unless required by applicable law or agreed to in writing, software\r\n   distributed under the License is distributed on an \"AS IS\" BASIS,\r\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n   See the License for the specific language governing permissions and\r\n   limitations under the License.\r\n*/\r\nimport { EPOCH_DAYS } from './types';\r\n\r\n// Common utilities\r\n\r\nfunction leastUpperBound(array: ReadonlyArray<number>, value: number) {\r\n    let l = 0, h = array.length - 1;\r\n    while (l <= h) {\r\n        let m = l + ((h - l) >> 1);\r\n        let mv = array[m];\r\n        let r = mv - value;\r\n        if (r < 0) {\r\n            l = m + 1;\r\n        }\r\n        else if (r > 0) {\r\n            h = m - 1;\r\n        }\r\n        else {\r\n            return m;\r\n        }\r\n    }\r\n    return l;\r\n}\r\n\r\n\r\n// Date utilities\r\n\r\nconst DAY_OFFSETS_STANDARD: ReadonlyArray<number> = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];\r\nconst DAY_OFFSETS_LEAP_YEAR: ReadonlyArray<number> = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366];\r\nconst MONTHS_PER_YEAR = 12;\r\nconst DAYS_PER_1_YEAR = 365;\r\nconst DAYS_PER_4_YEARS = 1461;\r\nconst DAYS_PER_100_YEARS = 36524;\r\nconst DAYS_PER_400_YEARS = 146097;\r\nconst DAYS_PER_WEEK = 7;\r\nconst EPOCH_DAY_OFFSET = 719162; // days between the EPOCH and 0\r\nconst INITIAL_WEEK_DAY = 4; // January 1st, 1970 was a Thursday\r\n\r\n/* @internal */ export { MONTHS_PER_YEAR }\r\n\r\n// https://tc39.github.io/ecma262/#sec-makeday\r\n/* @internal */ export function getDate(year: number, month: number, day: number) {\r\n    // normalize inputs\r\n    while (month < 1) year--, month += MONTHS_PER_YEAR;\r\n    while (month > MONTHS_PER_YEAR) year++, month -= MONTHS_PER_YEAR;\r\n\r\n    const dayOffsets = isLeapYear(year) ? DAY_OFFSETS_LEAP_YEAR : DAY_OFFSETS_STANDARD;\r\n    // https://tc39.github.io/ecma262/#eqn-DaysFromYear\r\n    const date = (year - 1970) * 365 + Math.floor((year - 1969) / 4) - Math.floor((year - 1901) / 100) + Math.floor((year - 1601) / 400) + dayOffsets[month - 1] + day - 1;\r\n    return date as EPOCH_DAYS;\r\n}\r\n\r\n/* @internal */ export function isLeapYear(year: number) {\r\n    return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);\r\n}\r\n\r\n/* @internal */ export function getDaysInMonth(year: number, month: number) {\r\n    // normalize inputs\r\n    while (month < 1) year-- , month += MONTHS_PER_YEAR;\r\n    while (month > MONTHS_PER_YEAR) year++ , month -= MONTHS_PER_YEAR;\r\n    const dayOffsets = isLeapYear(year) ? DAY_OFFSETS_LEAP_YEAR : DAY_OFFSETS_STANDARD;\r\n    return dayOffsets[month] - dayOffsets[month - 1];\r\n}\r\n\r\n/* @internal */ export function getDaysInYear(year: number) {\r\n    return isLeapYear(year) ? DAY_OFFSETS_LEAP_YEAR[MONTHS_PER_YEAR] : DAY_OFFSETS_STANDARD[MONTHS_PER_YEAR];\r\n}\r\n\r\n/* @internal */ export function getWeeksInYear(year: number) {\r\n    const yearM1 = year - 1;\r\n    if ((year + Math.floor(year / 4) - Math.floor(year / 100) + Math.floor(year / 400)) % DAYS_PER_WEEK === 4 ||\r\n        (yearM1 + Math.floor(yearM1 / 4) - Math.floor(yearM1 / 100) + Math.floor(yearM1 / 400)) % DAYS_PER_WEEK === 3) {\r\n        return 53;\r\n    }\r\n    return 52;\r\n}\r\n\r\n/* @internal */ export interface DateParts {\r\n    year: number;\r\n    month: number;\r\n    day: number;\r\n    dayOfYear: number;\r\n    dayOfWeek: number;\r\n    weekOfYear: number;\r\n}\r\n\r\n/* @internal */ export const enum DatePart {\r\n    year,\r\n    dayOfYear,\r\n    month,\r\n    day,\r\n    dayOfWeek,\r\n    weekOfYear,\r\n    all\r\n}\r\n\r\n/* @internal */ export function getDatePart<P extends DatePart>(date: EPOCH_DAYS, part: P): P extends DatePart.all ? DateParts : number;\r\n/* @internal */ export function getDatePart(date: EPOCH_DAYS, part: DatePart) {\r\n    const dayOfWeek = part === DatePart.dayOfWeek || part === DatePart.weekOfYear || part === DatePart.all \r\n        ? ((date + INITIAL_WEEK_DAY) % DAYS_PER_WEEK) || DAYS_PER_WEEK\r\n        : 0;\r\n    if (part === DatePart.dayOfWeek) return dayOfWeek;\r\n    let days = date + EPOCH_DAY_OFFSET;\r\n    const years400 = Math.floor(days / DAYS_PER_400_YEARS);\r\n    days -= years400 * DAYS_PER_400_YEARS;\r\n    let years100 = Math.floor(days / DAYS_PER_100_YEARS);\r\n    if (years100 === 4) years100--;\r\n    days -= years100 * DAYS_PER_100_YEARS;\r\n    const years4 = Math.floor(days / DAYS_PER_4_YEARS);\r\n    days -= years4 * DAYS_PER_4_YEARS;\r\n    let years1 = Math.floor(days / DAYS_PER_1_YEAR);\r\n    if (years1 === 4) years1--;\r\n    const year = years400 * 400 + years100 * 100 + years4 * 4 + years1 + 1;\r\n    if (part === DatePart.year) return year;\r\n    const dayOfYear = days - years1 * DAYS_PER_1_YEAR + 1;\r\n    if (part === DatePart.dayOfYear) return dayOfYear;\r\n    const weekOfYear = part === DatePart.weekOfYear || part === DatePart.all\r\n        ? Math.floor((dayOfYear - dayOfWeek + 10) / DAYS_PER_WEEK)\r\n        : 0;\r\n    if (part === DatePart.weekOfYear) return weekOfYear;\r\n    const dayOffsets = isLeapYear(year) ? DAY_OFFSETS_LEAP_YEAR : DAY_OFFSETS_STANDARD;\r\n    const month = leastUpperBound(dayOffsets, dayOfYear);\r\n    if (part === DatePart.month) return month;\r\n    const day = dayOfYear - dayOffsets[month - 1];\r\n    if (part === DatePart.day) return day;\r\n    return { year, month, day, dayOfYear, dayOfWeek, weekOfYear };\r\n}\r\n\r\nfunction getDayOfYearFromWeekDate(year: number, weekOfYear: number, dayOfWeek: number) {\r\n    // The first week of the year is always the week that contains January 4th.\r\n    // https://en.wikipedia.org/wiki/ISO_week_date#First_week\r\n    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year,_week_number_and_weekday\r\n    return weekOfYear * DAYS_PER_WEEK + dayOfWeek - (getDatePart(getDate(year, 1, 4), DatePart.dayOfWeek) + 3);\r\n}\r\n\r\n/* @internal */ export function getCalendarDateFromWeekDate(year: number, weekOfYear: number, dayOfWeek: number) {\r\n    // normalize inputs\r\n    if (dayOfWeek < 1 || dayOfWeek > DAYS_PER_WEEK) throw new RangeError();\r\n    while (weekOfYear < 1) year--, weekOfYear += getWeeksInYear(year);\r\n    while (weekOfYear > getWeeksInYear(year)) weekOfYear -= getWeeksInYear(year), year++;\r\n\r\n    return getCalendarDateFromOrdinalDate(year, getDayOfYearFromWeekDate(year, weekOfYear, dayOfWeek));\r\n}\r\n\r\n/* @internal */ export function getCalendarDateFromOrdinalDate(year: number, dayOfYear: number) {\r\n    // normalize inputs\r\n    while (dayOfYear < 1) year--, dayOfYear += getDaysInYear(year);\r\n    while (dayOfYear > getDaysInYear(year)) dayOfYear -= getDaysInYear(year), year++;\r\n    const dayOffsets = isLeapYear(year) ? DAY_OFFSETS_LEAP_YEAR : DAY_OFFSETS_STANDARD;\r\n    const month = leastUpperBound(dayOffsets, dayOfYear)\r\n    const day = dayOfYear - dayOffsets[month - 1];\r\n    return { year, month, day };\r\n}\r\n"],"sourceRoot":".."}