🕐

Synchro - タイムゾーン型安全な Go ライブラリを開発している

2023/09/04に公開4

synchro と呼ばれる Go でもタイムゾーンを含めて型比較できるようになるライブラリを開発し始めました。スターください。

https://github.com/Code-Hex/synchro

こんな感じで使えます。

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 でもやれるじゃん!という気持ちになって開発し始めました。他の言語のいい部分は積極的に取り入れていきたいですね!

https://twitter.com/mpyw/status/1697113770840219843?s=20

このポストの時間帯で検索してみると、沢山の方が日付とタイムゾーンに関して不満を持っていました。

  • DB とアプリケーションロジック間での変換
    • どのタイムゾーンに変換されたのかぱっと見でわからない
  • タイムゾーンの変換がコード上で追い辛い
  • 日付ロジックがある一つのタイムゾーンしか考慮されていないのを後から気づく

これらの問題を解決できるといいなと考えています。

基本的な使い方

このパッケージで提供されている関数やメソッドは synchro.In を用いて time.Time からタイムゾーンの変換を行なっています。

Go の time.Time のゼロ値はどうしても UTC になってしまうので、型通りにはならないという点には注意です。

一度 synchro.Time[TimeZone] の型に変換されるとそのタイムゾーンでの取り扱いが保証されます。

また time パッケージで提供されてる time.Time のメソッドだったり関連する関数を同様に提供しているので、既存のロジックを大きく変更しなくても導入できる設計にしました。

便利なユーティリティ

実行速度やバイナリの肥大化の最適化は置いておいて、まずは開発速度を優先する!ことをテーマにして、以下のライブラリを参考にしながらユーティリティ関数を増やしていっています。

個人的に一番気に入っている機能は NowContext で、これはリクエストが発生した時のタイムスタンプを context.Context へインジェクトすることで、その時間を現在時刻としてアプリケーションロジックで利用できるようになります。またテストでも現在時刻を固定できるようになるので最高です!

GoDoc に Example をいっぱい書いていますので是非参考にしてください。

機能追加のリクエストがあれば気軽に issues を立ててください。日本語でも構いません。

これから対応していきたいこと

  • 人に優しいフォーマットでの出力
    • i18n
  • database/sql での変換
  • ISO8601 の扱い
  • 高速化

最後に

試してみた感想や意見、これってこうできないの?みたいなフィードバックなどをお待ちしてます。

使ってみた記事や GitHub にスターをいただけると大変喜びます。

https://twitter.com/codehex/status/1698248990742175803?s=20

Discussion

codehexcodehex

こちらこそ、相互リンクみたいな形式で貼っていただいてありがとうございます! 🙏

firedflyfiredfly

良さそう……!

ところで コメントアウトするとコンパイルエラーになるアンコメントすると〜 でしょうか。

codehexcodehex

恥ずかしい...
修正しました。ありがとうございます!