👏

DenoでTimezoneのTypeをtaskとして作る

2023/09/12に公開

Denoだろうが、nodejsだろうがあんまやり方変わらんのですが、
timezone一覧の型が欲しかったりします。
これを作っておくと、後でUTC時刻とtimezoneを分けて管理することが楽になるので、ええ感じのDB、 tableを作るのが楽になります。
また、reactなり何なりでも、frontendからもこの値を参照したらいいので、バックエンドとフロントエンドのタイムゾーンで混乱することもなくなります。

下のようなソースコードを吐くことが出来たらいいんじゃないでしょうか?

Timezone.ts
// Don't edit this file.
// this code create from create_timezone.ts

/** Deno usable timezone list */
export type Timezone =
  "Africa/Abidjan" |
  "Africa/Accra" |
  "Africa/Addis_Ababa" |
  "Africa/Algiers" |
  "Africa/Asmera" |
  "Africa/Bamako" |
  "Africa/Bangui" |
  "Africa/Banjul" |
  ...
  "Pacific/Wallis";

timezoneは増えるとしてもたまにでしょうし、
ユーザーの国が無くても近いやつを選ぶはずです。
(そもそもメジャーな国は全部サポートされている。)

上のソースコードを吐くには下のソースコードをタスクランナーから実行したらいけます。

tasks/create_timezone.ts
const timezone_file = "localize/Timezone.ts";

// clear context file.
await Deno.writeTextFile(timezone_file, "");

const beginning_of_file = `// Don't edit this file.
// this code create from create_timezone.ts

`;

await Deno.writeTextFile(timezone_file, beginning_of_file, {append: true});

// js はunix改行コードで統一されているので\nで良い。
const timezones = ["/** Deno usable timezone list */\n", "export type Timezone =\n"].concat(
    Intl.supportedValuesOf('timeZone').map((x) => String(x)).map(x => `  "${x}" |\n`)
);

// 末尾を削除
timezones[timezones.length - 1] = timezones[timezones.length - 1].slice(0, -3) + ";\n";

for (const timezone of timezones) {
    await Deno.writeTextFile(timezone_file, timezone, {append: true});
}

で下のようなdeno.jsoncをプロジェクト直下に置いときます。

deno.jsonc
{
  "tasks": {
    "create_timezone": "deno run --allow-write tasks/create_timezone.ts"
  },
}

タスクを実行したらええ感じにtimezone.tsが生成されます。

deno task create_timezone

まとめ

Denoあんま関係なかったけど、タイムゾーンで困っている人はぜひ。
規模大きくなると、上みたいな感じで言語にあるなり、自分で作ったなりリソースからソースコード吐けるようにしとくと、エラー、正常、タイムゾーンの文字列の管理がクソ楽になるのでやっとくと助かるかと。

Discussion