Skip to content

Commit 31792a3

Browse files
authored
space lua: os.date add support for %U, %V and %W (#1250)
1 parent 2a3c926 commit 31792a3

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

common/space_lua/stdlib/os.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
import { LuaBuiltinFunction, LuaTable } from "$common/space_lua/runtime.ts";
22

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+
329
export const osApi = new LuaTable({
430
time: new LuaBuiltinFunction((_sf, tbl?: LuaTable) => {
531
if (tbl) {
@@ -69,10 +95,13 @@ export const osApi = new LuaTable({
6995
"%j": () => {
7096
const start = new Date(date.getFullYear(), 0, 0);
7197
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);
7499
return dayOfYear.toString().padStart(3, "0");
75100
},
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"),
76105
// Time zone
77106
"%Z": () => {
78107
const match = date.toTimeString().match(/\((.*)\)/);

common/space_lua/stdlib/os_test.lua

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ end
66

77
-- Basic OS functions
88
assert(os.time() > 0)
9-
assert(os.date("%Y-%m-%d", os.time({ year = 2020, month = 1, day = 1 })) == "2020-01-01")
9+
assert(os.date("%Y-%m-%d", os.time({ year = 2020, month = 1, day = 1 })) == "2020-01-01")
10+
11+
-- Week calculations
12+
assert(os.date("%U %V %W", os.time({ year = 2051, month = 1, day = 1 })) == "01 52 00")
13+
assert(os.date("%U %V %W", os.time({ year = 2025, month = 2, day = 18})) == "07 08 07")

website/API/os.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ Format specifiers:
3535
- `%A`: Full weekday name (e.g., "Sunday")
3636
- `%a`: Abbreviated weekday name (e.g., "Sun")
3737
- `%w`: Weekday (0-6, Sunday is 0)
38+
- `%U`: Week of the year, starting with the first Sunday as the first day of week 01 (00-53)
39+
- `%W`: Week of the year, starting with the first Monday as the first day of week 01 (00-53)
40+
- `%V`: ISO 8601 week of the year (01-53) (see [Wikipedia](https://en.wikipedia.org/wiki/ISO_week_date))
3841
- `%j`: Day of year (001-366)
3942
- `%Z`: Time zone name
4043
- `%z`: Time zone offset from UTC

0 commit comments

Comments
 (0)