日本の暦情報を取得するパッケージを作ってみた

no extension

いやね。

ちう記事を見かけて「Go 言語でも似たようなコードを書けばいいぢゃん」と軽く考えたわけですよ。

実は Google Calendar を操作する Go 言語用パッケージとしては Google 公式の

ってのがあるのだが,これって認証とか含めたガチなやつなのよ。 でも欲しいのは国立天文台から「公開」されているただの暦情報なので,こんなガチなやつは(面倒くさいだけだし)要らないわけ。

もっとお気楽に使える iCal パーサがないかなぁ,と思ったらありました。

ありがたや。

早速,これを使って日本の暦情報を取得するパッケージを作ってみた。

これを使った以下のコードは,2020年5月の祝日・休日と二十四節気・雑節を CSV 形式で出力するもの。

package main

import (
	"bytes"
	"fmt"
	"io"
	"os"

	"github.com/spiegel-im-spiegel/koyomi"
)

func main() {
	start, _ := koyomi.DateFrom("2020-05-01")
	end, _ := koyomi.DateFrom("2020-05-31")
	k, err := koyomi.NewSource(
		koyomi.WithCalendarID(koyomi.Holiday, koyomi.SolarTerm),
		koyomi.WithStartDate(start),
		koyomi.WithEndDate(end),
	).Get()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}

	b, err := k.EncodeCSV()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}
	io.Copy(os.Stdout, bytes.NewReader(b))
}

これを実行すると

$ go run sample.go 
"Date","Title"
"2020-05-01","八十八夜"
"2020-05-03","憲法記念日"
"2020-05-04","みどりの日"
"2020-05-05","こどもの日"
"2020-05-05","立夏"
"2020-05-06","休日"
"2020-05-20","小満"

てな感じになる。 また

b, err := k.EncodeCSV()

の部分を

b, err := k.EncodeJSON()

と書き換えれば

$ go run sample.go | jq .
[
  {
    "Date": "2020-05-01",
    "Title": "八十八夜"
  },
  {
    "Date": "2020-05-03",
    "Title": "憲法記念日"
  },
  {
    "Date": "2020-05-04",
    "Title": "みどりの日"
  },
  {
    "Date": "2020-05-05",
    "Title": "こどもの日"
  },
  {
    "Date": "2020-05-05",
    "Title": "立夏"
  },
  {
    "Date": "2020-05-06",
    "Title": "休日"
  },
  {
    "Date": "2020-05-20",
    "Title": "小満"
  }
]

てな感じに JSON 形式でも出力できる。

koyomi.WithCalendarID(), koyomi.WithStartDate(), koyomi.WithEndDate() 各関数は Functional Option なので省略可能である。 まぁ,全部省略したら何も取れないけど(笑)

koyomi.WithCalendarID() 関数には1個以上の koyomi.CalendarID を指定できる。 指定できる koyomi.CalendarID は以下の通り。

const (
    Holiday   CalendarID = iota + 1 //国民の祝日および休日
    MoonPhase                       //朔弦望
    SolarTerm                       //二十四節気・雑節
    Eclipse                         //日食・月食・日面経過
    Planet                          //惑星現象
)

取得できるイベントは日本時間がベースになっていて,しかも(終日イベントなので)日付のみ有効である。 時刻情報はカットされているのであしからず。

あと PuloV/ics-golang パッケージの仕様の問題で,リモートにある iCal ファイルを一時ファイルに落とし込むようだ。 落とし込み先ディレクトリの既定がカレントの tmp/ になっている(ない場合は tmp/ ディレクトリを作成しようとする)。 このディレクトリを指定するのであれば

k, err := koyomi.NewSource(
    koyomi.WithCalendarID(koyomi.Holiday, koyomi.SolarTerm),
    koyomi.WithStartDate(start),
    koyomi.WithEndDate(end),
    koyomi.WithTempDir("/home/username/.cache/"),
).Get()

などとすればよい。

ぶっちゃけ遅いです。 まぁ Google Calndar から iCal ファイルをフィルタリングなしでまるっと取ってくるのだから遅いに決まってるのだけど。 実務で使うならバッチ処理でデータベース等に保持っておくのがよろしいかと思われ。

ブックマーク