space lua: os.date add support for %U, %V and %W (#1250)

pull/1246/head^2
KitAmbraid 2025-02-22 12:00:54 +01:00 committed by GitHub
parent 2a3c926849
commit 31792a3a43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 3 deletions

View File

@ -1,5 +1,31 @@
import { LuaBuiltinFunction, LuaTable } from "$common/space_lua/runtime.ts";
const ONE_DAY = 1000 * 60 * 60 * 24;
// weekStartDay: 0 for Sunday, 1 for Monday
// iso: if true, week 01 contains Jan. 4th and prior week is week 52 or 53 of year prior
// if false, week 01 starts on first weekStartDay of the year and prior week is week 00
function weekNumber(inDate: Date, weekStartDay: number, iso: boolean): number {
const year = inDate.getFullYear();
const jan1 = new Date(year, 0, 1);
let jan1Week: number;
if (iso) {
jan1Week = (jan1.getDay() - weekStartDay + 7) % 7 < 3 ? 1 : 0;
} else jan1Week = jan1.getDay() == weekStartDay ? 1 : 0;
const week = Math.floor(
((inDate.getTime() - jan1.getTime() + ONE_DAY) / ONE_DAY) / 7,
) + jan1Week;
if (iso && week == 0) {
const dec31 = new Date(inDate.getFullYear() - 1, 11, 31);
return weekNumber(dec31, weekStartDay, iso);
}
return week;
}
export const osApi = new LuaTable({
time: new LuaBuiltinFunction((_sf, tbl?: LuaTable) => {
if (tbl) {
@ -69,10 +95,13 @@ export const osApi = new LuaTable({
"%j": () => {
const start = new Date(date.getFullYear(), 0, 0);
const diff = date.getTime() - start.getTime();
const oneDay = 1000 * 60 * 60 * 24;
const dayOfYear = Math.floor(diff / oneDay);
const dayOfYear = Math.floor(diff / ONE_DAY);
return dayOfYear.toString().padStart(3, "0");
},
// Week
"%U": () => weekNumber(date, 0, false).toString().padStart(2, "0"),
"%W": () => weekNumber(date, 1, false).toString().padStart(2, "0"),
"%V": () => weekNumber(date, 1, true).toString().padStart(2, "0"),
// Time zone
"%Z": () => {
const match = date.toTimeString().match(/\((.*)\)/);

View File

@ -6,4 +6,8 @@ end
-- Basic OS functions
assert(os.time() > 0)
assert(os.date("%Y-%m-%d", os.time({ year = 2020, month = 1, day = 1 })) == "2020-01-01")
assert(os.date("%Y-%m-%d", os.time({ year = 2020, month = 1, day = 1 })) == "2020-01-01")
-- Week calculations
assert(os.date("%U %V %W", os.time({ year = 2051, month = 1, day = 1 })) == "01 52 00")
assert(os.date("%U %V %W", os.time({ year = 2025, month = 2, day = 18})) == "07 08 07")

View File

@ -35,6 +35,9 @@ Format specifiers:
- `%A`: Full weekday name (e.g., "Sunday")
- `%a`: Abbreviated weekday name (e.g., "Sun")
- `%w`: Weekday (0-6, Sunday is 0)
- `%U`: Week of the year, starting with the first Sunday as the first day of week 01 (00-53)
- `%W`: Week of the year, starting with the first Monday as the first day of week 01 (00-53)
- `%V`: ISO 8601 week of the year (01-53) (see [Wikipedia](https://en.wikipedia.org/wiki/ISO_week_date))
- `%j`: Day of year (001-366)
- `%Z`: Time zone name
- `%z`: Time zone offset from UTC