Synchro - タイムゾーン型安全な Go ライブラリを開発している
synchro と呼ばれる Go でもタイムゾーンを含めて型比較できるようになるライブラリを開発し始めました。スターください。
こんな感じで使えます。
package main
import (
"fmt"
"time"
"github.com/Code-Hex/synchro"
"github.com/Code-Hex/synchro/tz"
)
func main() {
utcNow := synchro.Now[tz.UTC]()
jstNow := synchro.Now[tz.AsiaTokyo]()
fmt.Println(utcNow)
fmt.Println(jstNow)
// Output:
// 2023-09-02 14:00:00 +0000 UTC
// 2023-09-02 23:00:00 +0900 JST
fmt.Println("------")
d := time.Date(2023, 9, 2, 14, 0, 0, 0, time.UTC)
utc := synchro.In[tz.UTC](d)
jst := synchro.In[tz.AsiaTokyo](d)
fmt.Println(utc)
fmt.Println(jst)
// Output:
// 2023-09-02 14:00:00 +0000 UTC
// 2023-09-02 23:00:00 +0900 JST
// アンコメントするとコンパイルエラーになる。
// invalid operation: utc == jst (mismatched types synchro.Time[tz.UTC] and synchro.Time[tz.AsiaTokyo])
// fmt.Println("compare utc == jst:", utc == jst)
}
GoDoc にいっぱい使用例を載せています。
Playground: https://go.dev/play/p/BoBqPejVJUW
なぜ開発し始めたのか
X (旧 Twitter) で以下のような投稿を見かけた時に、これは確かに良さそう。Go でもやれるじゃん!という気持ちになって開発し始めました。他の言語のいい部分は積極的に取り入れていきたいですね!
このポストの時間帯で検索してみると、沢山の方が日付とタイムゾーンに関して不満を持っていました。
- DB とアプリケーションロジック間での変換
- どのタイムゾーンに変換されたのかぱっと見でわからない
- タイムゾーンの変換がコード上で追い辛い
- 日付ロジックがある一つのタイムゾーンしか考慮されていないのを後から気づく
これらの問題を解決できるといいなと考えています。
基本的な使い方
このパッケージで提供されている関数やメソッドは synchro.In
を用いて time.Time
からタイムゾーンの変換を行なっています。
Go の time.Time
のゼロ値はどうしても UTC になってしまうので、型通りにはならないという点には注意です。
一度 synchro.Time[TimeZone]
の型に変換されるとそのタイムゾーンでの取り扱いが保証されます。
また time
パッケージで提供されてる time.Time
のメソッドだったり関連する関数を同様に提供しているので、既存のロジックを大きく変更しなくても導入できる設計にしました。
便利なユーティリティ
実行速度やバイナリの肥大化の最適化は置いておいて、まずは開発速度を優先する!ことをテーマにして、以下のライブラリを参考にしながらユーティリティ関数を増やしていっています。
個人的に一番気に入っている機能は NowContext
で、これはリクエストが発生した時のタイムスタンプを context.Context
へインジェクトすることで、その時間を現在時刻としてアプリケーションロジックで利用できるようになります。またテストでも現在時刻を固定できるようになるので最高です!
GoDoc に Example をいっぱい書いていますので是非参考にしてください。
- ConvertTz
- NowContext
- Quarter
- Semester
- StartOfMonth
- EndOfMonth
- StartOfQuarter
- EndOfQuarter
- StartOfSemester
- EndOfSemester
- StartOfWeek
- EndOfWeek
- StartOfYear
- EndOfYear
- IsBetween
- IsLeapYear
- DiffInCalendarDays
機能追加のリクエストがあれば気軽に issues を立ててください。日本語でも構いません。
これから対応していきたいこと
- 人に優しいフォーマットでの出力
- i18n
- database/sql での変換
- ISO8601 の扱い
- 高速化
最後に
試してみた感想や意見、これってこうできないの?みたいなフィードバックなどをお待ちしてます。
使ってみた記事や GitHub にスターをいただけると大変喜びます。
Discussion
この度はありがとうございます!途中で X のポストを紹介頂いているので、関連している PHP の brick/date-time の例を含む記事を引用させていただきます 🙏
こちらこそ、相互リンクみたいな形式で貼っていただいてありがとうございます! 🙏
良さそう……!
ところで
コメントアウトするとコンパイルエラーになる
→アンコメントすると〜
でしょうか。恥ずかしい...
修正しました。ありがとうございます!