azihsoyn's blog

技術のこととか釣りの事とか(書けたらいいなぁ)

timeutil改めtimexライブラリを作った

新年早々ブログ書きました。美味しいものを食べた後なので気分がいいです。

タイトル通りtimeutiltimexという薄いライブラリを作りました。 (2018/01/06改名)

何ができるかというとREADMEの通りなのですが、標準のtimeパッケージに入ってない便利メソッドを用意したものになってます。100番煎じぐらいかなと思ったのですが、比較する用の便利ライブラリは探した感じはなさそうだったので公開に至りました。(同名の時刻系ライブラリは見つかりましたが)

業務でgoを書いていて時刻の比較をよく使うのですが、標準のtimeパッケージにはBefore, Afterの比較用メソッドしかなく上記のリンクを毎度探してはテストを厳重に書いてという不毛な努力をしていました。もうこのライブラリさえあればどっちがどっちだっけという混乱はないかなと思います(大げさ)



まぁここまではただの宣伝なのですが、標準のパッケージにある機能を拡張したい場合ってどうするのがいいんでしょうね?考えたのは以下の3つぐらいですが、とりあえず案1を選択しました。

sqldriverみたいにtimeパッケージがinterfaceになってれば案3もできたのかなと思います。

案1

time.Timeをラップする

package timeutil

type Time struct {
    time.Time
}
   t2 := timeutil.Time{n}
    // t2 = timeutil.Time(n) castはできない

    // cannot convert n (type time.Time) to type Time
    t2.Unix() // timeのメソッドは使える

案2

time.Timeを再定義(?)する

package timeutil

type Time time.Time

この場合以下の使い方はできません。

   n := time.Now()
    t1 := timeutil.Time(n) // castはできる
    // t1 = timeutil.Time{n}
    // implicit assignment of unexported field 'wall' in Time literal

    // t1.Unix() time型のメソッドは継承されない
    // t1.Unix undefined (type Time has no field or method Unix)

案3

理想はこんな使い方したい

package main

import (
    "time"
    _ "github.com/azihsoyn/timeutil"
)

func main(){
    now := time.Now()
    now.Between(t1, t2) // timeutilで拡張したメソッドとかも使える
}

モンキーパッチでも書くといいんですかね



なにかいい方法があれば教えてください。

以上。

2018-01-06追記

timeutilだと長い気がしたのでtimexにrenameしました。 sqlxみたいな標準パッケージといい感じに共存できるようなライブラリになれるようにという思いを込めて。hogexって名前の付け方いいですね。