qcal/common/src/french/index.ts

150 lines
3.4 KiB
TypeScript
Raw Normal View History

2022-02-12 13:02:31 -05:00
import data from './cal.json';
2022-02-13 00:02:01 -05:00
import ruralName from './rural-days.json';
2022-02-12 12:27:14 -05:00
// Month 13 is for the complementary days
2023-04-21 02:21:12 -04:00
export type FrenchMonth = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
export type FrenchDay =
2022-02-12 12:27:14 -05:00
1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
| 12
| 13
| 14
| 15
| 16
| 17
| 18
| 19
| 20
| 21
| 22
| 23
| 24
| 25
| 26
| 27
| 28
| 29
| 30;
export type FrenchDate = {
2022-02-12 13:17:24 -05:00
year: number,
2023-04-21 02:21:12 -04:00
month: FrenchMonth,
day: FrenchDay,
2022-02-12 13:17:24 -05:00
};
2023-04-22 19:02:25 -04:00
const monthNames: { [key in FrenchMonth]: string } = {
2022-02-12 12:27:14 -05:00
1: 'Vendémiaire',
2: 'Brumaire',
3: 'Frimaire',
4: 'Nivôse',
5: 'Pluviôse',
6: 'Ventôse',
7: 'Germinal',
8: 'Floréal',
9: 'Prairial',
10: 'Messidor',
11: 'Thermidor',
12: 'Fructidor',
13: 'Jours Complémentaires',
};
2022-02-12 13:02:31 -05:00
export const decadeNames = [
'primidi', 'duodi', 'tridi', 'quartidi', 'quintidi', 'sextidi', 'septidi', 'octidi', 'nonidi', 'décadi',
];
2023-04-22 19:02:25 -04:00
export const frStartJD = data.start_jd;
export const frStartYear = data.start_year;
2022-02-12 12:27:14 -05:00
const leaps: Array<number> = [0];
let leapFromStart = 0;
data.leap.forEach(leap => {
leapFromStart += leap;
leaps.push(leapFromStart);
2022-02-12 17:58:54 -05:00
2022-02-12 12:27:14 -05:00
});
2023-04-22 19:02:25 -04:00
export const frEndYear = frStartYear + leaps.length - 1;
2023-04-21 02:21:12 -04:00
2022-02-12 17:58:54 -05:00
export function frSupportedYear(year: number): boolean {
2023-04-22 19:02:25 -04:00
return frStartYear <= year && year <= frEndYear;
2022-02-12 17:58:54 -05:00
}
2023-04-21 02:21:12 -04:00
export function frJDN(year: number, month: FrenchMonth, day: FrenchDay): number {
2023-04-22 19:02:25 -04:00
const dy = year - frStartYear;
2022-02-12 12:27:14 -05:00
const dd = month * 30 + day - 31;
2023-04-22 19:02:25 -04:00
return frStartJD + 365 * dy + leaps[dy] + dd;
2022-02-12 12:27:14 -05:00
}
export function frIsLeap(year: number): boolean {
2023-04-22 19:02:25 -04:00
return !!data.leap[year - frStartYear];
}
2023-04-22 19:02:25 -04:00
export const frEndJD = frJDN(frEndYear, 13, frIsLeap(frEndYear) ? 6 : 5);
2022-02-14 01:48:09 -05:00
export function jdnFrench(jdn: number): FrenchDate {
let lo = 0;
let hi = leaps.length;
while (lo + 1 < hi) {
const mid = Math.floor((lo + hi) / 2);
2023-04-22 19:02:25 -04:00
if (frStartJD + 365 * mid + leaps[mid] <= jdn)
lo = mid;
else
hi = mid;
}
2023-04-22 19:02:25 -04:00
const dd = jdn - (frStartJD + 365 * lo + leaps[lo]);
return {
2023-04-22 19:02:25 -04:00
year: frStartYear + lo,
2023-04-21 02:21:12 -04:00
month: Math.floor(dd / 30) + 1 as FrenchMonth,
day: dd % 30 + 1 as FrenchDay,
2023-04-22 19:02:25 -04:00
};
2022-02-12 13:39:32 -05:00
}
2023-04-21 02:21:12 -04:00
export function monthName(month: FrenchMonth): string {
2022-02-12 12:27:14 -05:00
return monthNames[month];
}
2023-04-21 02:21:12 -04:00
export function dateName(month: FrenchMonth, day: FrenchDay): string | null {
2022-02-12 12:27:14 -05:00
if (month === 13) {
switch (day) {
2022-02-12 13:02:31 -05:00
case 1:
return 'La Fête de la Vertu';
case 2:
return 'La Fête du Génie';
case 3:
return 'La Fête du Travail';
case 4:
return "La Fête de l'Opinion";
case 5:
return 'La Fête des Récompenses';
case 6:
return 'La Fête de la Révolution';
default:
return null;
2022-02-12 12:27:14 -05:00
}
}
return `${day} ${monthNames[month]}`;
}
2022-02-13 00:02:01 -05:00
2023-04-21 02:21:12 -04:00
export function dateRuralName(month: FrenchMonth, day: FrenchDay): { name: string, title: string } | null {
2022-02-13 00:02:01 -05:00
const rural = ruralName[month * 30 + day - 31];
if (!rural)
return null;
const [name, title] = rural;
return {name, title};
}
2023-04-21 02:21:12 -04:00
2023-04-22 19:02:25 -04:00
export function frDateFormat({year, month, day}: { year: number, month: FrenchMonth, day: FrenchDay }): string {
return `${dateName(month, day)} ${year}`;
}