ソフトウェア/javascript/japanese-holidays の履歴(No.3)
更新日本の休日を求めるための javascript ライブラリを npm と github へ公開しました†
祝日名が取れて、なおかつメンテナンスしやすい形の ライブラリが見付からなかったので書いてみました。
一応、複数のライブラリと突き合わせて齟齬がないことを確認しましたが、 運用は個々の責任でお願いします。ミスがあれば教えてください。
法律改正などで休日が変更になっても、よほどのことがない限り definition のところをいじるだけで対応できるはずです。
もともとこのライブラリは 2013 年に書かれた物です。 2016年から 「山の日」 が新設されましたが、これに対するコードの追加は、
LANG: javascript [ "山の日", simpleHoliday( 8, 11), 2016 ],
の一行だけで済みました。
ライセンスは MIT です。 煮るなり焼くなり好きにしてください。
使い方†
npm を使うなら、
LANG:console $ npm i japanese-holidays $ node > Holidays = require('japanese-holidays'); > Holidays.getHolidaysOf(2016); [ { month: 1, date: 1, name: '元日' }, { month: 1, date: 11, name: '成人の日' }, { month: 2, date: 11, name: '建国記念の日' }, { month: 3, date: 20, name: '春分の日' }, { month: 3, date: 21, name: '振替休日' }, { month: 4, date: 29, name: '昭和の日' }, { month: 5, date: 3, name: '憲法記念日' }, { month: 5, date: 4, name: 'みどりの日' }, { month: 5, date: 5, name: 'こどもの日' }, { month: 7, date: 18, name: '海の日' }, { month: 8, date: 11, name: '山の日' }, { month: 9, date: 19, name: '敬老の日' }, { month: 9, date: 22, name: '秋分の日' }, { month: 10, date: 10, name: '体育の日' }, { month: 11, date: 3, name: '文化の日' }, { month: 11, date: 23, name: '勤労感謝の日' }, { month: 12, date: 23, name: '天皇誕生日' } ] > Holidays.isHoliday(new Date(2016,3-1,20)); '春分の日' > Holidays.isHoliday(new Date(2016,3-1,21)); '振替休日'
npm を使わないなら、
https://rawgit.com/osamutake/japanese-holidays-js/master/lib/japanese-holidays.js
を読み込めば JapaneseHolidays に必要な関数が入ってきます。
LANG:javascript <script src="https://rawgit.com/osamutake/japanese-holidays-js/master/lib/japanese-holidays.js"></script> <script> alert( JapaneseHolidays.isHoliday(new Date(2016,3-1,20)) ); </script>
さらにちゃんとした例をこちらに置きました。
http://jsbin.com/qicazaroxu/edit?js,output
リンク先では上記ライブラリを使って休日入りのカレンダーを表示しています。
休日の上にマウスカーソルを置くと、休日名がツールチップとして表示されるはずです。
(下はスクリーンキャプチャーですので表示されている休日名は変化しません)
タイムゾーンに注意が必要†
JapaneseHolidays.isHoliday に与える Date 型の値を作成する際には、 タイムゾーンについてよく考える必要があります。
LANG:javascript JapaneseHolidays.isHoliday(new Date());
例えばこのコードは一見、「今日」が祝日かどうかを判断しているように読めますが、 実際に判断しているのは「今」が祝日かどうか、です。
というのも、このコードが例えばアメリカで実行されたとすると、その時点で アメリカが例えば8日だったとしても、日本はすでに9日かもしれなくて、 isHoliday は実際には今日でなく明日が祝日かどうかを判断してしまうかも しれないのです。
同様に、ニュージーランドで
LANG:javascript JapaneseHolidays.isHoliday(new Date(2016,3,8));
を実行してしまうと、これはニュージーランド時間で 2016-03-08 00:00:00 を表しますから、このとき日本では 2016-03-07 21:00:00 でして、 意図せず前日を判定してしまいます。
ですので、もしあなたが 2016/03/08 が祝日かどうかを判別したければ、 日時を日本のタイムゾーン居合わせて指定しなければなりません。例えば
LANG:javascript JapaneseHolidays.isHoliday(new Date(Date.UTC(2016,3,8,-9)));
のように書けばいいわけです。ちょっと分かりづらかったら試してみれば、
$ node > new Date(Date.UTC(2016,3,8,-9)) Fri Apr 08 2016 00:00:00 GMT+0900 (JST)
のように、正しく動作はすることを確かめられます。とはいえ、 これでは非常に読みづらいので、 JapaneseHolidays は jDate という関数を提供しています。
LANG:javascript JapaneseHolidays.isHoliday(JapaneseHolidays.jDate(2016,3,8)));
これは、上と同じ動作をします。
逆に、ある Date オブジェクトが日本時間で何日の何時何分を 表しているか読み取るため、getJ??? という形式の一連の 関数も提供しています。
LANG:javascript var date = new Date(); var jyear = JapaneseHolidays.getJFullYear(date); var jmonth = JapaneseHolidays.getJMonth(date); var jdate = JapaneseHolidays.getJDate(date); var jday = JapaneseHolidays.getJDay(date); var jhours = JapaneseHolidays.getJHours(date); var jminutes = JapaneseHolidays.getJMinutes(date);
あともう一つ便利なユーティリティ関数として、 JapaneseHolidays.shiftDate があります。 この関数は与えられた Date を与えられた期間分だけ変化させた 値を計算して返します。期間には負の値も入れられます。
LANG:javascript // 1年前 console.log(JapaneseHolidays.shiftDate(new Date(), -1)); // 1ヶ月後 console.log(JapaneseHolidays.shiftDate(new Date(), 0, 1)); // 15ヶ月後 console.log(JapaneseHolidays.shiftDate(new Date(), 0, 15)); // 明日 console.log(JapaneseHolidays.shiftDate(new Date(), 0, 0, 1)); // 100 時間後 console.log(JapaneseHolidays.shiftDate(new Date(), 0, 0, 0, 100));
これらのユーティリティ関数の有効な使い方については、 例えば上でも紹介した jsbin のカレンダーの例をご参照ください。
http://jsbin.com/qicazaroxu/edit?js,output
やっぱりおかしい†
結果がタイムゾーンによらないように、今、ではなく、今日、 の判定をするように変更すべきだと思えてきました。
コメント・質問・バグ報告†
できれば github の方へお願いします。日本語で結構です。
https://github.com/osamutake/japanese-holidays-js/issues
よく分からなければここでも構いません。