space lua: os.date add support for %U, %V and %W (#1250)
parent
2a3c926849
commit
31792a3a43
|
@ -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(/\((.*)\)/);
|
||||
|
|
|
@ -7,3 +7,7 @@ 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")
|
||||
|
||||
-- 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")
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue