ちょっと、2月のカレンダーと「14日の土曜日」ネタがらみで、
そういや、2月のカレンダーが823年ぶりというガセ、ゆうきまさみファンならすぐ見抜けたはず…
究極超人あ〜る 8 (少年サンデーコミックス) http://t.co/GKKHtUc5DY
1987/06
第80話「14日の土曜日」 pic.twitter.com/vD0WISAjhS
— 風柳 (@furyutei) 2015, 2月 13
のようなことをつぶやきたいな、と思って、念のため調べていたら、いつの間にかFreeBSDのncalコマンドのバグなのかも?と思われるものを見つけてしまった、という話。
いや、我ながら何を言っているのかわかりませんが…。
■ 経緯
◇ 13日の金曜日よりも14日の土曜日が重要なクラスタより
- タイムライン上に「そういえば13日の金曜日」のようなツイートがちらちら
- すると「14日は土曜日ではないか!」と反応しはじめる、偏った人々(ゆうきまさみフォロワーの方ね)
◇ 2月で「14日の土曜日」だった年を調べたところ…
『あ〜るのバレンタイン話は、確か1987年だったよなぁ』
$ cal 219872月 1987日 月 火 水 木 金 土 12345678910111213141516171819202122232425262728
『うんうん。えーと、今年はそれから何回目?ついでに西暦1年から調べてみるか』
$ python >>> import calendar >>> all, counter =0, 0>>>for year in range(1, 1+2015): ... if calendar.weekday(year, 2, 14)==5: ... all +=1 ... if 1987< year: counter +=1 ... print year ... 4915:(中略)17501756:(中略)198119871998200420092015>>>print all, counter2884>>>
『ほぉ、西暦4年もそうだったのか』
$ cal 242月 4日 月 火 水 木 金 土 1234567891011121314151617181920212223242526272829
『あ、あれれ……?』
:
(中略)
:
$ cal 217502月 1750日 月 火 水 木 金 土 12345678910111213141516171819202122232425262728
『んん…?』
― 間 ―
$ cal 217562月 1756日 月 火 水 木 金 土 1234567891011121314151617181920212223242526272829
『あ、これはちゃんと14日の土曜日になってるな。このあたりが境目、か……?』
◇ 原因は?
$ man cal CAL(1) FreeBSD General Commands Manual CAL(1) NAME cal, ncal ― displays a calendar and the date of Easter (中略) -s country_code Assume the switch from Julian to Gregorian Calendar at the date associated with the country_code. If not specified, ncal tries to guess the switch date from the local environment or falls back to September 2, 1752. This was when Great Britain and her colonies switched to the Gregorian Calendar.
なる程、デフォルトだと、イギリスがグレゴリオ暦を採用した1752年9月14日以降がグレゴリオ暦表示で、それ以前はユリウス暦表示なのね。
$ cal 917529月 1752日 月 火 水 木 金 土 121415161718192021222324252627282930
ほうほう。グレゴリオ暦での1752年9月13日はユリウス暦1752年9月2日なので、こうなるのね。
◇ 国名コードを指定するとどうなる?
これ、他の国だとどうなるんだろう?
ISO 3166-1 - Wikipedia
コマンドの -s オプションで指定できる国名コード(country_code)は二字のもの、ただし、網羅されているわけではない。
そもそも、イタリア(1582年10月15日グレゴリオ暦制定)だと?
《参考資料》ユリウス暦からグレゴリオ暦への切り替え
みんなの知識【ちょっと便利帳】 - その曜日は何日? 各年・各月の曜日を調べる - 西暦と月を設定し、各曜日の日付を一覧表示
・1582年にローマ法王グレゴリオ13世がユリウス暦からグレゴリオ暦への転換を宣言したことにより、この時期にユリウス暦からグレゴリオ暦への切り替えが行われた国があります。
・カトリック国のイタリア、スペインなどでは1582年10月に切り替えが行われ、1582年10月4日の翌日が10月15日になり、1582年10月5日から10月14日までは存在しません。
$ cal -s IT 101582 Usage: cal [general options][-hjy][[month] year] cal [general options][-hj][-m month][year] ncal [general options][-hJjpwy][-s country_code][[month] year] ncal [general options][-hJeo][year] General options: [-NC3][-A months][-B months] For debug the highlighting: [-H yyyy-mm-dd][-d yyyy-mm]
あ、-s オプションは ncal だけか。
$ ncal -s IT 10158210月 1582月 11825火 21926水 32027木 42128金 152229土 162330日 172431
うん、確かに10/15を境に切り替わっているな。
じゃあ、日本だとどうなの?
・1873年1月1日に当たる明治5年12月3日(旧暦)を明治6年1月1日(新暦)とする太陽暦への改暦(明治改暦)。
グレゴリオ暦 - Wikipedia
$ ncal -s JP -A112187212月 18721月 1873月 411182518152229火 512192629162330水 6132027310172431木 71421284111825金 181522295121926土 291623306132027日 3101724317142128
ん?日付は連続しているし……
$ ncal -s IT -A112187212月 18721月 1873月 291623306132027火 3101724317142128水 411182518152229木 512192629162330金 6132027310172431土 71421284111825日 181522295121926
イタリアの暦とも違っている、ということは、このあたりはまだユリウス暦で表示されている、ということ?
◇ ncalでは、日本はいつグレゴリオ暦に切り替えたことになっているのか?
$ ncal -s JP -A112191812月 19181月 1919月 310176132027火 411187142128水 51218152229木 61329162330金 714310172431土 18154111825日 29165121926
は、はい……?
1919年1月1日から切り替えたことになっているのか……なぜ???
■結論(暫定)
結局、自分が調べた範囲では理由がわからず、単純なプログラム上の登録ミスではないか? と考えている。
実は深い理由があるのかも……ご存知の方、教えてください。
[base] Contents of /head/usr.bin/ncal/ncal.c
69/* The switches from Julian to Gregorian in some countries */70staticstruct djswitch { 71constchar *cc; /* Country code according to ISO 3166 */72constchar *nm; /* Name of country */73 date dt; /* Last day of Julian calendar */74 } switches[] = { 75 {"AL", "Albania", {1912, 11, 30}}, 76 {"AT", "Austria", {1583, 10, 5}},
のように、ISO 3166の国名コード(2文字)毎にユリウス暦→グレゴリオ暦に移り変わった日付の定義がなされているが、そのうち、日本(JP)用の定義が違っているのではないか、と。
$ diff -c ncal.c.r241737 ./ncal.c *** ncal.c.r241737 2015-02-13 02:24:25.000000000 +0900--- ./ncal.c 2015-02-13 02:26:03.000000000 +0900****************** 91,97 **** {"HU", "Hungary", {1587, 10, 21}}, {"IS", "Iceland", {1700, 11, 16}}, {"IT", "Italy", {1582, 10, 4}}, ! {"JP", "Japan", {1918, 12, 18}}, {"LI", "Lithuania", {1918, 2, 1}}, {"LN", "Latin", {9999, 05, 31}}, {"LU", "Luxembourg", {1582, 12, 14}}, --- 91,97 ---- {"HU", "Hungary", {1587, 10, 21}}, {"IS", "Iceland", {1700, 11, 16}}, {"IT", "Italy", {1582, 10, 4}}, ! {"JP", "Japan", {1872, 12, 19}}, {"LI", "Lithuania", {1918, 2, 1}}, {"LN", "Latin", {9999, 05, 31}}, {"LU", "Luxembourg", {1582, 12, 14}},
$ # 改修版の実行結果 $ ./ncal -s JP -A112187212月 18721月 1873月 411186132027火 512197142128水 61318152229木 71429162330金 1815310172431土 29164111825日 310175121926
◇ 注釈
そもそも日本の場合、べつにグレゴリオ暦の前にユリウス暦を使っていたわけではないので、定義するのはナンセンス、という話はある。
その上で、元のソースコード中で「グレゴリオ暦1919年1月1日」(厳密にはその前日に当たるユリウス暦1918年12月18日)が登録されている根拠もよくわからず、まだこれよりは、明治改暦が実施された「グレゴリオ暦1873年1月1日」(同1872年12月19日)を登録した方がもっともらしいのではないか、と考える次第。
■ 補足等
◇ ncal のバグについて
そもそもncal中の国別のユリウス暦→グレゴリオ暦切替日定義は、日本以外に関しても信頼できるかどうかは怪しい、のかも。
ncal(1)
BUGS
https://www.freebsd.org/cgi/man.cgi?query=ncal&sektion=1&manpath=FreeBSD+6.0-RELEASE
The assignment of Julian--Gregorian switching dates to country codes is
historically naive for many countries.
$ ncal -p AL Albania 1912-11-30 IT Italy 1582-10-04 AT Austria 1583-10-05 *JP Japan 1918-12-18 AU Australia 1752-09-02 LI Lithuania 1918-02-01 BE Belgium 1582-12-14 LN Latin 9999-05-31 BG Bulgaria 1916-03-18 LU Luxembourg 1582-12-14 CA Canada 1752-09-02 LV Latvia 1918-02-01 CH Switzerland 1655-02-28 NL Netherlands 1582-12-14 CN China 1911-12-18 NO Norway 1700-02-18 CZ Czech Republic 1584-01-06 PL Poland 1582-10-04 DE Germany 1700-02-18 PT Portugal 1582-10-04 DK Denmark 1700-02-18 RO Romania 1919-03-31 ES Spain 1582-10-04 RU Russia 1918-01-31 FI Finland 1753-02-17 SI Slovenia 1919-03-04 FR France 1582-12-09 SW Sweden 1753-02-17 GB United Kingdom 1752-09-02 TR Turkey 1926-12-18 GR Greece 1924-03-09 US United States 1752-09-02 HU Hungary 1587-10-21 YU Yugoslavia 1919-03-04 IS Iceland 1700-11-16
※ラテン世界の9999年
$ ncal -s LN 999999991月 2月 3月 4月 月 181522295121926512192629162330火 29162330613202761320273101724水 310172431714212871421284111825木 4111825181522181522295121926金 5121926291623291623306132027土 613202731017243101724317142128日 714212841118254111825181522295月 6月 7月 8月 月 7142128162330火 18152229172431水 291623301825木 3101724311926金 4111825132027土 5121926142128日 61320271522299月 10月 11月 12月 月 61320274111825181522296132027火 71421285121926291623307142128水 181522296132027310172418152229木 291623307142128411182529162330金 3101724181522295121926310172431土 41118252916233061320274111825日 512192631017243171421285121926
◇ 覚書
- FreeBSD の cal コマンドは ncal コマンドのエイリアス
バイナリレベルで同一。コマンド名で判別し、ncalの -C オプション相当の表示をしている模様。
◇ 愚痴
というかそもそも、「とある年月を境にしてユリウス暦とグレゴリオ暦が切り替えられ、かつ、一見して(表示結果では)それとわからない」なんて仕様のカレンダー自体、やめて欲しいと思うのは自分だけ?
「デフォルトでグレゴリオ暦換算のカレンダーを表示、オプションでユリウス暦換算でも表示可能だよ」でええやん…。