[401] 日時処理で犯しがちなミスの1つが暦年と週年の混同です。 本来暦年を指定するべきところで週年を指定してしまったために、 年が1年ずれたり、思いもよらない日時表示が出現したり、 一見関係なさそうなシステムに不具合が生じたりします。
[402] ここでいう暦年とは、 (暦年, 暦月, 暦日) の組で日付を特定する、 私達が普段用いている年月日 (暦日付) の年です。
[403] そして週年とは、 (週年, 暦週, 曜日) の組で日付を特定する週暦 (週日付) の年です。
[404] 月日と週の関係は毎年変化します。 つまりの曜日は毎年違います。 「週年 > 暦週 > 曜日」 の包含関係を保ちつつ7日周期の週を恒久的に連続させるには、 前年末の何日かを翌年に移動させるか、 翌年始の何日かを前年に移動させなければなりません。 そのため暦年の年始と週年の年始は一致しないことが多くなります。 わかりやすく言えば、 に週年が切り替わるとは限らないのです。
[405]
日時処理で最も広く実装されている週暦がISO週暦です。
暦週は月曜日に始まり日曜日に終わります。
グレゴリオ年の最初の木曜日が含まれる暦週
(= 4日以上が新グレゴリオ年に含まれる暦週)
が、その週年の第1週になります。
[406] 週暦は他にもあり得ます (そして実際に使われています)。 次の表では、
においてからの年始がどの日になるかを一覧にしています。
本項の趣旨から離れますが、
表に挙げた手法以外にもが含まれる週を第1週とするなどいくつかの方法が使われています。
[411] この問題には、 日時というシステムが内在する複雑さに加えて、 プログラマーを誘い込む罠のような好ましからざる言語仕様や、 誤情報の拡散があって混沌としています。
%G
と %Y
[394]
日時書式指定の構文の1つに
C言語などで使われる
POSIX
の
strftime(3)
のものがあります。
それによると
%G
が週年、
%Y
が暦年を表します。
また、
%g
と %y
はそれぞれ週年と暦年の2桁年号を表します。
>>398, >>393
[399]
本来の POSIX の strftime
以外でも、
プログラミング言語のライブラリー等で同等の構文に対応していることがあります。
[395]
たまに暦年のつもりで
%G
を使う人がいるようで、
年末年始に不具合が起きることがあるといわれます。
[396]
暦月は %m
,
暦日は %d
のように英語の頭文字になっているので、
暦年は %Y
や %y
だと予想が付きそうなもので、
意味がわからない %G
を使ってしまうのがどういう誤解に基づくのか、
よくわかりません。
[397]
ドキュメントの先頭から読んでいくとアルファベット順で
%G
が先に出てくるから、という説が唱えられています。
ドキュメントによっては説明が簡素すぎて暦年と週年の違いがわかりにくこともあるようです。
[400]
%G
と %Y
の違いについて、
POSIX
が悪い、
仕様がおかしいと主張する人もいるようです (>>154, >>155, >>245)。
逆恨みではないでしょうか。
[412]
の Twitter 障害 (>>2) の原因がこの
%G
の誤用とする説が有力視されています。
そのため悪名が広まったのですが、
大規模な障害で %G
が関係したといわれているのはその1件だけです。
他にもいちいち報告されないレベルの小規模な不具合は起きているのかもしれませんが・・・。
[413]
なお、
%G
など strftime(3)
で使われるのは、
ISO週暦です。
YYYY
と yyyy
[385]
日時書式指定の構文の1つに UAX #35 (LDML) の
date format pattern
があります。
それによると Y
が週年、 y
が暦年を表します。
>>386
[387]
大文字と小文字の違いだけで意味が変わるのはわかりにくいですね。
ドキュメントを注意して読まないと取り違えてしまいます。
もし間違って使っていても気づきにくいです。
他の日時書式指定の構文では大文字の Y
でも暦年を表すことがあるので、
その利用経験があるとかなり混乱しそうです。
[388]
月の M
と分の m
も大文字と小文字の違いしかないのですが、
月と分はほとんどの瞬間に違う値になるので、間違えてもすぐに気づきます。
暦年と週年はほとんどの時期に同じ値になるので、
発覚が遅れてしまいます。
M
と m
の書き分けは他の多くの日時書式指定の構文でも採用されていながら、
それが原因の不具合はほとんど報告されていません。
[414]
なお
LDML の date format pattern
における週は
LDML/CLDR週です。
これはロケールによって挙動が変化します。
暦法がグレゴリオ暦で週初が月曜日のとき
ISO週暦と同等になります。
[392] ICU がこの構文を実装しています。 >>391 (LDML の実質的な参照実装でしょう。)
[390]
Apple のプラットフォームで使われる NSDateFormatter
はこの構文を採用しています。
>>389
バックエンドが ICU なのか独自実装なのかは不明です。
[317]
Objective-C や Swift の
NSDateFormatter
(Mac OS X や iOS)
の
YYYY
を誤用したことによる大小の不具合
(質問サイトへの投稿を含みます。)
は、
少なくても末
>>227, >>330,
末 >>331, >>332 / 初 >>327,
末 >>333,
末 >>342,
末
>>318,
末
>>318
など
>>326, >>328, >>329, >>334
に繰り返し報告されています。
末の >>108、
末の >>282
も参照。
[415] 自己解決できず質問サイトに投稿されて発覚したものだけで相当数に上りますので、 潜在的にはもっと多数の事象が発生していると推測できます。
[319]
NSDateFormatter
は日時を整形して文字列を得るだけでなく、
文字列を解釈して日時を得る操作もできます。
その解釈にもやはり同じ書式の指定を用いるため、
yyyy
でなく
YYYY
と指定すると暦年でなく週年と解釈されることになります。
これによる不具合も何度か報告されています
>>318。
[336] この場合は対象となる日付は年末年始に限りません。
2012-09-14
()
を
YYYY-MM-dd
として解釈した結果、
「2011-09-13 16:00:00 +0000」
が得られました。
>>318Feb 28, 2013 05:30pm
()
を
MMM dd, YYYY hh:mma
として解釈した結果、
「2013-01-05 12:00:00 +0000」
が得られました。
>>34003-02-2017
()
を
dd-MM-YYYY
として解釈した結果、
「2016-12-24 16:00:00 +0000」
が得られました。
>>32001/24/2018
()
を
MM/dd/YYYY
として解釈した結果、
「2017-12-24」
が得られました。
>>338[343]
書式を用いた日時文字列の構文解析の挙動の詳細は、
Apple のドキュメントにも、
そこから参照される LDML >>269
にも定められていません。
報告されている
NSDateFormatter
の挙動はプログラマーにとって意図しないものですが、
Apple
にとって意図したものなのかどうかはよくわかりません。
[344]
YYYY-MM-dd
のような指定があると、
(週年, 暦月, 暦日)
という3つの値の組から日付を決定することになります。
年末年始の日付で曖昧性が生じるかもしれませんが、
それ以外の大部分の日付は実は曖昧なく特定できます。
[345] そうなっていないのは、おそらく週年の年始の日付を基準に、 月と日の値を調整するような形の実装になっているのでしょう。
[346] きっと Apple は週年が暦月や暦日と組み合わせるようなケースは想定していなかったのでしょう。 想定していない入力に対して壊れた (しかしそのことがわかりにくい) 出力をするくらいなら、 エラーにしてしまうべきだと思うのですが、 十年以上もこの仕様にしてしまっている以上、 後方互換性のため今更仕様変更というわけにもいかないのでしょう。
[322] 本題から外れますが、 その質問サイトは投稿日時を
<div class="flex--item ws-nowrap mr16 mb8" title="2012-09-14 11:00:30Z"> <span class="fc-light mr2">Asked</span> <time itemprop="dateCreated" datetime="2012-09-14T11:00:30">9 years, 10 months ago</time> </div> <div class="flex--item ws-nowrap mr16 mb8"> <span class="fc-light mr2">Modified</span> <a href="?lastactivity" class="s-link s-link__inherit" title="2019-05-19 03:43:59Z">3 years, 1 month ago</a> </div>
のように記述しています。 >>318
[323]
作成日時は Microdata の特性として time
要素で記述されていますが、
更新日時が time
要素でも Microdata 特性でもないただのテキストだけなのは謎です。
[324]
両者ともただの div
要素や a
要素の title
属性にそれと等しい日時らしきものを記述しています。
日時を記述する意思はあるのに、なぜ time
要素にしないのか不思議です。
[325]
作成日の場合 title
属性値は時間帯の Z
が明記されているのに、
time
要素の datetime
属性値には付いていません。
これは HTML の time
要素の構文として誤りではないのですが、
時間帯が不明の地方時の扱いになってしまいます。
時間帯を明示する意思はあるのに、なぜ time
要素でだけ明示しないのか謎です。
[371] 、 iOS の指定日時の alarm 機能が動作しなくなる不具合が発生しました。 >>375, >>374, >>373, >>370, >>377
[372] Apple は、 に解消すると回答しました。 >>373, >>370, >>377 実際そうだったことを時点で一般の利用者が確認していました >>374。
[378]
Apple は夏時刻関係で alarm の不具合を度々起こしているので、
利用者らはまたいつものかという反応だったようです。
[379] にも同じ現象が発生しました。 しかし Apple はその間に修正版を公開しており、 不具合が発生したのは1年間更新されていない環境のみだったようです。 >>376
[383] この頃はあまり原因を追求した記事が出ていなかったようですが、 の不具合 (>>348) では前例として参照されて、 どちらも週暦絡みの問題ではないかと疑われたようです。 (実際そうである可能性は低くなさそうです。)
[348] 、 Apple 社の iOS に新規実装されていた Do Not Disturb (DND) 機能が誤動作する不具合が発生しました。 これは予め指定していた時刻に切り替わるはずでしたが、 それが機能しなくなっていました。 >>357, >>349, >>347, >>365
[351] 、 Apple は、 以来機能しなくなっており、 に復旧すると発表しました。 >>350, >>361, >>366, >>369
[353] 付の Apple 文書には iOS を更新すると解消すると書かれており >>352、 その日までには修正版が公開されたようです。
[384] この件に対する反応では、 の不具合 (>>371) などが参照されて、またいつものやつか、 なぜ再発したのか (修正したのではなかったのか)、 といったような反応だったようです。 (関係していそうな機能ではありますが、実装の一部が共有されていたのか、 まったく独立して発生したのかはわかりません。)
[355] Apple は不具合の原因は発表せず、 ニュースサイト記者の照会にも回答しませんでした >>349, >>347。
[356]
週が関係している >>354,
ISO週日付が関係している >>347, >>362, >>366
といった推測がなされています。
もっと踏み込んで
yyyy
とするべきところを YYYY
と誤ったとの推測もあります >>347。
[363] ただしの年始数日がISO週暦に属する >>347, >>362 とするのは誤りで >>362、 逆にがISO週暦に属します。 従ってそのような単純な誤りではこの不具合は説明できません。 また週年と暦年の違いを 「ISO versus Gregorian」 と表現する >>347 のも誤りです。
[367]
YYYY
や yyyy
のような表現について、
Unix-style date formatting
だと説明する者がいたようです。
それは誤りで正しくは
「ISO-based」
だと訂正する記事があります。
>>366
ただし「Unix」だとする部分は当該記事が補っていて、
原文
>>368
にはありません。
他のツイートから補ったのかもしれませんが、出典不明です。
しかも訂正後の
「ISO-based」
も誤っています。
[360] 発症直後ののうちに日付を変えて各年の挙動を確かめた人がいました。 >>359 この結果は原因の推測に大変参考になります。
Let's check the next few years, this is the pattern :
2013 : Issue fixed on Sunday Jan 6 2014 : Issue fixed on Sunday Jan 5 2015 : Issue fixed on Sunday Jan 4 2016 : Issue not happening even though first day is a Friday 2017 : Issue fixed on Sunday Jan 8 (Jan 1st is also a Sunday) 2018 : Issue fixed on Sunday Jan 7 2019 : Issue fixed on Sunday Jan 6 2020 : Issue fixed on Sunday Jan 5 2021 : Issue fixed on Sunday Jan 3 2022 : Issue not happening even though first day is a Saturday 2023 : Issue fixed on Sunday Jan 8 (Jan 1st is also a Sunday) 2024 : Issue fixed on Sunday Jan 7 Etc...The same pattern happens if you go back in time as well.
[2] 米国時間の、 Android 版 Twitter 公式アプリ等一部のクライアント (すべてではありません。) から Twitter にログインできなくなる障害がありました。 >>11, >>12, >>16, >>17, >>18
[19] Android 版 Twitter 公式アプリ等では、 一部の利用者がログアウト状態になり、 再ログインできない症状が発生していました。 >>17, >>18, >>30, >>263, >>250
[20] Twitter API を利用した外部製アプリでは、 新着ツイートの日付が “365日前” となる現象が発生していました。 >>17, >>18, >>30
[13] 付けの公式発表によれば、 から まで発生していました。 >>12
[14] 原因は 「front end code」 の不具合とだけ発表されました。 >>12。 ここでいうフロントエンドが何を指すか明らかではありませんが、 Android 版アプリや Twitter API 利用クライアント等での障害報告があること >>1, >>16 や、 この時間で対処可能であったことを鑑みれば、 Twitter サービスを提供するアプリケーションサーバーのうち、 アクセスを受け付ける外部側に近しい部分を担当するシステムでしょうか。
[3] 障害発生直後の 頃、 Twitter のHTTPサーバーが西暦2015年12月29日と書いた HTTPヘッダーを HTTP応答に含めて送ってきていると一般の Twitter 利用者と思われるアカウントが発見し、 数分後に報告しました。 >>1
[4] 発見報告ツイートへの返信で指摘されていますが、 本来のと曜日が合いません。 >>1 の曜日のまま、年が誤っているのです。
[5] 指摘はされていませんが、発見報告ツイートの画像 >>1 をよく見ると、
Date:
ヘッダーだけで、
Last-Modified:
ヘッダーはです。
年以外は秒まで一致しているにも関わらずです。Set-Cookie:
ヘッダーの
Expires
属性はになっていますが、
年と曜日を除けば月から秒まで一致しています。
(構文が他と少し違いますが、それは仕様通りです。
Date:
と
Expires
の時間帯は UTC
になっています。
Last-Modified:
の時間帯は
GMT
です。
正しいのは
GMT
です。
(ちょっと複雑な事情: [9]
この状況から、この3つの日付はすべて別の方法で出力されたことがわかります。
当時と現在では Twitter のサーバーの仕様も違っているでしょうからもはや検証不能ですが、
おそらく Expires
は現在日時の1年後を示していたものでしょう。
UTC
と誤記していたのは、この障害とは関係なく元々そうだったのでしょう。
Last-Modified:
はわかりませんが、
Date:
と
Expires
は
HTTP
専用の日時形式生成ライブラリーではなく独自のアドホックな方法で生成していたのか、
専用ライブラリーだとしても製作者は HTTP
の知識に乏しかったのでしょう。
[25] この発見報告が最速かどうかはわかりませんが、 この報告には多くの返信が付いており、 外部のブログ等からも引用されました。
[152] Berk D. Demir (@bd) は本段落執筆 () 時点で Twitter のプロフィールに元 Twitter 社員と書いています >>149。 当時は Twitter 社員の技術者であることをほのめかす記述がありました >>150。 が最終出社日で >>151、 障害当時もまだ社員だったことは確実と思われます。
[153] Berk D. Demir は、 に、 何かに驚いたような、しかし含みを残したような、 意味深なツイートを投稿しました。 >>144
[154] Berk D. Demir は、 に、 現状を的確に説明したイラストとして、 POSIX に銃口を向けた絵をツイートしました。 >>145
[155] Berk D. Demir は、 に、
my dinner is corn chips and soda. THANK YOU POSIX!
夕食はコーンチップとソーダでした。 ** POSIX さんありがと! **
と皮肉めいてツイートしました。 >>134 それに対する返信に対して Berk D. Demir は、 に、
%Good on you lad.
と意味深に「%G」と書いて返しました。 >>136 また、元の投稿に対して Rich Unger (>>141) は、 に、 料理中に呼び出されたので云々と返信しました。 >>133
[141] Rich Unger (@rich_unger) は本段落執筆 () 時点で Twitter のプロフィールに元 Twitter 社員と書いています >>140。 時点で入社1年と書いていました >>139。 障害から数日経ったには、 自分は Twitter でずっと技術的負債の相手をしているとツイートしていました >>137。 特に何を指しているとは言っていませんが、次に示すツイートを鑑みれば、 今回の障害をも含めていると解するのが自然でしょう。
[142] Rich Unger は、 に、
Hey, anyone know what week it is?
ねえ、いま何週か誰か知ってます?
[157] mark mcbride (@mccv) は Twitter の Java 技術者でしたが、 に3年にして退職したことを公表していました。 >>158 従って障害当時は社員ではありませんでした。 mark mcbride は障害当時、 Twitter の新旧社員らと障害原因についてツイートしていました。 >>156
[176] Jeff Hodges (@jmhodges) は Twitter の技術者でしたが、 に退職しました。 >>170 従って障害当時は社員ではありませんでした。 Jeff Hodges は障害当時、 Twitter の新旧社員らと障害原因についてツイートしていました。 >>175
[180] Jeff Hodges は、 に、 特に何とは明言せず、 YYYY と %G に言及しました。 >>165 続いて 、
If you're using YYYY in your JVM service or %G in anything, fix it now. You're using the wrong year format. Reproduction: `date -u "+%G"`
JVM サービスで YYYY を使っている人、何かで %G を使っている人は、今すぐ修正されたし。年の書式を間違って使っています。再現:
date -u "+%G"
とツイートしました。 >>169 このツイートはよく拡散されました >>171。
[143] 元社員の mark mcbride (>>157) と Jeff Hodges (>>176) は、 障害の原因は何だろうねとツイートし合っていました。 >>159
[178] Twitter 社員の Rich Unger (>>142) は、 に、
I'd tell you the root cause, Jeff, but you'd be too sad to have missed this.
Jeff に根本の原因を教えてあげたいわ、でもこれ逃してたなんて悲しみそうよね。
と返信しました。 >>132
[179]
その返信に対して
Jeff Hodges
は、
%G
ではないかという推測 >>165
を示しました >>163。
Rich Unger
はそれに対して特に何も明言しませんでした。
[177] Twitter 社員の Berk D. Demir (>>152) は、 に、
startup idea: uber for incident time ex-employee sideshows of wisdom distribution.
起業案: 事案の時に元従業員が余興で知識を広める Uber。
[181] 以上、 Twitter 社員は障害原因と明言はしないものの、 週年との関係性をほのめかすツイートをしていました。 そして親交が続いていたらしい Twitter 元社員が、 やはり障害原因とは明言しないものの、 より具体化したツイートで週年との関係性を説明していました。 そして Twitter 社員はその事故原因共有プロセスを好意的に評価していました。
[182] Twitter 社員が明言しなかったのは、 おそらく Twitter 社でも社内のプログラムコードの情報や障害原因は社外秘であって、 一従業員の立場で勝手にそれを開示するわけにはいかなかったからでしょう。 しかし技術者としての落胆や知的興奮の発露や情報共有の欲求は抑えきれなかったのですね。
[183] 元社員が非公開の場でそうした情報を密かに知った可能性は否定できませんが、 いずれのツイートも公開情報から推測し得る範囲に留まっていますから、 あくまで独自の推測で発言したものと思われます。 (同内容の推測は元社員以外も早い段階で行われています: 例えば >>1 への返信。) 社員時代に障害発生部分にどの程度関与していたかは不明ですが、 ある程度のシステム構成のイメージは把握していたでしょうから、 まったくの外部の人よりは確度が高く予測できそうです。 そして社員がその予測に明確な否定はせず、 歓迎するかのような反応をしているのをみれば、 概ね妥当な線といえるのではないでしょうか。
[108] Twitter のすべてのアクセスが遮断されたわけではありませんでしたから、 Twitter では利用者による関係する投稿が相次ぎました。 その中には Twitter の HTTP応答に注目したもの (>>3) や、それを受けて週年との関係を指摘したものもありました。
[109]
年末の月曜日というタイミングで年が切り替わるという現象に心当たりある技術者は珍しくないようです。
そしてその具体的な原因として、
日時形式パターンの G
と Y
の取り違いや、
yyyy
と YYYY
の取り違いではないかと推測されていました。
(例えば >>1 の返信欄を参照。)
[111] 一方で情報技術者ながらもその挙動に驚きを隠せないコメントを残す人が少なくありませんでした。 見る人が見れば一瞬でわかる反面、 まったく想像だにしなかった人も多いということなのでしょう。
[15] ITベンチャー系Web媒体として有名な TechCrunch (本家英語版) は、 に障害を報じました。 実際には復旧後に追記されています。 しかしこの記事は障害の発生原因には踏み込んでいませんでした。 >>16
[53] 本段落を執筆した時点で、 このWebページには次のようにあります。 >>16
2014/12/28
とあります。<meta name=sailthru.date>
には
"2014-12-28 18:21:52"
とあります。
Sailthruの日時形式で、時間帯は明記されません。dateCreated
が "2014-12-29T02:21:52Z"、
datePublished
が "2014-12-29T02:21:52Z"、
dateModified
が "2015-01-13T06:55:41Z"
とあります。datePublished
が "2014-12-29T02:21:52+00:00"、
dateModified
が "2015-01-13T06:55:41+00:00"
とあります。<meta name>
cXenseParse:recs:publishtime
に
"2014-12-29T02:21:52Z"、
cXenseParse:modified_time
に
"2015-01-13T06:55:41Z"
とあります。<time class="full-date-time" datetime="2014-12-29T02:21:52">11:21 AM GMT+9<span class="full-date-time__separator">•</span>December 29, 2014</time>
[21] 有名Web媒体の ZDNet (本家英語版) は、 に障害を報じました。 >>18
[24] この記事は、障害の症状を紹介したものでしたが、 「Twitter は2015年をほぼぶっ飛ばして2016年に近づいている」 と皮肉って、キャッチーな見出しを付けていました。 Twitter 社の告知文 (出典は明記されていませんが、 >>74 と推測されます。) を引用していました。 初公開以後も更新されているようですが (>>23)、 復旧は報じていませんし、 原因にも言及していません。 >>17, >>18
[68] 本段落を執筆した時点で、 このWebページには次のようにあります。 >>17
"articlePubDate":"2014-12-29 02:29:00+0000"
とあります。dateModified
が
"2015-01-05T22:29:00.000Z"、
datePublished
が
"2014-12-29T02:29:00.000Z"
とあります。<time class="c-globalAuthor_time">Dec. 28, 2014</time>とあります。
[28] IT技術者向けニュース掲示板コミュニティーの Slashdot (本家英語版) は、 29日13時 (時間帯不明) に記事を公開しました。 TechCrunch の記事 (>>15) と ZDNet の記事 (>>21) を参照し、特に後者から日時が1年ずれた症状の説明を引用していました。 >>27
[76] 本段落を執筆した時点で、 このWebページには次のようにあります。 >>27
14/12/29
とあります。<time id="fhtime-68598101" datetime="on Monday December 29, 2014 @01:01AM">on Monday December 29, 2014 @01:01AM</time>とあります。
[29] 1つ前の記事は URL path に「29」とあって表示されている日付に「28」とあります。 両者は別の瞬間または別の時間帯の日付であるようです。
[81] Internet Archive では時点の版が最古です。
[44] この事件の原因に言及したツイートがあったとされます >>51, >>52。 残念ながらこのアカウントは現在非公開になっており >>49、 Twitter サイト上の原文を確認できません。
[88]
Twitter の当該ページで返信関係の子孫に当たるツイートとして表示されるもののうち、
最古のものの日時は
2014-12-29T05:39:58.000Z
となっています
>>49, >>45。
従って大元のツイートはこれを下らないことになります。
(引用の >>51, >>52 とも引用元の日付だけで時刻は不明です。どちらの記事もこの返信ツイートより後に公開されたものです。)
a single character G instead of Y took down twitter’s api because the ISO year starts today
たった1文字 Y でなく G のせいで Twitter の API が落ちた、 今日から ISO 年が始まったので
[90]
すなわち、
「ISO year」 (>>185)
を表す
G
を暦年を表す
Y
のかわりに使ってしまったので障害が発生したと断定していました。
[91] しかしこのツイートはその根拠を一切示していませんでした。 同じアカウントの他のツイートがそれを書いていた可能性も否定はできませんが、 ツイートが非公開で他のサイトにも引用されていないため、 何とも言えません。
[92] このアカウントの所有者の素性もツイートが非公開のため確認し難いです。 しかし Internet Archive で確認できるごく一部のツイートや、 返信している他の人からのツイート、 当時及び現在のアカウントのプロフィール (bio) 欄とそのリンク先の Webページの記述内容において、 この人物が Twitter の社員等、本件の原因を知り得る立場にあったと推測し得る徴証は見つけられません。
[26] 時間的には Twitter 関係者のツイート (例えば >>155, >>180) を見て書いたのかもしれませんし、 まったく根拠なく当てずっぽうで書いているのかもしれませんが、 今となっては確かめる術がありません。
[185] このツイートは、 「ISO year」 が始まったの原因だと言っています。 このツイートだけ読んでも 「ISO year」 とは何か明らかにし得ませんが、 ISO 8601 の定める週年の意味でしょうか。 返信にも週年の誤りではないかとの指摘がありますが、 元のツイート主はそれに反応していません。 (現在では非公開なので、その後訂正したのかどうかわかりません。) 暦年と週年の取り違えが原因ではないかという文脈で、 暦年も週年もどちらも ISO 8601 の定めるところであるにも関わらず、 週年を 「ISO year」 と表記するのは極めて不適切と言わざるを得ません。 誤りといってもいいでしょう。
[186] そしてそのような技術的誤りを含むツイートを事実確認もせずに引用する媒体 (>>47 >>102) もまた、信頼に値しないと言わざるを得ません。 障害の原因 (とされるもの) を理解していたなら、 それと同じ過ちを犯したツイートを根拠に記事が書けるはずがありません。
[31] 英国のニュースサイト The Guardian は、 に障害を報じました。 >>30, >>32
[46] この記事はサーバーの返す時刻の間違いの発見ツイート (>>3) を引いて症状を紹介しました。 >>30
[47]
更に、
1文字間違いのツイート (>>44) を引いて、
Mac
で
date
コマンドを使って日時書式付けを1文字変えて実行した画面を示しつつ、
Assuming that this is the error that brought Twitter down overnight, it’s easy to see how it happened.
これが Twitter を一晩落とした誤りだったとすると、 如何にして起こったのかよくわかります。
と書いていました。 これを踏まえてでしょう、 この記事は障害を
a bug in a line of code caused the service to think that it was 29 December, 2015
1行のコードのバグによって Twitter は2015年12月29日だと思ってしまった
と説明していました。 「Assuming」と一歩引いた表現を織り交ぜながらも、 原因が週年を表す「1行」だと完全に断定しています。 >>30
[110]
この date
コマンドは元 Twitter 関係者がツイートしたもの
(>>180) とほぼ同じですが、そのツイートは引用していません。
この分野の知識のある技術者なら難しいものではなく、
単純で誰が書いても同じになるものですから、
まったく独立に考案していたとしてもおかしくありません。
当該ツイートを見ていなかったのでしょう。
素性の分からない者のツイートを引用してソースにするくらいですから、
情報源を隠す理由はないはずです。
[82] 本段落を執筆した時点で、 このWebページには次のようにあります。 >>30
2014/dec/29
とあります。datePublished
が
"2014-12-29T16:14:50.000Z"、
dateModified
が
"2017-02-21T18:17:06.000Z"
とあります。article:published_time
が
"2014-12-29T16:14:50.000Z"、
article:modified_time
が
"2017-02-21T18:17:06.000Z"
とあります。<details class="dcr-km9fgb"><summary class="dcr-h56grb">Mon 29 Dec 2014 16.14 GMT</summary>First published on Mon 29 Dec 2014 16.12 GMT</details>とあります。
[39] Internet Archive で保存されている最古は 時点とされるものです。 次のようにあります。 >>32
datePublished
は
"2014-12-29T11:14:50-0500"
と書かれていました。article:published_time
は
"2014-12-29T16:14:50.000Z"、
article:modified_time
は
"2014-12-29T17:30:27.963Z"
と書かれていました。"renderTime":"2014-12-30T02:06:30Z"
、
"webPublicationDate":1419869690000
と書かれていました。
>>32[35]
当時は time
要素で日時が HTML レベルで機械可読な形で明示されていたのに、
現在はそうではありません。 Webページの技術担当者 (社?) が変わったのでしょうか。
技術的には退化していると言わざるを得ません。
[93] 仏国のあるブログは、 に本件に言及しました。 >>48
[101] この記事は障害の期間を 「this Monday, between midnight and 5 AM, CET」 としました。 出典はなく根拠は不明です。 >>48 公式発表によれば UTC の0時から5時半前で (>>99)、 CET (>>13) では1時から6時半前に当たるものです。 分を丸めた大雑把な表現とも捉えられますが、 換算を1時間誤ったと解する方が素直でしょうか。
[102] この記事は1文字間違いのツイート (>>44) を引いて、
A bug in a line of code caused the service to think that it was 29 December, 2015.
1行のコード中のバグによって Twitter は2015年12月29日だと思ってしまった。
と断言しました。 >>48
[103] そして、
ISO week numbering system uses the
YYYY
format for the year instead of the Gregorian calendar’syyyy
.
と説明していました。 >>48
[187] この記事は 「ISO year」 という誤った記述 (>>185) を含んだツイートを引用しながら、何の断りもなくそれを 「ISO week numbering system」 の年の話にすり替えています。 文意を汲んだものだとしても、 話の根幹に関わる部分でこれは不誠実ではないでしょうか。
[104]
しかもこの記事は、
ISO週の週年が障害の原因だとする解釈は受け入れながら、
なぜか引用元ツイートの1文字間違い説ではなく大文字と小文字の違いで説明しています。
ただしこの記事の説明は ISO週がそうだと言っているだけで、
Twitter のシステムがそうしているとは断言していません
(著者はそう思っていたのかもしれませんが、この記事だけではどちらとも言えません)。
また、 YYYY
/ yyyy
の書式がどのプラットフォームのどの構文に基づいているのか、
一言も説明がありません。 ISO が決めているという認識かもしれませんね。
[106] この記事の著者が Twitter の社員等、本件の原因を知り得る立場にあったと推測し得る徴証は見つけられません。
[105] 更に Apple の Do Not Disturb の不具合を先行事例 >>347 として引いて、 日時処理は難しいと結んでいました。 >>48
[107] 本段落を執筆した時点で、 このWebページには次のようにあります。 >>48
2014/12
とあります。<li class="date-meta"> <div class="genericon genericon-month"></div> <span class="screen-reader-text">Date</span> <a href="https://blog.antoine-augusti.fr/2014/12/twitter-api-app-down-5-hours-calendars/" rel="bookmark" title="9 h 29 min">30 December 2014</a> </li>とあります。
[223] 英語の IT技術者向け掲示板コミュニティーとして有名な Hacker News には、 (時間帯不明) に親記事が投稿され、 多くのコメントが集まりました。 >>220
<span class="age" title="2014-12-29T15:35:12"><a href="item?id=8810157">on Dec 29, 2014</a></span>
と書かれていましたが、
The single character G instead of Y took down Twitter's API today.
たった1文字 Y でなく G のせいで Twitter の API が落ちた
と題し、本文で
If you're using YYYY in your JVM service or %G in anything, fix it now. You're very likely using the wrong year format.
date Mon Dec 29 00:44:45 EST 2014 date -u "+%G" 2015
ISO 8601 week numbering has 2015 start this week.
JVM サービスで YYYY を使っている人、何かで %G を使っている人は、今すぐ修正されたし。年の書式を間違って使っています。
date Mon Dec 29 00:44:45 EST 2014 date -u "+%G" 2015
ISO 8601 紀週法では今週、2015年が始まります。
と書きました。 >>220
[225] 題名は >>89, 本文の先頭2段落は >>169 のツイートとほぼ一致するものです。 差はほんのわずかで、明らかにどちらかがどちらかの複製です。 当サイトの日時が北米太平洋標準時だとすれば、 本文は >>169 がオリジナルということになります。 題名は >>89 の日時が確定できないので判断できません。
[228]
この
Hacker News
の記事に対し、その出典は何なのかと問うコメントがありました
>>220。
(当然の疑問ですね。)
それに対して
spatulon
は、
2014-12-29T16:26:48
(時間帯不明)
に、
Jeff Hodges (>>176)
の2つのツイート
>>169, >>188
を示しました
>>220。
それに対してどこかの誰かがツイートしただけでは出典にはならないとする指摘
(「Not much of a source really, it's just some random dudes tweet, with no real explanation.」)
がありましたが、
dmourati (時間帯不明)
は
2014-12-29T19:40:34
に、
※ Twitter で働いていた人で、その人がツイートしている時間に問題を見つけて直した現在 Twitter で働いてる人々を引用したどこかの誰か
* Random dude who worked at twitter and cited the people currently working at twitter who found and fixed the problem during the time he tweeted it.
と嫌味ったらしく補足しました >>220。
[229] つまり Jeff Hodges は Twitter の元社員で、 障害対応中の現役 Twitter 社員のツイートも引用しているから、 信頼できる情報だといいたいようです。 (それならそのツイートも提示するべきですよね。 URL が貼られた >>169 >>188 とその返信だけを見ても、 その情報にはたどり着けません。)
[230] 現役 Twitter 写真と親しい Twitter 元社員だからといって、 そのツイートが信用できるという主張には難があります。 該当すると思しき Twitter 社員は結局最後まで原因を明言しませんでした (>>181)。 ツイートを引用された Jeff Hodges 自身も、
I'm not working at any company right now and if someone is telling you different, they don't know me very well. This is a weird tweet.
私は今はどこの会社でも働いていないので、誰かが違うことを吹き込んだとしても、その人は私のことをよく知らない人です。これはおかしなツイートですね。
と書いていました。 >>168 どのツイートを指していたのか不明ですが、 件のコメントと同じように元社員だからと不当に引用か非難でもされて困っていたのでしょう。
[231] なお、 この Hacker News 記事の投稿者および「出典」ツイートを書き込んだ人、 ツイート主が Twitter 元社員だと書いた人の3人は、 Twitter の社員や関係者である(あった)という徴証を見つけられません。
[227] この Hacker News 記事にはいろいろなプログラミング言語やライブラリーの状況が報告されています。 また Twitter とは独立に Objective-C のソフトウェアで1件、 不明な言語の製品で1件、同じ原因のトラブルが報告されています。 >>220
[113] 障害原因については、公式な発表が見つけられません。 Twitter 社員の技術者のツイート (>>152 >>141) やそれに絡んだ元社員のツイート (>>157 >>176) は示唆に富んでいるのですが、 断片的な情報しか与えてくれません。
[114] 各媒体の記事も公式発表や一般利用者の症状報告の引用などに終始しており、 独自取材で追求したものは見つけられません。 原因を断定的に述べたツイートやそれを引用したニュース記事もあります (>>44 >>31 >>93) が、 断定した根拠が明らかではなく、 そのまま信用することはできません。
[184] それ故に推測を重ねることにはなりますが、 どのようなメカニズムで障害が発生したのか再検討してみます。
といった症状が報告されています。 >>116, >>117, >>118 は一般の利用者から見てわかりやすい症状で、 >>119 は証拠となるスクリーンショットが現存しますから、 一応これらは信用して良いと思われます。
[125] まず、これらの現象がいずれも一部のクライアントのみで確認されていることから、 Twitter のシステムの一部分でのみ発生していたことがわかります。 また HTTPヘッダーで不具合が確認されていることからクライアント側ではなく Twitter のサーバーに主要因がある可能性が高く、 しかも一部のHTTPヘッダーでのみ起こっていることから、 サーバープログラムの一部の処理にのみ不具合があることがわかります。
[120] HTTPヘッダーについて、 年が1年進んでいて曜日が進んでいないことから、 時計は狂っておらず、 現在時刻から年を得る処理に問題があったと断定して良いでしょう。
[121] 年を誤った理由については、 UTC でちょうど ISO週暦における週年が切り替わったタイミングで障害が発生していることから、 暦年と週年を取り違えた説は有力といえます。 社員の意味深なツイートから、 その点に不具合があったことは断定して良いでしょう。 他にも複合的な要因はあったかもしれません。
[122] 当時から現在まで、有名なライブラリー等にそのような不具合が混入していたという情報は見つけられません。 従って当該 HTTPヘッダーの生成は Twitter 社内の独自の実装によるものだった可能性が高いです。 なぜ HTTPの日時形式の文字列の生成のようなありふれた (しかし罠もある) プロトコル処理を実績のある汎用のライブラリーに委ねず独自処理としていたのかは謎です。 技術的水準の不十分なプログラマーがプロトコル仕様やプログラミング言語の仕様を十分理解しないまま、 見よう見まねで書いたコードという可能性も否定できません。 そうだとすると、 プロトコル仕様に合致しない構文で出力されていたこと (>>8) も納得できます。
[123] ambtime が誤った理由について、当該表示が Twitter サーバー側で生成されたものか、 クライアント側で生成されたものかは不明です。 ambtime は現在日時と投稿日時等との差を求めているものですから、 その現在日時が1年ずれていると、報告されているような表示になります。 クライアントが独自に現在日時を求めているとすると、 現在日時の元となるのはクライアント動作環境のシステム時計でしょうから (受信したHTTPヘッダーを使う合理的理由は考えつきません)、 仮にそれで1年前と表示されたならクライアントもたまたまサーバーと同じ不具合を抱えていたことになり不自然です (特に報告は見つけられませんが、 Twitter サーバー側の修正と同時に復旧したとみるべきでしょう)。 ということはサーバー側で生成された値を表示していた蓋然性が高いといえます。
[124]
ambtime がサーバー側で生成されたとすると、
その生成時に Date:
用の日付と同じ方法で得た年が使われたことになります。
[126]
ログインの失敗については詳細が明らかではありませんが、
もし「ログインそれ自体は成功したにも関わらず、
それ以後にログイン状態にならない」
という状態だったとすると、
既存のログイン状態が失われたという報告とも整合します。
どちらの場合も、
比較に Date:
用の日付と同じ方法で得た年が使われたため、
有効期限を1年近く超過したと判断され、
ログイン状態とみなされなかったとすれば、
こうした現象を説明できます。
あるいは新規ログインについては、 OAuth 1.0
の oauth_timestamp
の検査で失敗した可能性もあります。
[128] ambtime もログインも、これらの説が正しいと仮定すると、 現在日時と他の日時の差を求めた結果が実際より1年大きくなっていたことになります。 一般的にはまず日時データ型または整数時刻系の値で差を求めるように思われますから、 (計算結果に時間長の年が現れたとしても) 計算中に暦年 (のつもりの週年) が現れるのは不自然に感じられます。
[316]
サーバーから受信した Date:
ヘッダーを現在時刻として利用していたクライアントで障害が発生したとする説
(>>259) もあります。
一方でシステム時刻を変更すると挙動が変化したとする報告 (>>254)
もあって、簡単に説明できるものではなさそうです。
[130] この辺はもう少し詳細な実装状況がわからないことには何とも言えそうにないですね。 (そしてそれが明らかになることはおそらくないでしょう。) ただ暦年と週年を取り違えるような洗練されていない実装なら、 こうした処理も見通しの悪いコードにだったかもしれません。 正常なヘッダーと異常なヘッダーが混在していた (>>6) のも、コードの品質の傍証となるかもしれません。
[131]
以上をまとめると、暦年と週年の取り違えが障害の要因だった可能性は高いのですが、
それだけとは断定はできません。
ましてや1行 (YYYY
と yyyy
)
や1文字 (G
と Y
)
の誤りだけで発生したと断言できる材料はありません
(その可能性がないともいえませんが)。
[195] Tatsuhiko Miyagawa は自身の Podcast (配信ラジオ番組) Rebuild で付で Naoki Hiroshima と Kazuho Okui をゲストに >>234、 付で higepon をゲストに >>192、 Twitter の障害を紹介しました。
[197] Tatsuhiko Miyagawa は日本で知名度のある Web 系の技術者で、 Rebuild でも他の有名技術者等を招いていました。 業界内では注目されている番組だったと思われます。 自身は米国スタートアップ企業等を転々としており、 本段落執筆 () 時点の Twitter プロフィールによれば 9社目に在籍しているようです >>191。
[196]
Tatsuhiko Miyagawa
は末の障害当時に
Twitter
元社員の
mark mcbride (>>157)
の障害関係のツイートに対して、
GitHub で %G
を検索した結果の URL と顔文字だけの返信を投稿していました。
当該返信ツイートは
mark mcbride
も RT
していましたが、
両者に親交があったのかは不明です。
>>191
[236] の Tatsuhiko Miyagawa によれば、 次のようなことがありました。 >>234
Date:
ヘッダーがになっていた。
曜日がとは違っていた。Date:
ヘッダーを使っている。%Y
と書くべきところを %G
としていた。yyyy
と書くべきところを YYYY
。NSDate
にも同じ問題がある。[255] の配信 Webページのリンク集では、 当時のニュースサイトの記事 (>>21, >>223) と英語版 Wikipedia の記事 ISO week date が紹介されました >>234。
[193]
障害当時のツイートによれば、
Tatsuhiko Miyagawa
が独自に Date:
ヘッダーの誤りを発見していたのは事実のようです
>>252。
[256]
そしてそれは Twitter が C の %G
を誤用したことに起因し、
Android クライアントの独自の時刻補正処理のために障害につながったのだといいます。
その根拠は Twitter 社員から得た情報にあるようですが、
会話という性質上、どこからどこまでが Twitter 社員から知らされたのかは不明瞭です。
しかし確定した情報として断定的に語られています。
[257]
Twitter 社員から情報を得たというのが、どのような経路なのかも明かされていません。
現在発見されている社員のツイートには %G
の影響をほのめかすものはありますが、断定的に発表したものはありませんし、
Android クライアントの構造に関する情報も見つけられません。
公開されていない媒体での私的な交友関係で得た情報なのでしょうか。
障害対応に当たった社員と親交があるように見える元社員らも掴んでいなかった情報を得られるルートを持っていたのでしょうか。
[259] Android クライアントの障害発生のメカニズムは、 なるほどあり得なくはないと思えますが、 情報の出所が不明なままではそのまま信用するのは躊躇されます。 Android 版 Twitter アプリ以外のクライアントの現象にも言及がありません。 他のクライアントも同じように実装していたのでしょうか。 それとも別のメカニズムで発生したのでしょうか。
[198] のゲストの higepon (Taro Minowa Higepon) は、 当時 Twitter 社員でしたが >>194, >>192、 本件はまったく記憶にないといい、 完全に聞き手に回っていました。 話の中で思い出した様子もなく、隠しているようにも思えないので、 まったく関係ない部門に従事していたのでしょうか。 (当時の当該時間帯にはまったく無関係のツイートしかありません。)
[200] の Tatsuhiko Miyagawa によれば、 次のようなことがありました。 >>192
%Y
が今の年、 %G
がその週の月曜日の年を返す。%G
を使っていたので
になっているのに
のままになった。[209] の配信 Webページのリンク集では、 当時のニュースサイトの記事 >>30 が紹介されました >>193。 その記事は、本編で語られた初ではなく、 末の出来事を報じたものでした。
[208] 当時の本人のツイート (>>252) もリンクされた記事も末、 しかも前回紹介したはその直後ですから、 今回で語られたものは誤解 (記憶の劣化) と考えるのが妥当でしょう。 何も見ないで話の流れで喋っているようですから、そういうこともあるでしょう。 しかしリンクを Webページに掲載した時点で事実関係を誤っていると気づいたはずなのに、 何の注記もしていないのは、不親切、不誠実ではないでしょうか。
[210] の本編で語られた内容には多くの問題があります。
%G
や YYYY
が表すのは週年であって、
「その週の月曜日の年」ではありません。
週年は「その週の日曜日の暦年」になることだってあります。[222] >>217、>>218 は Apple の Do Not Disturb の不具合との混同が疑われます (そうだとしても少し違っているのですが)。
[260]
、
ブログで
Objective-C
における
YYYY
と yyyy
の違いを解説した日本語のブログ記事が公開されました。
>>233
はてなブックマークによるとこの記事は多くの人の目に留まったようです。
[261] このブログ記事は、 の Tatsuhiko Miyagawa の Podcast (>>236) を聴いたことを契機に執筆されたものだといい、 そこで紹介された事実をベースに話が進められます。 >>233
yyyy
ではなく YYYY
を使ったためである。NSDateFormatter
でも
yyyy
と YYYY
は件の挙動を示す。[270] そしてブログ記事は当時のニュースサイトの記事 (>>21, >>223) にもリンクしていました。 >>233 これらは Podcast の配信ページからリンクされていたものと同じです。 ブログ記事はリンクしているだけで、内容には言及していません。
[271]
このブログ記事のうち、 Twitter が YYYY
を使ったため障害に発展したという記述は、
引用元のはずの Podcast にも、
リンクされている他のニュースサイトの記事にもありません。
ブログ記事の著者の誤読でしょうか。
[272] Objective-C の挙動について Apple の公式の Cocoa ドキュメントを調べているのは立派な点です。 (まあ当然やるべきことなのですが、他の記事がちゃんとやっていないことなので。) ブログ記事が 「Unicode のフォーマット」 と呼んでいる >>233 のは、 ドキュメントが 「the format patterns from the Unicode Technical Standard #35」 と書いているものですね。 >>266, >>273
[274]
Apple のドキュメントとブログ記事が参照している
UTS #35 (LDML)
によると、
Y
は
「ISO year-week calendar as defined by ISO 8601」
における年を表します。
(厳密に言えばグレゴリオ暦以外も想定されているのですが、今回の件には関係してきません。)
>>269
Unicode も ISO 8601 を採用しているというのはこういうことです。
Apple のドキュメントも、
「the year (of “Week of Year”), used in the ISO year-week calendar」
だと明記しています。
>>266
[277] ブログ記事が Objective-C では ISO ではなく Unicode のフォーマットが採用されているのに、 Unicode のフォーマットは ISO 8601 を採用してるじゃん、 と言っているのは、これだけ読んでも意味がわかりませんが、 Podcast が雑に「ISO」と呼んでいる (>>215) せいでブログ記事の著者が混乱させられたのでしょう。
[275] 他の記事が「ISO」とだけ言って曖昧に済ませているところを、 「ISO 8601」ともう少し正確に書き表したのはこのブログ記事の優れているところです。 LDML と Apple がそうしているように、 「ISO 8601 の週年」ともう一言まできっちり書いておけばなお良かったのですが。
[278]
には、
Swift (が使う Foundation の DateFormatter
)
で YYYY
と書くとがと出力されることに注意喚起する記事が投稿されました。
>>276
[283] この記事は
先々週Rebuild.fmを聞いていたところ、以前TwitterのAndroidアプリがこの設定ミスによって5時間使えなくなっていた話をしていました。
と書いており、2回目の方の Podcast (>>210) がきっかけになって執筆されたようです。 >>276 しかもこの記事は本文中で特に言及なく当時のニュース記事 >>30 にリンクしていますが、 Podcast の配信ページからリンクされているのと同じ記事です。
[279] Objective-C も Swift もどちらも結局利用しているのは Apple 製の同じライブラリーです。ということでこの記事も以前のブログ記事 >>233 を紹介し、それと同じ問題だと言っていました。
[284] この記事はこの挙動を
これ自体はSwift関係なくISOの仕様です。
と書いています。 >>233 Podcast を踏襲して「ISOの仕様」と曖昧で不適切な表現を使っています (>>215)。 より正確な記載のある Apple のドキュメント >>266 や Objective-C の挙動を紹介したブログ記事 (>>275) にリンクしているにも関わらずです。 (ブログ記事の方では ISO ではなく Unicode のフォーマットだと明記しているのにです。) さすがに読んでもいないページにリンクしているとは思えないのですが・・・。
[281] この記事の著者は気づいていないようですが、 この記事とこの記事が参照している同内容の英語記事 >>280 の指摘する問題は、週初の違いが絡んだもう1段階複雑な事案です (>>282)。
[285]
そして LDML の Y
の説明は、よく読むとこうあります。
>>269
This year designation is used in ISO year-week calendar as defined by ISO 8601,
ISO 8601 週暦で使われると書いていますが、
Y
が ISO 8601 週年だとは書いていません。
細かい点ですが、この違いは重要です。
[286] ISO週は月曜日が週初となる週です。 この記事が扱っているのは
日曜始まりのLocaleでは2017年12月31日は2018年の最初の週にあたるため、2018と表示されてしまいます。
ということで >>276、
はじめからISO週ではないのです。
従ってこの記事の範囲では YYYY
は「ISOの仕様」にかすってもいません。
「LDML の仕様」
「LDML を採用した Foundation の仕様」
というべきものです。
[290] 誰もが口を揃えて言うように、日時処理は難しいです。 あちこちに罠があります。 だから知見を共有し啓蒙する活動は重要で、貴重です。 そして誰にでも間違いはあります。 ですからもし仮に間違った解説を公表してしまったとしても、 そのこと自体は決して責められるべきではないでしょう。 それもまた避けがたいことではあるのです。
[291] しかし出所不明の怪情報を垂れ流したり、 事情を調べもしない(調べる気もない)のにただ非難するだけ、 といったものは話が別です。 影響力が強い人の情報発信なら尚のことです。 ただでさえ複雑な問題に、 どうしてそんな非生産的なことをしてくれるのでしょうか。
[282] にも週年と暦年の混同による不具合が注意喚起されました。 >>280, >>293, >>276 今次は大規模な障害は報告されていませんが、 例年のように小規模な不具合はあちこちで発生していたのではないかと予想されます。
[294] 今次が例年と異なるのは、 とが日曜日と月曜日だったことです。 従って週初を月曜日とする場合 (ISO週) には問題は露呈せず、 週初を日曜日とする場合やロケール依存とする場合に異状が発生します。
[295]
週年と暦年を混同したのが不具合の根本原因には違いありませんので、
暦年を意図していたなら暦年を表す機能を使うべき
(%G
ではなく %Y
、 YYYY
ではなく yyyy
)
という修正法も同じです。
しかしこの頃書かれた解説には若干の混乱が見られますから、要注意です。
YYYY
ではなく yyyy
を使うべきと説明しました >>280。
「週」の説明には読者から指摘が入り >>293、
ロケールに依存すると補足が入りました >>280。