feat: Phase 1 — extract the client (web SPA + desktop) to dtoro/oikos-web
Problem: the hexagonal refactor churns the backend tree for nine more phases; the UI delivery stack (web/ SPA, cmd/desktop Wails wrapper, compose/web image) must move to its own repo first so doc/layout rewrites land once on a backend-only tree. Change: - New repo git.hubris.network/dtoro/oikos-web (v0.33.0): web/, desktop/ (updateURL repointed to oikos-web releases), compose/, own CI (web + desktop jobs), own deploy script (CI-green gate, TOCTOU guard, version-tagged images, prune-to-3), own webhook receiver on :9798 + launchd unit, own compose project publishing the same 8091:80. - Cutover executed on mac-mini in order: oikos stack's web service stopped+removed, oikos-web project brought up on 8091; outer Caddy untouched (targets the published port) — serving + Authentik flow + /wails 404 quirk verified post-cutover. - Stripped from oikos: web/, cmd/desktop/, compose/web/, desktop CI workflow, ci.yml web job, Makefile ui/desktop/desktop-package/install targets, the compose web service, oikos-web from deploy.sh's fallback prune list; wails + go-keyring dropped from go.mod, vendor synced. - README / CONTRIBUTING / AGENTS.md / .agents dev+operations docs now point at the new repo; mbse + mascot design docs carry a path note. Risk: production SPA serving depends on the new pipeline now; rollback is versioned-image re-up of the old web service from a pre-split checkout (port 8091). Desktop builds installed before the split still check dtoro/oikos releases — one manual reinstall, noted in the oikos-web release notes. Verification: go vet, make test (race), make generate-check, golangci (no new findings; baseline down 400→365); post-cutover curls — localhost:8091 200, /wails/runtime.js 404, outer Caddy 302 Authentik.
This commit is contained in:
59
web/node_modules/@internationalized/date/src/calendars/BuddhistCalendar.ts
generated
vendored
Normal file
59
web/node_modules/@internationalized/date/src/calendars/BuddhistCalendar.ts
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2020 Adobe. All rights reserved.
|
||||
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
* OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// Portions of the code in this file are based on code from ICU.
|
||||
// Original licensing can be found in the NOTICE file in the root directory of this source tree.
|
||||
|
||||
import {AnyCalendarDate, CalendarIdentifier} from '../types';
|
||||
import {CalendarDate} from '../CalendarDate';
|
||||
import {fromExtendedYear, getExtendedYear, GregorianCalendar} from './GregorianCalendar';
|
||||
|
||||
const BUDDHIST_ERA_START = -543;
|
||||
|
||||
/**
|
||||
* The Buddhist calendar is the same as the Gregorian calendar, but counts years
|
||||
* starting from the birth of Buddha in 543 BC (Gregorian). It supports only one
|
||||
* era, identified as 'BE'.
|
||||
*/
|
||||
export class BuddhistCalendar extends GregorianCalendar {
|
||||
identifier: CalendarIdentifier = 'buddhist';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let gregorianDate = super.fromJulianDay(jd);
|
||||
let year = getExtendedYear(gregorianDate.era, gregorianDate.year);
|
||||
return new CalendarDate(
|
||||
this,
|
||||
year - BUDDHIST_ERA_START,
|
||||
gregorianDate.month,
|
||||
gregorianDate.day
|
||||
);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
return super.toJulianDay(toGregorian(date));
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['BE'];
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
return super.getDaysInMonth(toGregorian(date));
|
||||
}
|
||||
|
||||
balanceDate(): void {}
|
||||
}
|
||||
|
||||
function toGregorian(date: AnyCalendarDate) {
|
||||
let [era, year] = fromExtendedYear(date.year + BUDDHIST_ERA_START);
|
||||
return new CalendarDate(era, year, date.month, date.day);
|
||||
}
|
||||
205
web/node_modules/@internationalized/date/src/calendars/EthiopicCalendar.ts
generated
vendored
Normal file
205
web/node_modules/@internationalized/date/src/calendars/EthiopicCalendar.ts
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2020 Adobe. All rights reserved.
|
||||
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
* OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// Portions of the code in this file are based on code from ICU.
|
||||
// Original licensing can be found in the NOTICE file in the root directory of this source tree.
|
||||
|
||||
import {AnyCalendarDate, Calendar, CalendarIdentifier} from '../types';
|
||||
import {CalendarDate} from '../CalendarDate';
|
||||
import {Mutable} from '../utils';
|
||||
|
||||
const ETHIOPIC_EPOCH = 1723856;
|
||||
const COPTIC_EPOCH = 1824665;
|
||||
|
||||
// The delta between Amete Alem 1 and Amete Mihret 1
|
||||
// AA 5501 = AM 1
|
||||
const AMETE_MIHRET_DELTA = 5500;
|
||||
|
||||
function ceToJulianDay(epoch: number, year: number, month: number, day: number): number {
|
||||
return (
|
||||
epoch + // difference from Julian epoch to 1,1,1
|
||||
365 * year + // number of days from years
|
||||
Math.floor(year / 4) + // extra day of leap year
|
||||
30 * (month - 1) + // number of days from months (1 based)
|
||||
day -
|
||||
1 // number of days for present month (1 based)
|
||||
);
|
||||
}
|
||||
|
||||
function julianDayToCE(epoch: number, jd: number) {
|
||||
let year = Math.floor((4 * (jd - epoch)) / 1461);
|
||||
let month = 1 + Math.floor((jd - ceToJulianDay(epoch, year, 1, 1)) / 30);
|
||||
let day = jd + 1 - ceToJulianDay(epoch, year, month, 1);
|
||||
return [year, month, day];
|
||||
}
|
||||
|
||||
function getLeapDay(year: number) {
|
||||
return Math.floor((year % 4) / 3);
|
||||
}
|
||||
|
||||
function getDaysInMonth(year: number, month: number) {
|
||||
// The Ethiopian and Coptic calendars have 13 months, 12 of 30 days each and
|
||||
// an intercalary month at the end of the year of 5 or 6 days, depending whether
|
||||
// the year is a leap year or not. The Leap Year follows the same rules as the
|
||||
// Julian Calendar so that the extra month always has six days in the year before
|
||||
// a Julian Leap Year.
|
||||
if (month % 13 !== 0) {
|
||||
// not intercalary month
|
||||
return 30;
|
||||
} else {
|
||||
// intercalary month 5 days + possible leap day
|
||||
return getLeapDay(year) + 5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Ethiopic calendar system is the official calendar used in Ethiopia.
|
||||
* It includes 12 months of 30 days each, plus 5 or 6 intercalary days depending
|
||||
* on whether it is a leap year. Two eras are supported: 'AA' and 'AM'.
|
||||
*/
|
||||
export class EthiopicCalendar implements Calendar {
|
||||
identifier: CalendarIdentifier = 'ethiopic';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let [year, month, day] = julianDayToCE(ETHIOPIC_EPOCH, jd);
|
||||
let era = 'AM';
|
||||
if (year <= 0) {
|
||||
era = 'AA';
|
||||
year += AMETE_MIHRET_DELTA;
|
||||
}
|
||||
|
||||
return new CalendarDate(this, era, year, month, day);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
let year = date.year;
|
||||
if (date.era === 'AA') {
|
||||
year -= AMETE_MIHRET_DELTA;
|
||||
}
|
||||
|
||||
return ceToJulianDay(ETHIOPIC_EPOCH, year, date.month, date.day);
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
return getDaysInMonth(date.year, date.month);
|
||||
}
|
||||
|
||||
getMonthsInYear(): number {
|
||||
return 13;
|
||||
}
|
||||
|
||||
getDaysInYear(date: AnyCalendarDate): number {
|
||||
return 365 + getLeapDay(date.year);
|
||||
}
|
||||
|
||||
getMaximumMonthsInYear(): number {
|
||||
return 13;
|
||||
}
|
||||
|
||||
getMaximumDaysInMonth(): number {
|
||||
return 30;
|
||||
}
|
||||
|
||||
getYearsInEra(date: AnyCalendarDate): number {
|
||||
// 9999-12-31 gregorian is 9992-20-02 ethiopic.
|
||||
// Round down to 9991 for the last full year.
|
||||
// AA 9999-01-01 ethiopic is 4506-09-30 gregorian.
|
||||
return date.era === 'AA' ? 9999 : 9991;
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['AA', 'AM'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Ethiopic (Amete Alem) calendar is the same as the modern Ethiopic calendar,
|
||||
* except years were measured from a different epoch. Only one era is supported: 'AA'.
|
||||
*/
|
||||
export class EthiopicAmeteAlemCalendar extends EthiopicCalendar {
|
||||
identifier: CalendarIdentifier = 'ethioaa'; // also known as 'ethiopic-amete-alem' in ICU
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let [year, month, day] = julianDayToCE(ETHIOPIC_EPOCH, jd);
|
||||
year += AMETE_MIHRET_DELTA;
|
||||
return new CalendarDate(this, 'AA', year, month, day);
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['AA'];
|
||||
}
|
||||
|
||||
getYearsInEra(): number {
|
||||
// 9999-13-04 ethioaa is the maximum date, which is equivalent to 4506-09-29 gregorian.
|
||||
return 9999;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Coptic calendar is similar to the Ethiopic calendar.
|
||||
* It includes 12 months of 30 days each, plus 5 or 6 intercalary days depending
|
||||
* on whether it is a leap year. Two eras are supported: 'BCE' and 'CE'.
|
||||
*/
|
||||
export class CopticCalendar extends EthiopicCalendar {
|
||||
identifier: CalendarIdentifier = 'coptic';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let [year, month, day] = julianDayToCE(COPTIC_EPOCH, jd);
|
||||
let era = 'CE';
|
||||
if (year <= 0) {
|
||||
era = 'BCE';
|
||||
year = 1 - year;
|
||||
}
|
||||
|
||||
return new CalendarDate(this, era, year, month, day);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
let year = date.year;
|
||||
if (date.era === 'BCE') {
|
||||
year = 1 - year;
|
||||
}
|
||||
|
||||
return ceToJulianDay(COPTIC_EPOCH, year, date.month, date.day);
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
let year = date.year;
|
||||
if (date.era === 'BCE') {
|
||||
year = 1 - year;
|
||||
}
|
||||
|
||||
return getDaysInMonth(year, date.month);
|
||||
}
|
||||
|
||||
isInverseEra(date: AnyCalendarDate): boolean {
|
||||
return date.era === 'BCE';
|
||||
}
|
||||
|
||||
balanceDate(date: Mutable<AnyCalendarDate>): void {
|
||||
if (date.year <= 0) {
|
||||
date.era = date.era === 'BCE' ? 'CE' : 'BCE';
|
||||
date.year = 1 - date.year;
|
||||
}
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['BCE', 'CE'];
|
||||
}
|
||||
|
||||
getYearsInEra(date: AnyCalendarDate): number {
|
||||
// 9999-12-30 gregorian is 9716-02-20 coptic.
|
||||
// Round down to 9715 for the last full year.
|
||||
// BCE 9999-01-01 coptic is BC 9716-06-15 gregorian.
|
||||
return date.era === 'BCE' ? 9999 : 9715;
|
||||
}
|
||||
}
|
||||
150
web/node_modules/@internationalized/date/src/calendars/GregorianCalendar.ts
generated
vendored
Normal file
150
web/node_modules/@internationalized/date/src/calendars/GregorianCalendar.ts
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2020 Adobe. All rights reserved.
|
||||
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
* OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// Portions of the code in this file are based on code from ICU.
|
||||
// Original licensing can be found in the NOTICE file in the root directory of this source tree.
|
||||
|
||||
import {AnyCalendarDate, Calendar, CalendarIdentifier} from '../types';
|
||||
import {CalendarDate} from '../CalendarDate';
|
||||
import {mod, Mutable} from '../utils';
|
||||
|
||||
const EPOCH = 1721426; // 001/01/03 Julian C.E.
|
||||
export function gregorianToJulianDay(
|
||||
era: string,
|
||||
year: number,
|
||||
month: number,
|
||||
day: number
|
||||
): number {
|
||||
year = getExtendedYear(era, year);
|
||||
|
||||
let y1 = year - 1;
|
||||
let monthOffset = -2;
|
||||
if (month <= 2) {
|
||||
monthOffset = 0;
|
||||
} else if (isLeapYear(year)) {
|
||||
monthOffset = -1;
|
||||
}
|
||||
|
||||
return (
|
||||
EPOCH -
|
||||
1 +
|
||||
365 * y1 +
|
||||
Math.floor(y1 / 4) -
|
||||
Math.floor(y1 / 100) +
|
||||
Math.floor(y1 / 400) +
|
||||
Math.floor((367 * month - 362) / 12 + monthOffset + day)
|
||||
);
|
||||
}
|
||||
|
||||
export function isLeapYear(year: number): boolean {
|
||||
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
||||
}
|
||||
|
||||
export function getExtendedYear(era: string, year: number): number {
|
||||
return era === 'BC' ? 1 - year : year;
|
||||
}
|
||||
|
||||
export function fromExtendedYear(year: number): [string, number] {
|
||||
let era = 'AD';
|
||||
if (year <= 0) {
|
||||
era = 'BC';
|
||||
year = 1 - year;
|
||||
}
|
||||
|
||||
return [era, year];
|
||||
}
|
||||
|
||||
const daysInMonth = {
|
||||
standard: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
|
||||
leapyear: [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||
};
|
||||
|
||||
/**
|
||||
* The Gregorian calendar is the most commonly used calendar system in the world. It supports two
|
||||
* eras: BC, and AD. Years always contain 12 months, and 365 or 366 days depending on whether it is
|
||||
* a leap year.
|
||||
*/
|
||||
export class GregorianCalendar implements Calendar {
|
||||
identifier: CalendarIdentifier = 'gregory';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let jd0 = jd;
|
||||
let depoch = jd0 - EPOCH;
|
||||
let quadricent = Math.floor(depoch / 146097);
|
||||
let dqc = mod(depoch, 146097);
|
||||
let cent = Math.floor(dqc / 36524);
|
||||
let dcent = mod(dqc, 36524);
|
||||
let quad = Math.floor(dcent / 1461);
|
||||
let dquad = mod(dcent, 1461);
|
||||
let yindex = Math.floor(dquad / 365);
|
||||
|
||||
let extendedYear =
|
||||
quadricent * 400 + cent * 100 + quad * 4 + yindex + (cent !== 4 && yindex !== 4 ? 1 : 0);
|
||||
let [era, year] = fromExtendedYear(extendedYear);
|
||||
let yearDay = jd0 - gregorianToJulianDay(era, year, 1, 1);
|
||||
let leapAdj = 2;
|
||||
if (jd0 < gregorianToJulianDay(era, year, 3, 1)) {
|
||||
leapAdj = 0;
|
||||
} else if (isLeapYear(year)) {
|
||||
leapAdj = 1;
|
||||
}
|
||||
let month = Math.floor(((yearDay + leapAdj) * 12 + 373) / 367);
|
||||
let day = jd0 - gregorianToJulianDay(era, year, month, 1) + 1;
|
||||
|
||||
return new CalendarDate(era, year, month, day);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
return gregorianToJulianDay(date.era, date.year, date.month, date.day);
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
return daysInMonth[isLeapYear(date.year) ? 'leapyear' : 'standard'][date.month - 1];
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
getMonthsInYear(date: AnyCalendarDate): number {
|
||||
return 12;
|
||||
}
|
||||
|
||||
getDaysInYear(date: AnyCalendarDate): number {
|
||||
return isLeapYear(date.year) ? 366 : 365;
|
||||
}
|
||||
|
||||
getMaximumMonthsInYear(): number {
|
||||
return 12;
|
||||
}
|
||||
|
||||
getMaximumDaysInMonth(): number {
|
||||
return 31;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
getYearsInEra(date: AnyCalendarDate): number {
|
||||
return 9999;
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['BC', 'AD'];
|
||||
}
|
||||
|
||||
isInverseEra(date: AnyCalendarDate): boolean {
|
||||
return date.era === 'BC';
|
||||
}
|
||||
|
||||
balanceDate(date: Mutable<AnyCalendarDate>): void {
|
||||
if (date.year <= 0) {
|
||||
date.era = date.era === 'BC' ? 'AD' : 'BC';
|
||||
date.year = 1 - date.year;
|
||||
}
|
||||
}
|
||||
}
|
||||
214
web/node_modules/@internationalized/date/src/calendars/HebrewCalendar.ts
generated
vendored
Normal file
214
web/node_modules/@internationalized/date/src/calendars/HebrewCalendar.ts
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright 2020 Adobe. All rights reserved.
|
||||
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
* OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// Portions of the code in this file are based on code from ICU.
|
||||
// Original licensing can be found in the NOTICE file in the root directory of this source tree.
|
||||
|
||||
import {AnyCalendarDate, Calendar, CalendarIdentifier} from '../types';
|
||||
import {CalendarDate} from '../CalendarDate';
|
||||
import {mod, Mutable} from '../utils';
|
||||
|
||||
const HEBREW_EPOCH = 347997;
|
||||
|
||||
// Hebrew date calculations are performed in terms of days, hours, and
|
||||
// "parts" (or halakim), which are 1/1080 of an hour, or 3 1/3 seconds.
|
||||
const HOUR_PARTS = 1080;
|
||||
const DAY_PARTS = 24 * HOUR_PARTS;
|
||||
|
||||
// An approximate value for the length of a lunar month.
|
||||
// It is used to calculate the approximate year and month of a given
|
||||
// absolute date.
|
||||
const MONTH_DAYS = 29;
|
||||
const MONTH_FRACT = 12 * HOUR_PARTS + 793;
|
||||
const MONTH_PARTS = MONTH_DAYS * DAY_PARTS + MONTH_FRACT;
|
||||
|
||||
function isLeapYear(year: number) {
|
||||
return mod(year * 7 + 1, 19) < 7;
|
||||
}
|
||||
|
||||
// Test for delay of start of new year and to avoid
|
||||
// Sunday, Wednesday, and Friday as start of the new year.
|
||||
function hebrewDelay1(year: number) {
|
||||
let months = Math.floor((235 * year - 234) / 19);
|
||||
let parts = 12084 + 13753 * months;
|
||||
let day = months * 29 + Math.floor(parts / 25920);
|
||||
|
||||
if (mod(3 * (day + 1), 7) < 3) {
|
||||
day += 1;
|
||||
}
|
||||
|
||||
return day;
|
||||
}
|
||||
|
||||
// Check for delay in start of new year due to length of adjacent years
|
||||
function hebrewDelay2(year: number) {
|
||||
let last = hebrewDelay1(year - 1);
|
||||
let present = hebrewDelay1(year);
|
||||
let next = hebrewDelay1(year + 1);
|
||||
|
||||
if (next - present === 356) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (present - last === 382) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function startOfYear(year: number) {
|
||||
return hebrewDelay1(year) + hebrewDelay2(year);
|
||||
}
|
||||
|
||||
function getDaysInYear(year: number) {
|
||||
return startOfYear(year + 1) - startOfYear(year);
|
||||
}
|
||||
|
||||
function getYearType(year: number) {
|
||||
let yearLength = getDaysInYear(year);
|
||||
|
||||
if (yearLength > 380) {
|
||||
yearLength -= 30; // Subtract length of leap month.
|
||||
}
|
||||
|
||||
switch (yearLength) {
|
||||
case 353:
|
||||
return 0; // deficient
|
||||
case 354:
|
||||
return 1; // normal
|
||||
case 355:
|
||||
return 2; // complete
|
||||
}
|
||||
}
|
||||
|
||||
function getDaysInMonth(year: number, month: number): number {
|
||||
// Normalize month numbers from 1 - 13, even on non-leap years
|
||||
if (month >= 6 && !isLeapYear(year)) {
|
||||
month++;
|
||||
}
|
||||
|
||||
// First of all, dispose of fixed-length 29 day months
|
||||
if (month === 4 || month === 7 || month === 9 || month === 11 || month === 13) {
|
||||
return 29;
|
||||
}
|
||||
|
||||
let yearType = getYearType(year);
|
||||
|
||||
// If it's Heshvan, days depend on length of year
|
||||
if (month === 2) {
|
||||
return yearType === 2 ? 30 : 29;
|
||||
}
|
||||
|
||||
// Similarly, Kislev varies with the length of year
|
||||
if (month === 3) {
|
||||
return yearType === 0 ? 29 : 30;
|
||||
}
|
||||
|
||||
// Adar I only exists in leap years
|
||||
if (month === 6) {
|
||||
return isLeapYear(year) ? 30 : 0;
|
||||
}
|
||||
|
||||
return 30;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Hebrew calendar is used in Israel and around the world by the Jewish faith.
|
||||
* Years include either 12 or 13 months depending on whether it is a leap year.
|
||||
* In leap years, an extra month is inserted at month 6.
|
||||
*/
|
||||
export class HebrewCalendar implements Calendar {
|
||||
identifier: CalendarIdentifier = 'hebrew';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let d = jd - HEBREW_EPOCH;
|
||||
let m = (d * DAY_PARTS) / MONTH_PARTS; // Months (approx)
|
||||
let year = Math.floor((19 * m + 234) / 235) + 1; // Years (approx)
|
||||
let ys = startOfYear(year); // 1st day of year
|
||||
let dayOfYear = Math.floor(d - ys);
|
||||
|
||||
// Because of the postponement rules, it's possible to guess wrong. Fix it.
|
||||
while (dayOfYear < 1) {
|
||||
year--;
|
||||
ys = startOfYear(year);
|
||||
dayOfYear = Math.floor(d - ys);
|
||||
}
|
||||
|
||||
// Now figure out which month we're in, and the date within that month
|
||||
let month = 1;
|
||||
let monthStart = 0;
|
||||
while (monthStart < dayOfYear) {
|
||||
monthStart += getDaysInMonth(year, month);
|
||||
month++;
|
||||
}
|
||||
|
||||
month--;
|
||||
monthStart -= getDaysInMonth(year, month);
|
||||
|
||||
let day = dayOfYear - monthStart;
|
||||
return new CalendarDate(this, year, month, day);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
let jd = startOfYear(date.year);
|
||||
for (let month = 1; month < date.month; month++) {
|
||||
jd += getDaysInMonth(date.year, month);
|
||||
}
|
||||
|
||||
return jd + date.day + HEBREW_EPOCH;
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
return getDaysInMonth(date.year, date.month);
|
||||
}
|
||||
|
||||
getMonthsInYear(date: AnyCalendarDate): number {
|
||||
return isLeapYear(date.year) ? 13 : 12;
|
||||
}
|
||||
|
||||
getDaysInYear(date: AnyCalendarDate): number {
|
||||
return getDaysInYear(date.year);
|
||||
}
|
||||
|
||||
getMaximumMonthsInYear(): number {
|
||||
return 13;
|
||||
}
|
||||
|
||||
getMaximumDaysInMonth(): number {
|
||||
return 30;
|
||||
}
|
||||
|
||||
getYearsInEra(): number {
|
||||
// 6239 gregorian
|
||||
return 9999;
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['AM'];
|
||||
}
|
||||
|
||||
balanceYearMonth(date: Mutable<AnyCalendarDate>, previousDate: AnyCalendarDate): void {
|
||||
// Keep date in the same month when switching between leap years and non leap years
|
||||
if (previousDate.year !== date.year) {
|
||||
if (isLeapYear(previousDate.year) && !isLeapYear(date.year) && previousDate.month > 6) {
|
||||
date.month--;
|
||||
} else if (
|
||||
!isLeapYear(previousDate.year) &&
|
||||
isLeapYear(date.year) &&
|
||||
previousDate.month > 6
|
||||
) {
|
||||
date.month++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
134
web/node_modules/@internationalized/date/src/calendars/IndianCalendar.ts
generated
vendored
Normal file
134
web/node_modules/@internationalized/date/src/calendars/IndianCalendar.ts
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2020 Adobe. All rights reserved.
|
||||
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
* OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// Portions of the code in this file are based on code from ICU.
|
||||
// Original licensing can be found in the NOTICE file in the root directory of this source tree.
|
||||
|
||||
import {AnyCalendarDate, CalendarIdentifier} from '../types';
|
||||
import {CalendarDate} from '../CalendarDate';
|
||||
import {
|
||||
fromExtendedYear,
|
||||
GregorianCalendar,
|
||||
gregorianToJulianDay,
|
||||
isLeapYear
|
||||
} from './GregorianCalendar';
|
||||
|
||||
// Starts in 78 AD,
|
||||
const INDIAN_ERA_START = 78;
|
||||
|
||||
// The Indian year starts 80 days later than the Gregorian year.
|
||||
const INDIAN_YEAR_START = 80;
|
||||
|
||||
/**
|
||||
* The Indian National Calendar is similar to the Gregorian calendar, but with
|
||||
* years numbered since the Saka era in 78 AD (Gregorian). There are 12 months
|
||||
* in each year, with either 30 or 31 days. Only one era identifier is supported: 'saka'.
|
||||
*/
|
||||
export class IndianCalendar extends GregorianCalendar {
|
||||
identifier: CalendarIdentifier = 'indian';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
// Gregorian date for Julian day
|
||||
let date = super.fromJulianDay(jd);
|
||||
|
||||
// Year in Saka era
|
||||
let indianYear = date.year - INDIAN_ERA_START;
|
||||
|
||||
// Day number in Gregorian year (starting from 0)
|
||||
let yDay = jd - gregorianToJulianDay(date.era, date.year, 1, 1);
|
||||
|
||||
let leapMonth: number;
|
||||
if (yDay < INDIAN_YEAR_START) {
|
||||
// Day is at the end of the preceding Saka year
|
||||
indianYear--;
|
||||
|
||||
// Days in leapMonth this year, previous Gregorian year
|
||||
leapMonth = isLeapYear(date.year - 1) ? 31 : 30;
|
||||
yDay += leapMonth + 31 * 5 + 30 * 3 + 10;
|
||||
} else {
|
||||
// Days in leapMonth this year
|
||||
leapMonth = isLeapYear(date.year) ? 31 : 30;
|
||||
yDay -= INDIAN_YEAR_START;
|
||||
}
|
||||
|
||||
let indianMonth: number;
|
||||
let indianDay: number;
|
||||
if (yDay < leapMonth) {
|
||||
indianMonth = 1;
|
||||
indianDay = yDay + 1;
|
||||
} else {
|
||||
let mDay = yDay - leapMonth;
|
||||
if (mDay < 31 * 5) {
|
||||
indianMonth = Math.floor(mDay / 31) + 2;
|
||||
indianDay = (mDay % 31) + 1;
|
||||
} else {
|
||||
mDay -= 31 * 5;
|
||||
indianMonth = Math.floor(mDay / 30) + 7;
|
||||
indianDay = (mDay % 30) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return new CalendarDate(this, indianYear, indianMonth, indianDay);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
let extendedYear = date.year + INDIAN_ERA_START;
|
||||
let [era, year] = fromExtendedYear(extendedYear);
|
||||
|
||||
let leapMonth: number;
|
||||
let jd: number;
|
||||
if (isLeapYear(year)) {
|
||||
leapMonth = 31;
|
||||
jd = gregorianToJulianDay(era, year, 3, 21);
|
||||
} else {
|
||||
leapMonth = 30;
|
||||
jd = gregorianToJulianDay(era, year, 3, 22);
|
||||
}
|
||||
|
||||
if (date.month === 1) {
|
||||
return jd + date.day - 1;
|
||||
}
|
||||
|
||||
jd += leapMonth + Math.min(date.month - 2, 5) * 31;
|
||||
|
||||
if (date.month >= 8) {
|
||||
jd += (date.month - 7) * 30;
|
||||
}
|
||||
|
||||
jd += date.day - 1;
|
||||
return jd;
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
if (date.month === 1 && isLeapYear(date.year + INDIAN_ERA_START)) {
|
||||
return 31;
|
||||
}
|
||||
|
||||
if (date.month >= 2 && date.month <= 6) {
|
||||
return 31;
|
||||
}
|
||||
|
||||
return 30;
|
||||
}
|
||||
|
||||
getYearsInEra(): number {
|
||||
// 9999-12-31 gregorian is 9920-10-10 indian.
|
||||
// Round down to 9919 for the last full year.
|
||||
return 9919;
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['saka'];
|
||||
}
|
||||
|
||||
balanceDate(): void {}
|
||||
}
|
||||
248
web/node_modules/@internationalized/date/src/calendars/IslamicCalendar.ts
generated
vendored
Normal file
248
web/node_modules/@internationalized/date/src/calendars/IslamicCalendar.ts
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright 2020 Adobe. All rights reserved.
|
||||
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
* OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// Portions of the code in this file are based on code from ICU.
|
||||
// Original licensing can be found in the NOTICE file in the root directory of this source tree.
|
||||
|
||||
import {AnyCalendarDate, Calendar, CalendarIdentifier} from '../types';
|
||||
import {CalendarDate} from '../CalendarDate';
|
||||
|
||||
const CIVIL_EPOC = 1948440; // CE 622 July 16 Friday (Julian calendar) / CE 622 July 19 (Gregorian calendar)
|
||||
const ASTRONOMICAL_EPOC = 1948439; // CE 622 July 15 Thursday (Julian calendar)
|
||||
const UMALQURA_YEAR_START = 1300;
|
||||
const UMALQURA_YEAR_END = 1600;
|
||||
const UMALQURA_START_DAYS = 460322;
|
||||
|
||||
function islamicToJulianDay(epoch: number, year: number, month: number, day: number): number {
|
||||
return (
|
||||
day +
|
||||
Math.ceil(29.5 * (month - 1)) +
|
||||
(year - 1) * 354 +
|
||||
Math.floor((3 + 11 * year) / 30) +
|
||||
epoch -
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
function julianDayToIslamic(calendar: Calendar, epoch: number, jd: number) {
|
||||
let year = Math.floor((30 * (jd - epoch) + 10646) / 10631);
|
||||
let month = Math.min(
|
||||
12,
|
||||
Math.ceil((jd - (29 + islamicToJulianDay(epoch, year, 1, 1))) / 29.5) + 1
|
||||
);
|
||||
let day = jd - islamicToJulianDay(epoch, year, month, 1) + 1;
|
||||
|
||||
return new CalendarDate(calendar, year, month, day);
|
||||
}
|
||||
|
||||
function isLeapYear(year: number): boolean {
|
||||
return (14 + 11 * year) % 30 < 11;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Islamic calendar, also known as the "Hijri" calendar, is used throughout much of the Arab
|
||||
* world. The civil variant uses simple arithmetic rules rather than astronomical calculations to
|
||||
* approximate the traditional calendar, which is based on sighting of the crescent moon. It uses
|
||||
* Friday, July 16 622 CE (Julian) as the epoch. Each year has 12 months, with either 354 or 355
|
||||
* days depending on whether it is a leap year. Learn more about the available Islamic calendars
|
||||
* [here](https://cldr.unicode.org/development/development-process/design-proposals/islamic-calendar-types).
|
||||
*/
|
||||
export class IslamicCivilCalendar implements Calendar {
|
||||
identifier: CalendarIdentifier = 'islamic-civil';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
return julianDayToIslamic(this, CIVIL_EPOC, jd);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
return islamicToJulianDay(CIVIL_EPOC, date.year, date.month, date.day);
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
let length = 29 + (date.month % 2);
|
||||
if (date.month === 12 && isLeapYear(date.year)) {
|
||||
length++;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
getMonthsInYear(): number {
|
||||
return 12;
|
||||
}
|
||||
|
||||
getDaysInYear(date: AnyCalendarDate): number {
|
||||
return isLeapYear(date.year) ? 355 : 354;
|
||||
}
|
||||
|
||||
getMaximumMonthsInYear(): number {
|
||||
return 12;
|
||||
}
|
||||
|
||||
getMaximumDaysInMonth(): number {
|
||||
return 30;
|
||||
}
|
||||
|
||||
getYearsInEra(): number {
|
||||
// 9999 gregorian
|
||||
return 9665;
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['AH'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Islamic calendar, also known as the "Hijri" calendar, is used throughout much of the Arab
|
||||
* world. The tabular variant uses simple arithmetic rules rather than astronomical calculations to
|
||||
* approximate the traditional calendar, which is based on sighting of the crescent moon. It uses
|
||||
* Thursday, July 15 622 CE (Julian) as the epoch. Each year has 12 months, with either 354 or 355
|
||||
* days depending on whether it is a leap year. Learn more about the available Islamic calendars
|
||||
* [here](https://cldr.unicode.org/development/development-process/design-proposals/islamic-calendar-types).
|
||||
*/
|
||||
export class IslamicTabularCalendar extends IslamicCivilCalendar {
|
||||
identifier: CalendarIdentifier = 'islamic-tbla';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
return julianDayToIslamic(this, ASTRONOMICAL_EPOC, jd);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
return islamicToJulianDay(ASTRONOMICAL_EPOC, date.year, date.month, date.day);
|
||||
}
|
||||
}
|
||||
|
||||
// Generated by scripts/generate-umalqura.js
|
||||
const UMALQURA_DATA =
|
||||
'qgpUDckO1AbqBmwDrQpVBakGkgepC9QF2gpcBS0NlQZKB1QLagutBa4ETwoXBYsGpQbVCtYCWwmdBE0KJg2VDawFtgm6AlsKKwWVCsoG6Qr0AnYJtgJWCcoKpAvSC9kF3AJtCU0FpQpSC6ULtAW2CVcFlwJLBaMGUgdlC2oFqworBZUMSg2lDcoF1gpXCasESwmlClILagt1BXYCtwhbBFUFqQW0BdoJ3QRuAjYJqgpUDbIN1QXaAlsJqwRVCkkLZAtxC7QFtQpVCiUNkg7JDtQG6QprCasEkwpJDaQNsg25CroEWworBZUKKgtVC1wFvQQ9Ah0JlQpKC1oLbQW2AjsJmwRVBqkGVAdqC2wFrQpVBSkLkgupC9QF2gpaBasKlQVJB2QHqgu1BbYCVgpNDiULUgtqC60FrgIvCZcESwalBqwG1gpdBZ0ETQoWDZUNqgW1BdoCWwmtBJUFygbkBuoK9QS2AlYJqgpUC9IL2QXqAm0JrQSVCkoLpQuyBbUJ1gSXCkcFkwZJB1ULagVrCisFiwpGDaMNygXWCtsEawJLCaUKUgtpC3UFdgG3CFsCKwVlBbQF2gntBG0BtgimClINqQ3UBdoKWwmrBFMGKQdiB6kLsgW1ClUFJQuSDckO0gbpCmsFqwRVCikNVA2qDbUJugQ7CpsETQqqCtUK2gJdCV4ELgqaDFUNsga5BroEXQotBZUKUguoC7QLuQXaAloJSgukDdEO6AZqC20FNQWVBkoNqA3UDdoGWwWdAisGFQtKC5ULqgWuCi4JjwwnBZUGqgbWCl0FnQI=';
|
||||
let UMALQURA_MONTHLENGTH: Uint16Array;
|
||||
let UMALQURA_YEAR_START_TABLE: Uint32Array;
|
||||
|
||||
function umalquraYearStart(year: number): number {
|
||||
return UMALQURA_START_DAYS + UMALQURA_YEAR_START_TABLE[year - UMALQURA_YEAR_START];
|
||||
}
|
||||
|
||||
function umalquraMonthLength(year: number, month: number): number {
|
||||
let idx = year - UMALQURA_YEAR_START;
|
||||
let mask = 0x01 << (11 - (month - 1));
|
||||
if ((UMALQURA_MONTHLENGTH[idx] & mask) === 0) {
|
||||
return 29;
|
||||
} else {
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
function umalquraMonthStart(year: number, month: number): number {
|
||||
let day = umalquraYearStart(year);
|
||||
for (let i = 1; i < month; i++) {
|
||||
day += umalquraMonthLength(year, i);
|
||||
}
|
||||
return day;
|
||||
}
|
||||
|
||||
function umalquraYearLength(year: number): number {
|
||||
return (
|
||||
UMALQURA_YEAR_START_TABLE[year + 1 - UMALQURA_YEAR_START] -
|
||||
UMALQURA_YEAR_START_TABLE[year - UMALQURA_YEAR_START]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Islamic calendar, also known as the "Hijri" calendar, is used throughout much of the Arab
|
||||
* world. The Umalqura variant is primarily used in Saudi Arabia. It is a lunar calendar, based on
|
||||
* astronomical calculations that predict the sighting of a crescent moon. Month and year lengths
|
||||
* vary between years depending on these calculations. Learn more about the available Islamic
|
||||
* calendars
|
||||
* [here](https://cldr.unicode.org/development/development-process/design-proposals/islamic-calendar-types).
|
||||
*/
|
||||
export class IslamicUmalquraCalendar extends IslamicCivilCalendar {
|
||||
identifier: CalendarIdentifier = 'islamic-umalqura';
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
if (!UMALQURA_MONTHLENGTH) {
|
||||
UMALQURA_MONTHLENGTH = new Uint16Array(
|
||||
Uint8Array.from(atob(UMALQURA_DATA), c => c.charCodeAt(0)).buffer
|
||||
);
|
||||
}
|
||||
|
||||
if (!UMALQURA_YEAR_START_TABLE) {
|
||||
UMALQURA_YEAR_START_TABLE = new Uint32Array(UMALQURA_YEAR_END - UMALQURA_YEAR_START + 1);
|
||||
|
||||
let yearStart = 0;
|
||||
for (let year = UMALQURA_YEAR_START; year <= UMALQURA_YEAR_END; year++) {
|
||||
UMALQURA_YEAR_START_TABLE[year - UMALQURA_YEAR_START] = yearStart;
|
||||
for (let i = 1; i <= 12; i++) {
|
||||
yearStart += umalquraMonthLength(year, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let days = jd - CIVIL_EPOC;
|
||||
let startDays = umalquraYearStart(UMALQURA_YEAR_START);
|
||||
let endDays = umalquraYearStart(UMALQURA_YEAR_END);
|
||||
if (days < startDays || days > endDays) {
|
||||
return super.fromJulianDay(jd);
|
||||
} else {
|
||||
let y = UMALQURA_YEAR_START - 1;
|
||||
let m = 1;
|
||||
let d = 1;
|
||||
while (d > 0) {
|
||||
y++;
|
||||
d = days - umalquraYearStart(y) + 1;
|
||||
let yearLength = umalquraYearLength(y);
|
||||
if (d === yearLength) {
|
||||
m = 12;
|
||||
break;
|
||||
} else if (d < yearLength) {
|
||||
let monthLength = umalquraMonthLength(y, m);
|
||||
m = 1;
|
||||
while (d > monthLength) {
|
||||
d -= monthLength;
|
||||
m++;
|
||||
monthLength = umalquraMonthLength(y, m);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new CalendarDate(this, y, m, days - umalquraMonthStart(y, m) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
if (date.year < UMALQURA_YEAR_START || date.year > UMALQURA_YEAR_END) {
|
||||
return super.toJulianDay(date);
|
||||
}
|
||||
|
||||
return CIVIL_EPOC + umalquraMonthStart(date.year, date.month) + (date.day - 1);
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
if (date.year < UMALQURA_YEAR_START || date.year > UMALQURA_YEAR_END) {
|
||||
return super.getDaysInMonth(date);
|
||||
}
|
||||
|
||||
return umalquraMonthLength(date.year, date.month);
|
||||
}
|
||||
|
||||
getDaysInYear(date: AnyCalendarDate): number {
|
||||
if (date.year < UMALQURA_YEAR_START || date.year > UMALQURA_YEAR_END) {
|
||||
return super.getDaysInYear(date);
|
||||
}
|
||||
|
||||
return umalquraYearLength(date.year);
|
||||
}
|
||||
}
|
||||
185
web/node_modules/@internationalized/date/src/calendars/JapaneseCalendar.ts
generated
vendored
Normal file
185
web/node_modules/@internationalized/date/src/calendars/JapaneseCalendar.ts
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright 2020 Adobe. All rights reserved.
|
||||
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
* OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// Portions of the code in this file are based on code from the TC39 Temporal proposal.
|
||||
// Original licensing can be found in the NOTICE file in the root directory of this source tree.
|
||||
|
||||
import {AnyCalendarDate, CalendarIdentifier} from '../types';
|
||||
import {CalendarDate} from '../CalendarDate';
|
||||
import {GregorianCalendar} from './GregorianCalendar';
|
||||
import {Mutable} from '../utils';
|
||||
|
||||
const ERA_START_DATES = [
|
||||
[1868, 9, 8],
|
||||
[1912, 7, 30],
|
||||
[1926, 12, 25],
|
||||
[1989, 1, 8],
|
||||
[2019, 5, 1]
|
||||
];
|
||||
const ERA_END_DATES = [
|
||||
[1912, 7, 29],
|
||||
[1926, 12, 24],
|
||||
[1989, 1, 7],
|
||||
[2019, 4, 30]
|
||||
];
|
||||
const ERA_ADDENDS = [1867, 1911, 1925, 1988, 2018];
|
||||
const ERA_NAMES = ['meiji', 'taisho', 'showa', 'heisei', 'reiwa'];
|
||||
|
||||
function findEraFromGregorianDate(date: AnyCalendarDate) {
|
||||
const idx = ERA_START_DATES.findIndex(([year, month, day]) => {
|
||||
if (date.year < year) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (date.year === year && date.month < month) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (date.year === year && date.month === month && date.day < day) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (idx === -1) {
|
||||
return ERA_START_DATES.length - 1;
|
||||
}
|
||||
|
||||
if (idx === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return idx - 1;
|
||||
}
|
||||
|
||||
function toGregorian(date: AnyCalendarDate) {
|
||||
let eraAddend = ERA_ADDENDS[ERA_NAMES.indexOf(date.era)];
|
||||
if (!eraAddend) {
|
||||
throw new Error('Unknown era: ' + date.era);
|
||||
}
|
||||
|
||||
return new CalendarDate(date.year + eraAddend, date.month, date.day);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Japanese calendar is based on the Gregorian calendar, but with eras for the reign of each
|
||||
* Japanese emperor. Whenever a new emperor ascends to the throne, a new era begins and the year
|
||||
* starts again from 1. Note that eras before 1868 (Gregorian) are not currently supported by this
|
||||
* implementation.
|
||||
*/
|
||||
export class JapaneseCalendar extends GregorianCalendar {
|
||||
identifier: CalendarIdentifier = 'japanese';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let date = super.fromJulianDay(jd);
|
||||
let era = findEraFromGregorianDate(date);
|
||||
|
||||
return new CalendarDate(
|
||||
this,
|
||||
ERA_NAMES[era],
|
||||
date.year - ERA_ADDENDS[era],
|
||||
date.month,
|
||||
date.day
|
||||
);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
return super.toJulianDay(toGregorian(date));
|
||||
}
|
||||
|
||||
balanceDate(date: Mutable<AnyCalendarDate>): void {
|
||||
let gregorianDate = toGregorian(date);
|
||||
let era = findEraFromGregorianDate(gregorianDate);
|
||||
|
||||
if (ERA_NAMES[era] !== date.era) {
|
||||
date.era = ERA_NAMES[era];
|
||||
date.year = gregorianDate.year - ERA_ADDENDS[era];
|
||||
}
|
||||
|
||||
// Constrain in case we went before the first supported era.
|
||||
this.constrainDate(date);
|
||||
}
|
||||
|
||||
constrainDate(date: Mutable<AnyCalendarDate>): void {
|
||||
let idx = ERA_NAMES.indexOf(date.era);
|
||||
let end = ERA_END_DATES[idx];
|
||||
if (end != null) {
|
||||
let [endYear, endMonth, endDay] = end;
|
||||
|
||||
// Constrain the year to the maximum possible value in the era.
|
||||
// Then constrain the month and day fields within that.
|
||||
let maxYear = endYear - ERA_ADDENDS[idx];
|
||||
date.year = Math.max(1, Math.min(maxYear, date.year));
|
||||
if (date.year === maxYear) {
|
||||
date.month = Math.min(endMonth, date.month);
|
||||
|
||||
if (date.month === endMonth) {
|
||||
date.day = Math.min(endDay, date.day);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (date.year === 1 && idx >= 0) {
|
||||
let [, startMonth, startDay] = ERA_START_DATES[idx];
|
||||
date.month = Math.max(startMonth, date.month);
|
||||
|
||||
if (date.month === startMonth) {
|
||||
date.day = Math.max(startDay, date.day);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ERA_NAMES;
|
||||
}
|
||||
|
||||
getYearsInEra(date: AnyCalendarDate): number {
|
||||
// Get the number of years in the era, taking into account the date's month and day fields.
|
||||
let era = ERA_NAMES.indexOf(date.era);
|
||||
let cur = ERA_START_DATES[era];
|
||||
let next = ERA_START_DATES[era + 1];
|
||||
if (next == null) {
|
||||
// 9999 gregorian is the maximum year allowed.
|
||||
return 9999 - cur[0] + 1;
|
||||
}
|
||||
|
||||
let years = next[0] - cur[0];
|
||||
|
||||
if (date.month < next[1] || (date.month === next[1] && date.day < next[2])) {
|
||||
years++;
|
||||
}
|
||||
|
||||
return years;
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
return super.getDaysInMonth(toGregorian(date));
|
||||
}
|
||||
|
||||
getMinimumMonthInYear(date: AnyCalendarDate): number {
|
||||
let start = getMinimums(date);
|
||||
return start ? start[1] : 1;
|
||||
}
|
||||
|
||||
getMinimumDayInMonth(date: AnyCalendarDate): number {
|
||||
let start = getMinimums(date);
|
||||
return start && date.month === start[1] ? start[2] : 1;
|
||||
}
|
||||
}
|
||||
|
||||
function getMinimums(date: AnyCalendarDate) {
|
||||
if (date.year === 1) {
|
||||
let idx = ERA_NAMES.indexOf(date.era);
|
||||
return ERA_START_DATES[idx];
|
||||
}
|
||||
}
|
||||
98
web/node_modules/@internationalized/date/src/calendars/PersianCalendar.ts
generated
vendored
Normal file
98
web/node_modules/@internationalized/date/src/calendars/PersianCalendar.ts
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2020 Adobe. All rights reserved.
|
||||
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
* OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// Portions of the code in this file are based on code from ICU.
|
||||
// Original licensing can be found in the NOTICE file in the root directory of this source tree.
|
||||
|
||||
import {AnyCalendarDate, Calendar, CalendarIdentifier} from '../types';
|
||||
import {CalendarDate} from '../CalendarDate';
|
||||
import {mod} from '../utils';
|
||||
|
||||
const PERSIAN_EPOCH = 1948320;
|
||||
|
||||
// Number of days from the start of the year to the start of each month.
|
||||
const MONTH_START = [
|
||||
0, // Farvardin
|
||||
31, // Ordibehesht
|
||||
62, // Khordad
|
||||
93, // Tir
|
||||
124, // Mordad
|
||||
155, // Shahrivar
|
||||
186, // Mehr
|
||||
216, // Aban
|
||||
246, // Azar
|
||||
276, // Dey
|
||||
306, // Bahman
|
||||
336 // Esfand
|
||||
];
|
||||
|
||||
/**
|
||||
* The Persian calendar is the main calendar used in Iran and Afghanistan. It has 12 months
|
||||
* in each year, the first 6 of which have 31 days, and the next 5 have 30 days. The 12th month
|
||||
* has either 29 or 30 days depending on whether it is a leap year. The Persian year starts
|
||||
* around the March equinox.
|
||||
*/
|
||||
export class PersianCalendar implements Calendar {
|
||||
identifier: CalendarIdentifier = 'persian';
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let daysSinceEpoch = jd - PERSIAN_EPOCH;
|
||||
let year = 1 + Math.floor((33 * daysSinceEpoch + 3) / 12053);
|
||||
let farvardin1 = 365 * (year - 1) + Math.floor((8 * year + 21) / 33);
|
||||
let dayOfYear = daysSinceEpoch - farvardin1;
|
||||
let month = dayOfYear < 216 ? Math.floor(dayOfYear / 31) : Math.floor((dayOfYear - 6) / 30);
|
||||
let day = dayOfYear - MONTH_START[month] + 1;
|
||||
return new CalendarDate(this, year, month + 1, day);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
let jd = PERSIAN_EPOCH - 1 + 365 * (date.year - 1) + Math.floor((8 * date.year + 21) / 33);
|
||||
jd += MONTH_START[date.month - 1];
|
||||
jd += date.day;
|
||||
return jd;
|
||||
}
|
||||
|
||||
getMonthsInYear(): number {
|
||||
return 12;
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
if (date.month <= 6) {
|
||||
return 31;
|
||||
}
|
||||
|
||||
if (date.month <= 11) {
|
||||
return 30;
|
||||
}
|
||||
|
||||
let isLeapYear = mod(25 * date.year + 11, 33) < 8;
|
||||
return isLeapYear ? 30 : 29;
|
||||
}
|
||||
|
||||
getMaximumMonthsInYear(): number {
|
||||
return 12;
|
||||
}
|
||||
|
||||
getMaximumDaysInMonth(): number {
|
||||
return 31;
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['AP'];
|
||||
}
|
||||
|
||||
getYearsInEra(): number {
|
||||
// 9378-10-10 persian is 9999-12-31 gregorian.
|
||||
// Round down to 9377 to set the maximum full year.
|
||||
return 9377;
|
||||
}
|
||||
}
|
||||
81
web/node_modules/@internationalized/date/src/calendars/TaiwanCalendar.ts
generated
vendored
Normal file
81
web/node_modules/@internationalized/date/src/calendars/TaiwanCalendar.ts
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2020 Adobe. All rights reserved.
|
||||
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
* OF ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// Portions of the code in this file are based on code from ICU.
|
||||
// Original licensing can be found in the NOTICE file in the root directory of this source tree.
|
||||
|
||||
import {AnyCalendarDate, CalendarIdentifier} from '../types';
|
||||
import {CalendarDate} from '../CalendarDate';
|
||||
import {fromExtendedYear, getExtendedYear, GregorianCalendar} from './GregorianCalendar';
|
||||
import {Mutable} from '../utils';
|
||||
|
||||
const TAIWAN_ERA_START = 1911;
|
||||
|
||||
function gregorianYear(date: AnyCalendarDate) {
|
||||
return date.era === 'minguo' ? date.year + TAIWAN_ERA_START : 1 - date.year + TAIWAN_ERA_START;
|
||||
}
|
||||
|
||||
function gregorianToTaiwan(year: number): [string, number] {
|
||||
let y = year - TAIWAN_ERA_START;
|
||||
if (y > 0) {
|
||||
return ['minguo', y];
|
||||
} else {
|
||||
return ['before_minguo', 1 - y];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Taiwanese calendar is the same as the Gregorian calendar, but years
|
||||
* are numbered starting from 1912 (Gregorian). Two eras are supported:
|
||||
* 'before_minguo' and 'minguo'.
|
||||
*/
|
||||
export class TaiwanCalendar extends GregorianCalendar {
|
||||
identifier: CalendarIdentifier = 'roc'; // Republic of China
|
||||
|
||||
fromJulianDay(jd: number): CalendarDate {
|
||||
let date = super.fromJulianDay(jd);
|
||||
let extendedYear = getExtendedYear(date.era, date.year);
|
||||
let [era, year] = gregorianToTaiwan(extendedYear);
|
||||
return new CalendarDate(this, era, year, date.month, date.day);
|
||||
}
|
||||
|
||||
toJulianDay(date: AnyCalendarDate): number {
|
||||
return super.toJulianDay(toGregorian(date));
|
||||
}
|
||||
|
||||
getEras(): string[] {
|
||||
return ['before_minguo', 'minguo'];
|
||||
}
|
||||
|
||||
balanceDate(date: Mutable<AnyCalendarDate>): void {
|
||||
let [era, year] = gregorianToTaiwan(gregorianYear(date));
|
||||
date.era = era;
|
||||
date.year = year;
|
||||
}
|
||||
|
||||
isInverseEra(date: AnyCalendarDate): boolean {
|
||||
return date.era === 'before_minguo';
|
||||
}
|
||||
|
||||
getDaysInMonth(date: AnyCalendarDate): number {
|
||||
return super.getDaysInMonth(toGregorian(date));
|
||||
}
|
||||
|
||||
getYearsInEra(date: AnyCalendarDate): number {
|
||||
return date.era === 'before_minguo' ? 9999 : 9999 - TAIWAN_ERA_START;
|
||||
}
|
||||
}
|
||||
|
||||
function toGregorian(date: AnyCalendarDate) {
|
||||
let [era, year] = fromExtendedYear(gregorianYear(date));
|
||||
return new CalendarDate(era, year, date.month, date.day);
|
||||
}
|
||||
Reference in New Issue
Block a user