|
1 | 1 | import { LuaBuiltinFunction, LuaTable } from "$common/space_lua/runtime.ts"; |
2 | 2 |
|
| 3 | +const ONE_DAY = 1000 * 60 * 60 * 24; |
| 4 | + |
| 5 | +// weekStartDay: 0 for Sunday, 1 for Monday |
| 6 | +// iso: if true, week 01 contains Jan. 4th and prior week is week 52 or 53 of year prior |
| 7 | +// if false, week 01 starts on first weekStartDay of the year and prior week is week 00 |
| 8 | +function weekNumber(inDate: Date, weekStartDay: number, iso: boolean): number { |
| 9 | + const year = inDate.getFullYear(); |
| 10 | + const jan1 = new Date(year, 0, 1); |
| 11 | + |
| 12 | + let jan1Week: number; |
| 13 | + if (iso) { |
| 14 | + jan1Week = (jan1.getDay() - weekStartDay + 7) % 7 < 3 ? 1 : 0; |
| 15 | + } else jan1Week = jan1.getDay() == weekStartDay ? 1 : 0; |
| 16 | + |
| 17 | + const week = Math.floor( |
| 18 | + ((inDate.getTime() - jan1.getTime() + ONE_DAY) / ONE_DAY) / 7, |
| 19 | + ) + jan1Week; |
| 20 | + |
| 21 | + if (iso && week == 0) { |
| 22 | + const dec31 = new Date(inDate.getFullYear() - 1, 11, 31); |
| 23 | + return weekNumber(dec31, weekStartDay, iso); |
| 24 | + } |
| 25 | + |
| 26 | + return week; |
| 27 | +} |
| 28 | + |
3 | 29 | export const osApi = new LuaTable({ |
4 | 30 | time: new LuaBuiltinFunction((_sf, tbl?: LuaTable) => { |
5 | 31 | if (tbl) { |
@@ -69,10 +95,13 @@ export const osApi = new LuaTable({ |
69 | 95 | "%j": () => { |
70 | 96 | const start = new Date(date.getFullYear(), 0, 0); |
71 | 97 | const diff = date.getTime() - start.getTime(); |
72 | | - const oneDay = 1000 * 60 * 60 * 24; |
73 | | - const dayOfYear = Math.floor(diff / oneDay); |
| 98 | + const dayOfYear = Math.floor(diff / ONE_DAY); |
74 | 99 | return dayOfYear.toString().padStart(3, "0"); |
75 | 100 | }, |
| 101 | + // Week |
| 102 | + "%U": () => weekNumber(date, 0, false).toString().padStart(2, "0"), |
| 103 | + "%W": () => weekNumber(date, 1, false).toString().padStart(2, "0"), |
| 104 | + "%V": () => weekNumber(date, 1, true).toString().padStart(2, "0"), |
76 | 105 | // Time zone |
77 | 106 | "%Z": () => { |
78 | 107 | const match = date.toTimeString().match(/\((.*)\)/); |
|
0 commit comments