🏖️
golangで祝日判定と営業日計算できるライブラリを作った
はじめに
自分がGoでプログラムを組んでいたら営業日計算が必要な場合に遭遇しました。
基本的な営業日なので土日祝日を除いた日での計算になります。
そこまで複雑ではないしrubyならそれっぽいgemがあったはずだからGoでもあるだろうと探してもなかなか見つからない...
外部APIを使用するとメンテコストが高いだろうと思いライブラリとして作りました。
リポジトリ
Install
$ go get github.com/yut-kt/goholiday
Sample
package main
import (
"fmt"
"github.com/yut-kt/goholiday" // ライブラリインポート
"github.com/yut-kt/goholiday/nholidays/jp"
"time"
)
func main() {
ghj := goholiday.New(jp.New())
NYD := "2018-01-01 JST"
datetime, err := time.Parse("2006-01-02 MST", NYD)
if err != nil {
panic(err)
}
// 20営業日後を計算
fmt.Println(ghj.BusinessDaysAfter(datetime, 20))
// 20営業日前を計算
fmt.Println(ghj.BusinessDaysBefore(datetime, 20))
// 祝日かどうか判定
fmt.Println(ghj.IsNationalHoliday(datetime))
// 営業日かどうか判定
fmt.Println(ghj.IsBusinessDay(datetime))
}
今回はパフォーマンスよりも安定性を意識して作ったので少し遅く感じるかもしれませんが、そこまで時間がかかるわけでもないので計算が面倒と感じたら使えるレベルかなと思います。
事前に祝日をメモリ展開することでパフォーマンスも改善しています。
ベンチマーク
ベンチマーク載せておきます。
判定は0.0002ms,営業日計算は0.002sほどかかっています.
バージョンアップして当初から数百倍の速度にはしてあるので実用できそうかと思います.
goos: darwin
goarch: amd64
pkg: github.com/yut-kt/goholiday
BenchmarkIsNationalHoliday-4 10000000 222 ns/op 16 B/op 1 allocs/op
BenchmarkIsNationalHoliday-4 10000000 233 ns/op 16 B/op 1 allocs/op
BenchmarkIsNationalHoliday-4 10000000 235 ns/op 16 B/op 1 allocs/op
BenchmarkIsNationalHoliday-4 10000000 224 ns/op 16 B/op 1 allocs/op
BenchmarkIsNationalHoliday-4 10000000 226 ns/op 16 B/op 1 allocs/op
BenchmarkIsWeekDay-4 10000000 199 ns/op 11 B/op 0 allocs/op
BenchmarkIsWeekDay-4 10000000 200 ns/op 11 B/op 0 allocs/op
BenchmarkIsWeekDay-4 10000000 200 ns/op 11 B/op 0 allocs/op
BenchmarkIsWeekDay-4 10000000 185 ns/op 11 B/op 0 allocs/op
BenchmarkIsWeekDay-4 10000000 192 ns/op 11 B/op 0 allocs/op
BenchmarkBusinessDaysBefore-4 10000 2368289 ns/op 83723 B/op 5225 allocs/op
BenchmarkBusinessDaysBefore-4 10000 2153245 ns/op 83723 B/op 5225 allocs/op
BenchmarkBusinessDaysBefore-4 10000 2122294 ns/op 83723 B/op 5225 allocs/op
BenchmarkBusinessDaysBefore-4 10000 2179232 ns/op 83723 B/op 5225 allocs/op
BenchmarkBusinessDaysBefore-4 10000 2091056 ns/op 83723 B/op 5225 allocs/op
BenchmarkBusinessDaysAfter-4 10000 2033209 ns/op 80509 B/op 5024 allocs/op
BenchmarkBusinessDaysAfter-4 10000 1923448 ns/op 80509 B/op 5024 allocs/op
BenchmarkBusinessDaysAfter-4 10000 1973427 ns/op 80509 B/op 5024 allocs/op
BenchmarkBusinessDaysAfter-4 10000 2109766 ns/op 80509 B/op 5024 allocs/op
BenchmarkBusinessDaysAfter-4 10000 1909945 ns/op 80509 B/op 5024 allocs/op
PASS
ok github.com/yut-kt/goholiday 244.707s
さらにベンチマーク改善しました
$ go test -bench . -benchmem -count 5 -run none
goos: darwin
goarch: arm64
pkg: github.com/yut-kt/goholiday
BenchmarkNew-12 79984 13085 ns/op 42375 B/op 7 allocs/op
BenchmarkNew-12 93198 13324 ns/op 42375 B/op 7 allocs/op
BenchmarkNew-12 93420 13415 ns/op 42375 B/op 7 allocs/op
BenchmarkNew-12 85468 13360 ns/op 42375 B/op 7 allocs/op
BenchmarkNew-12 89742 13285 ns/op 42376 B/op 7 allocs/op
BenchmarkGoholiday_IsNationalHoliday-12 42303 29020 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_IsNationalHoliday-12 41546 28491 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_IsNationalHoliday-12 41554 28864 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_IsNationalHoliday-12 41583 28882 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_IsNationalHoliday-12 41703 28985 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_IsHoliday-12 30775 39136 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_IsHoliday-12 30190 39374 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_IsHoliday-12 30613 39318 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_IsHoliday-12 30726 40038 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_IsHoliday-12 30562 40115 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_IsBusinessDay-12 29947 39978 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_IsBusinessDay-12 30261 39579 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_IsBusinessDay-12 30164 39439 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_IsBusinessDay-12 29936 40088 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_IsBusinessDay-12 29887 39679 ns/op 8128 B/op 508 allocs/op
BenchmarkGoholiday_SetUniqueHolidays-12 41427 28403 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_SetUniqueHolidays-12 41937 29126 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_SetUniqueHolidays-12 41332 28998 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_SetUniqueHolidays-12 42133 28862 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_SetUniqueHolidays-12 41314 29365 ns/op 5856 B/op 366 allocs/op
BenchmarkGoholiday_BusinessDaysAfter-12 19584 61063 ns/op 12048 B/op 753 allocs/op
BenchmarkGoholiday_BusinessDaysAfter-12 19690 61339 ns/op 12048 B/op 753 allocs/op
BenchmarkGoholiday_BusinessDaysAfter-12 19684 61210 ns/op 12048 B/op 753 allocs/op
BenchmarkGoholiday_BusinessDaysAfter-12 19171 61532 ns/op 12048 B/op 753 allocs/op
BenchmarkGoholiday_BusinessDaysAfter-12 19692 60958 ns/op 12048 B/op 753 allocs/op
BenchmarkGoholiday_BusinessDaysBefore-12 19203 61553 ns/op 12048 B/op 753 allocs/op
BenchmarkGoholiday_BusinessDaysBefore-12 19454 62000 ns/op 12048 B/op 753 allocs/op
BenchmarkGoholiday_BusinessDaysBefore-12 19081 62520 ns/op 12048 B/op 753 allocs/op
BenchmarkGoholiday_BusinessDaysBefore-12 19138 62519 ns/op 12048 B/op 753 allocs/op
BenchmarkGoholiday_BusinessDaysBefore-12 19383 62537 ns/op 12048 B/op 753 allocs/op
PASS
ok github.com/yut-kt/goholiday 56.333s
おわりに
Go書いているのは楽しいけど結構他の言語だとこうできるのに、このライブラリないの!?みたいなことに陥るのでもっと言語自体もコミュニティも伸びて行って欲しいです。
現在はコミュニティも大きくなりましたが、ライブラリはまだ少なく感じますね。
もっとこんな機能があったら便利とかあればコメントいただけると追加や修正ができるかもしれないのでお願いします。
Discussion