From 960db96f6261c24b4e86c4f513084f46663693ae Mon Sep 17 00:00:00 2001 From: salano_ym <53254905+salano-ym@users.noreply.github.com> Date: Thu, 11 Apr 2024 17:53:23 +0000 Subject: [PATCH 1/5] Date:to_iso_str --- CHANGELOG.md | 1 + docs/std.md | 5 +++++ src/interpreter/lib/std.ts | 26 ++++++++++++++++++++++++++ test/index.ts | 13 +++++++++++++ 4 files changed, 45 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89464f88..8a757046 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - `Date:millisecond`を追加 - `arr.fill`, `arr.repeat`, `Arr:create`を追加 - JavaScriptのように分割代入ができるように(現段階では機能は最小限) +- `Date:to_iso_str`を追加 # 0.17.0 - `package.json`を修正 diff --git a/docs/std.md b/docs/std.md index 4e888add..1d2e7588 100644 --- a/docs/std.md +++ b/docs/std.md @@ -95,6 +95,11 @@ _date_ を渡した場合、_date_に対応するミリ秒、 ### @Date:parse(_date_: str): num +### @Date:to_iso_str(_date_?: num): str +_date_ を拡張表記のISO形式にした文字列を返します。 +_date_ を渡していない場合は現在時刻を使用します。 +タイムゾーンはローカルのものを参照します。 + ## :: Math 数が多いため専用のページになっています。→[std-math.md](std-math.md) diff --git a/src/interpreter/lib/std.ts b/src/interpreter/lib/std.ts index 469cba07..649dcc4f 100644 --- a/src/interpreter/lib/std.ts +++ b/src/interpreter/lib/std.ts @@ -220,6 +220,32 @@ export const std: Record = { assertString(v); return NUM(new Date(v.value).getTime()); }), + + 'Date:to_iso_str': FN_NATIVE(([v]) => { + if (v) { assertNumber(v); } + + const date = new Date(v?.value || Date.now()); + const y = date.getFullYear().toString().padStart(4, "0"); + const mo = (date.getMonth() + 1).toString().padStart(2, "0"); + const d = date.getDate().toString().padStart(2, "0"); + const h = date.getHours().toString().padStart(2, "0"); + const mi = date.getMinutes().toString().padStart(2, "0"); + const s = date.getSeconds().toString().padStart(2, "0"); + const ms = date.getMilliseconds().toString().padStart(3, "0"); + + const offset = date.getTimezoneOffset(); + let offset_s; + if (offset === 0) { + offset_s = "Z"; + } else { + const sign = (offset < 0) ? "+" : "-"; + const offset_h = Math.floor(Math.abs(offset) / 60).toString().padStart(2, "0"); + const offset_m = (Math.abs(offset) % 60).toString().padStart(2, "0"); + offset_s = `${sign}${offset_h}:${offset_m}`; + } + + return STR(`${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}${offset_s}`); + }), //#endregion //#region Math diff --git a/test/index.ts b/test/index.ts index 5d4634e9..8ae01005 100644 --- a/test/index.ts +++ b/test/index.ts @@ -3128,6 +3128,19 @@ describe('std', () => { }); }); }); + + describe('Date', () => { + test.concurrent('to_iso_str', async () => { + const res = await exe(` + let d1 = Date:parse("2024-04-12T01:47:46.021+09:00") + let s1 = Date:to_iso_str(d1) + let d2 = Date:parse(s1) + <: [d1, d2, s1] + `); + eq(res.value[0], res.value[1]); + assert.match(res.value[2].value, /^[0-9]{4,4}-[0-9]{2,2}-[0-9]{2,2}T[0-9]{2,2}:[0-9]{2,2}:[0-9]{2,2}\.[0-9]{3,3}(Z|[-+][0-9]{2,2}:[0-9]{2,2})$/); + }); + }); }); describe('Unicode', () => { From 205f3322d3b3d738652fb0fa3bb79e5d9a19473f Mon Sep 17 00:00:00 2001 From: salano_ym <53254905+salano-ym@users.noreply.github.com> Date: Mon, 15 Apr 2024 09:58:48 +0000 Subject: [PATCH 2/5] =?UTF-8?q?Date:to=5Fiso=5Fstr=E3=81=AB=E5=BC=95?= =?UTF-8?q?=E6=95=B0time=5Foffset=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/std.md | 5 +++-- src/interpreter/lib/std.ts | 39 +++++++++++++++++++++++--------------- test/index.ts | 33 ++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/docs/std.md b/docs/std.md index 1d2e7588..d857e498 100644 --- a/docs/std.md +++ b/docs/std.md @@ -95,10 +95,11 @@ _date_ を渡した場合、_date_に対応するミリ秒、 ### @Date:parse(_date_: str): num -### @Date:to_iso_str(_date_?: num): str +### @Date:to_iso_str(_date_?: num, _time_offset_?: num): str _date_ を拡張表記のISO形式にした文字列を返します。 _date_ を渡していない場合は現在時刻を使用します。 -タイムゾーンはローカルのものを参照します。 +_time_offset_ はUTCからの時差(分単位)を指定します。 +_time_offset_ を渡していない場合はローカルのものを参照します。 ## :: Math 数が多いため専用のページになっています。→[std-math.md](std-math.md) diff --git a/src/interpreter/lib/std.ts b/src/interpreter/lib/std.ts index 649dcc4f..36266468 100644 --- a/src/interpreter/lib/std.ts +++ b/src/interpreter/lib/std.ts @@ -221,29 +221,38 @@ export const std: Record = { return NUM(new Date(v.value).getTime()); }), - 'Date:to_iso_str': FN_NATIVE(([v]) => { + 'Date:to_iso_str': FN_NATIVE(([v, ofs]) => { if (v) { assertNumber(v); } + const date = new Date(v?.value ?? Date.now()); - const date = new Date(v?.value || Date.now()); - const y = date.getFullYear().toString().padStart(4, "0"); - const mo = (date.getMonth() + 1).toString().padStart(2, "0"); - const d = date.getDate().toString().padStart(2, "0"); - const h = date.getHours().toString().padStart(2, "0"); - const mi = date.getMinutes().toString().padStart(2, "0"); - const s = date.getSeconds().toString().padStart(2, "0"); - const ms = date.getMilliseconds().toString().padStart(3, "0"); - - const offset = date.getTimezoneOffset(); + if (ofs) { assertNumber(ofs); } + const offset = ofs?.value ?? -date.getTimezoneOffset(); + console.log(ofs?.value); + console.log(offset); let offset_s; if (offset === 0) { offset_s = "Z"; } else { - const sign = (offset < 0) ? "+" : "-"; - const offset_h = Math.floor(Math.abs(offset) / 60).toString().padStart(2, "0"); - const offset_m = (Math.abs(offset) % 60).toString().padStart(2, "0"); - offset_s = `${sign}${offset_h}:${offset_m}`; + const sign = Math.sign(offset); + const offset_hours = Math.floor(Math.abs(offset) / 60); + const offset_minutes = Math.abs(offset) % 60; + date.setUTCHours(date.getUTCHours() + sign * offset_hours); + date.setUTCMinutes(date.getUTCMinutes() + sign * offset_minutes); + + const sign_s = (offset > 0) ? "+" : "-"; + const offset_hours_s = offset_hours.toString().padStart(2, "0"); + const offset_minutes_s = offset_minutes.toString().padStart(2, "0"); + offset_s = `${sign_s}${offset_hours_s}:${offset_minutes_s}`; } + const y = date.getUTCFullYear().toString().padStart(4, "0"); + const mo = (date.getUTCMonth() + 1).toString().padStart(2, "0"); + const d = date.getUTCDate().toString().padStart(2, "0"); + const h = date.getUTCHours().toString().padStart(2, "0"); + const mi = date.getUTCMinutes().toString().padStart(2, "0"); + const s = date.getUTCSeconds().toString().padStart(2, "0"); + const ms = date.getUTCMilliseconds().toString().padStart(3, "0"); + return STR(`${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}${offset_s}`); }), //#endregion diff --git a/test/index.ts b/test/index.ts index 8ae01005..9597b96e 100644 --- a/test/index.ts +++ b/test/index.ts @@ -3140,6 +3140,39 @@ describe('std', () => { eq(res.value[0], res.value[1]); assert.match(res.value[2].value, /^[0-9]{4,4}-[0-9]{2,2}-[0-9]{2,2}T[0-9]{2,2}:[0-9]{2,2}:[0-9]{2,2}\.[0-9]{3,3}(Z|[-+][0-9]{2,2}:[0-9]{2,2})$/); }); + + test.concurrent('to_iso_str (UTC)', async () => { + const res = await exe(` + let d1 = Date:parse("2024-04-12T01:47:46.021+09:00") + let s1 = Date:to_iso_str(d1, 0) + let d2 = Date:parse(s1) + <: [d1, d2, s1] + `); + eq(res.value[0], res.value[1]); + eq(res.value[2], STR("2024-04-11T16:47:46.021Z")); + }); + + test.concurrent('to_iso_str (+09:00)', async () => { + const res = await exe(` + let d1 = Date:parse("2024-04-12T01:47:46.021+09:00") + let s1 = Date:to_iso_str(d1, 9*60) + let d2 = Date:parse(s1) + <: [d1, d2, s1] + `); + eq(res.value[0], res.value[1]); + eq(res.value[2], STR("2024-04-12T01:47:46.021+09:00")); + }); + + test.concurrent('to_iso_str (-05:18)', async () => { + const res = await exe(` + let d1 = Date:parse("2024-04-12T01:47:46.021+09:00") + let s1 = Date:to_iso_str(d1, -5*60-18) + let d2 = Date:parse(s1) + <: [d1, d2, s1] + `); + eq(res.value[0], res.value[1]); + eq(res.value[2], STR("2024-04-11T11:29:46.021-05:18")); + }); }); }); From ee2733b90e33cf354f3df0d37eeb59a799013762 Mon Sep 17 00:00:00 2001 From: salano_ym <53254905+salano-ym@users.noreply.github.com> Date: Mon, 15 Apr 2024 11:31:04 +0000 Subject: [PATCH 3/5] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AA=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AE=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/interpreter/lib/std.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/interpreter/lib/std.ts b/src/interpreter/lib/std.ts index 36266468..5983e3bc 100644 --- a/src/interpreter/lib/std.ts +++ b/src/interpreter/lib/std.ts @@ -227,8 +227,6 @@ export const std: Record = { if (ofs) { assertNumber(ofs); } const offset = ofs?.value ?? -date.getTimezoneOffset(); - console.log(ofs?.value); - console.log(offset); let offset_s; if (offset === 0) { offset_s = "Z"; @@ -255,6 +253,21 @@ export const std: Record = { return STR(`${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}${offset_s}`); }), + + 'Date:to_utc_iso_str': FN_NATIVE(([v]) => { + if (v) { assertNumber(v); } + + const date = new Date(v?.value || Date.now()); + const y = date.getUTCFullYear().toString().padStart(4, "0"); + const mo = (date.getUTCMonth() + 1).toString().padStart(2, "0"); + const d = date.getUTCDate().toString().padStart(2, "0"); + const h = date.getUTCHours().toString().padStart(2, "0"); + const mi = date.getUTCMinutes().toString().padStart(2, "0"); + const s = date.getUTCSeconds().toString().padStart(2, "0"); + const ms = date.getUTCMilliseconds().toString().padStart(3, "0"); + + return STR(`${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}Z`); + }), //#endregion //#region Math From c3b12f96687f709d1c1f8bf71e7506891a9f1e2e Mon Sep 17 00:00:00 2001 From: salano_ym <53254905+salano-ym@users.noreply.github.com> Date: Mon, 15 Apr 2024 12:09:02 +0000 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BD=99=E8=A8=88=E3=81=AA=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AE=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/interpreter/lib/std.ts | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/interpreter/lib/std.ts b/src/interpreter/lib/std.ts index 5983e3bc..a636ddd5 100644 --- a/src/interpreter/lib/std.ts +++ b/src/interpreter/lib/std.ts @@ -229,7 +229,7 @@ export const std: Record = { const offset = ofs?.value ?? -date.getTimezoneOffset(); let offset_s; if (offset === 0) { - offset_s = "Z"; + offset_s = 'Z'; } else { const sign = Math.sign(offset); const offset_hours = Math.floor(Math.abs(offset) / 60); @@ -253,21 +253,6 @@ export const std: Record = { return STR(`${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}${offset_s}`); }), - - 'Date:to_utc_iso_str': FN_NATIVE(([v]) => { - if (v) { assertNumber(v); } - - const date = new Date(v?.value || Date.now()); - const y = date.getUTCFullYear().toString().padStart(4, "0"); - const mo = (date.getUTCMonth() + 1).toString().padStart(2, "0"); - const d = date.getUTCDate().toString().padStart(2, "0"); - const h = date.getUTCHours().toString().padStart(2, "0"); - const mi = date.getUTCMinutes().toString().padStart(2, "0"); - const s = date.getUTCSeconds().toString().padStart(2, "0"); - const ms = date.getUTCMilliseconds().toString().padStart(3, "0"); - - return STR(`${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}Z`); - }), //#endregion //#region Math From 3c54235646efc57ac206d6182cb8b8090ed006bd Mon Sep 17 00:00:00 2001 From: salano_ym <53254905+salano-ym@users.noreply.github.com> Date: Mon, 15 Apr 2024 12:20:03 +0000 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BA=8C=E9=87=8D=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E7=AC=A6=E3=82=92=E4=B8=80=E9=87=8D=E5=BC=95=E7=94=A8=E7=AC=A6?= =?UTF-8?q?=E3=81=AB=20lint=E3=81=AE=E8=AD=A6=E5=91=8A=E8=A7=A3=E6=B6=88?= =?UTF-8?q?=E3=81=AE=E3=81=9F=E3=82=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/interpreter/lib/std.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/interpreter/lib/std.ts b/src/interpreter/lib/std.ts index a636ddd5..33daec7d 100644 --- a/src/interpreter/lib/std.ts +++ b/src/interpreter/lib/std.ts @@ -237,19 +237,19 @@ export const std: Record = { date.setUTCHours(date.getUTCHours() + sign * offset_hours); date.setUTCMinutes(date.getUTCMinutes() + sign * offset_minutes); - const sign_s = (offset > 0) ? "+" : "-"; - const offset_hours_s = offset_hours.toString().padStart(2, "0"); - const offset_minutes_s = offset_minutes.toString().padStart(2, "0"); + const sign_s = (offset > 0) ? '+' : '-'; + const offset_hours_s = offset_hours.toString().padStart(2, '0'); + const offset_minutes_s = offset_minutes.toString().padStart(2, '0'); offset_s = `${sign_s}${offset_hours_s}:${offset_minutes_s}`; } - const y = date.getUTCFullYear().toString().padStart(4, "0"); - const mo = (date.getUTCMonth() + 1).toString().padStart(2, "0"); - const d = date.getUTCDate().toString().padStart(2, "0"); - const h = date.getUTCHours().toString().padStart(2, "0"); - const mi = date.getUTCMinutes().toString().padStart(2, "0"); - const s = date.getUTCSeconds().toString().padStart(2, "0"); - const ms = date.getUTCMilliseconds().toString().padStart(3, "0"); + const y = date.getUTCFullYear().toString().padStart(4, '0'); + const mo = (date.getUTCMonth() + 1).toString().padStart(2, '0'); + const d = date.getUTCDate().toString().padStart(2, '0'); + const h = date.getUTCHours().toString().padStart(2, '0'); + const mi = date.getUTCMinutes().toString().padStart(2, '0'); + const s = date.getUTCSeconds().toString().padStart(2, '0'); + const ms = date.getUTCMilliseconds().toString().padStart(3, '0'); return STR(`${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}${offset_s}`); }),