📅

date コマンドから脱却するテンプレート

に公開1

tl;dr

  • date コマンドの差異に気がついていなかった話(Taskfile) で date コマンドを使わないようにしようと考えた
  • 今日日付は簡単だけど、個人的によく使う、前月、翌月の表現に悩んだ
  • 日付確認用の taskfile を作ってチートシート化した
  • 特定の日から前月、翌月を算出する方法の意見募集中

結果

別ファイルのままでも呼べる

# alias t='task' してある
zenn $ t -t Taskfile.date.yml
task: Available tasks for this project:
* format-like-rfc:       date format like RFC      (aliases: rfc)
* format-sequence:       date format sample        (aliases: fs)
* samples:               date samples              (aliases: s)

よく使う定型フォーマットは用意しておくと楽

zenn $ t -t Taskfile.date.yml rfc
2026-09-16 13:45:30
| Format Name           | Sprig                           | Result                          | Note |
|-----------------------|---------------------------------|---------------------------------|------|
| ISO 8601 like date -I | 2006-01-02                      | 2026-09-16                      |  |
| ISO 8601 w/z TZ       | 2006-01-02T15:04:05Z07:00       | 2026-09-16T13:45:30+09:00       |  |
| ISO 5322 a.k.a Email  | Mon, 02 Jan 2006 15:04:05 -0700 | Wed, 16 Sep 2026 13:45:30 +0900 |  |
| RFC 1123              | Mon, 02 Jan 2006 15:04:05 MST   | Wed, 16 Sep 2026 13:45:30 JST   |  |
| ISO 3339              | 2006-01-02T15:04:05Z07:00       | 2026-09-16T13:45:30+09:00       |  |
| YYYY-MM-DD HH:mm:ss   | 2006-01-02 03:04:05             | 2026-09-16 01:45:30             |  |
| YYYY-MM-DD hh:mm:ss   | 2006-01-02 15:04:05             | 2026-09-16 13:45:30             |  |
| YYYYMMDD              | 20060102                        | 20260916                        |  |
| ISO / YMD             | 2006-01-02                      | 2026-09-16                      |  |
| USA / MDY             | 01/02/2006                      | 09/16/2026                      |  |
| EUR / DMY             | 02/01/2006                      | 16/09/2026                      |  |

Go の Sprig template は慣れ

zenn $ t -t Taskfile.date.yml fs
2026-09-16 13:45:30
| HCL   | Sprig     | Result     | Note               |
|-------|-----------|------------|--------------------|
| YYYY  | 2006      | 2026       |4|
| YY    | 06        | 26         |2|
| MMMM  | January   | September  | 月名(フル) |
| MMM   | Jan       | Sep        | 月名(短縮) |
| MM    | 01        | 09         |2|
| M     | 1         | 9          |1|
| DD    | 02        | 16         |2|
| D     | 2         | 16         |1|
| EEEE  | Monday    | Wednesday  | 曜日(フル) |
| EEE   | Mon       | Wed        | 曜日(短縮) |
| hh    | 15        | 13         |24 時間表記 0 埋め |
| h     | 15        | 13         | X 存在しない |
| HH    | 03        | 01         |12 時間表記 0 埋め |
| H     | 3         | 1          |12 時間表記 0 埋めなし |
| AA    | PM        | PM         | AM / PM |
| aa    | pm        | pm         | am / pm |
| mm    | 04        | 45         |2|
| m     | 4         | 45         |1|
| ss    | 05        | 30         |2|
| s     | 5         | 30         |1|
| ZZZZZ | -07:00    | +09:00     | Timezone offset コロンあり |
| ZZZZ  | -0700     | +0900      | Timezone offset コロンなし |
| ZZZ   | MST       | JST        | like UTC (例: JST) |
  • 学習曲線は確かに低いしゆるやかだけど正直嫌い
  • テンプレートフォーマットはフォーマット文字列としての見た目を持っていて欲しい

日付計算

zenn $ t -t Taskfile.date.yml s
| Date                | Result |
| ---                 | --- |
| 2025-06-17 07:48:02 | now |
| 2026-09-16 13:45:30 | BASE_DATE |
| ---                 | --- |
| 2025                | Prev year  : YYYY |
| 2025-09-16          | Prev year  : YYYY-MM-DD |
| 2026-08             | Prev month : YYYY-MM |
| 2026-08-31          | Prev month : YYYY-MM-DD : Last day of last month |
| 2026-09-09          | Prev week  : 7 days ago |
| 2026-09-15          | Prev day   : Yesterday |
| 2026-09-16 12:45:30 | Prev hour  : 1 hour ago |
| 2026-09-16 13:45:30 | BASE_DATE  * |
| 2026-09-16 14:45:30 | Next hour  : 1 hour later |
| 2026-09-17          | Next day   : Tomorrow |
| 2026-09-23          | Next week  : 7 days later |
| 2026-10             | Next month : YYYY-MM |
| 2026-10-02          | Next month : YYYY-MM-DD : Last day of last month |
| 2027-09-16          | Next year  : YYYY-MM-DD |
| 2027                | Next year  : YYYY |
| ---                 | --- |
  • テンプレートだけで割といろいろできる
  • 年は加減算するだけでいいけど、月の移動は関数あったほうが楽
  • 前月、翌月の生成に、他の手段あったら教えて欲しい

まとめ

  • date コマンドをやめるために 3 日も粘った
  • 定期的な振り返り処理を別で書いていて、先月日付の取得は必須だったのでがんばった
  • エポックタイムを計算した後、そこから time.time に戻すのができてない
  • 前月、翌月の生成方法の別解大募集
  • (おまけ)ChatGPT では正解にたどり着けなかった。AI で正解にたどり着くためのプロンプトも募集。。。

Discussion

rakiraki

別解ってほどじゃないけど、前月を取得する計算については、毎月月初に振り返り処理をする時の日付を作っていただけ(毎月第一週程度で実行する。それ以外では実行しない)なので、-648h することで対応するようにした。
当月27日まではちゃんと前月になる(日は気にしてない。あと一応書いておくと28日(-672h)でも問題ない)。
計算用に別途変数を用意するとか長ったらしい式にする必要がないのがメリット。

ところで、今月は28年後が公開予定ね。28日後と28週後を振り返っておかなくちゃ。
28日後はアマプラ、28週後はNetFlixで見れるっぽい(閑話休題)