# 2018/1の事故で消失した記事を元のまま復旧させたものです
10.8になって、「自然言語による相対日付指定v13」などの高度な処理を行うカレンダー計算プログラムが正しい値を返さなくなったことに気付いていたのですが、これがあまりに巨大なプログラムなので、問題の所在がどこにあるのか調査できずにいました。
確認してみたところ、どうやらOS X 10.8のdate文に強烈なバグが存在していることが分りました。確認はOS X 10.8.3(Build 12D78)にて行っています。
スクリプト名:10.8のdateバグ |
set a to “2013年2月1日金曜日 0:00:00” set b to date a –> date “1999年12月31日金曜日 0:00:00” |
date文で曜日が書かれた日付テキストをdateオブジェクトに変換すると、すべて「1999年12月31日金曜日 0:00:00」になってしまうというものです。
さらに、AppleScriptエディタ上でdate文のあとにダイレクトに日付文字列を書いて指定し、コンパイル(構文確認)を行うとあからさまに1999年12月の日付に変わってしまいます。
▲文字入力中。このあと、コンパイル(構文確認)を実行すると……
▲1999年12月の日付に勝手に書き換えられてしまう!
念のため、手元のMac OS X 10.6.8および10.7.5の環境で同様の内容をテストしてみましたが、これらの環境では問題は発生していません。
問題の回避策は、
(1)dateに与える日付文字列に曜日を含めないこと
(2)current dateでdateオブジェクトを作成しておいて、そのyear, month, dayなどのプロパティを個別に設定して返すサブルーチンを用いること
(3)dateに与える日付文字列に日本語の文字列を含めないこと
(4)曜日の文字列だけ英語で書くこと
などが考えられます。
スクリプト名:10.8のバグの一時的な回避策1 |
set a to “2013年2月1日” –曜日を含めない set b to date a –> date “2013年2月1日金曜日 0:00:00” |
スクリプト名:10.8のバグの一時的な回避策2 |
set aDate to makeDateObj(2013, 2, 1, 0) of me –> date “2013年2月1日金曜日 0:00:00” on makeDateObj(aYear, aMonth, aDay, aTimeNum) set a to current date set year of a to (aYear as number) set month of a to (aMonth as number) set day of a to (aDay as number) set time of a to aTimeNum return a end makeDateObj |
スクリプト名:10.8のバグの一時的な回避策3 |
set a to “2013/2/1 0:00:00” –日本語の日付文字列を渡さない set b to date a –> date “2013年2月1日金曜日 0:00:00” |
スクリプト名:10.8のバグの一時的な回避策4 |
set a to “2013年2月15日Friday” –曜日だけ英語で書く set b to date a –> date “2013年2月15日金曜日 0:00:00” |
「OS X 10.8のdateに強烈なバグ」の話の続報です。
OS X 10.8になって正常に動作しなくなった「自然言語による相対日付指定v13」サブルーチンの調査中に出くわした不具合点とその回避方法について解説します。
結論からいえば、date文のトリッキーな記述を行っていた箇所があり、そこが問題になっていました。素直に書くようにすれば、機能を回復できます。
他のCJK言語環境(中国語や韓国語)においても問題が発生するのか興味深いところです。
スクリプト名:10.8でdate文のトリッキーな記述を回避する |
–10.8で問題になる書き方 set tmp4 to "2013/2/1" set ret2Date to date "0:0:0" of (date tmp4) –> date "1999年12月31日金曜日 0:00:00" –10.8で問題にならない書き方 set tmp4 to "2013/2/1" set ret2Date to date (tmp4 & " 0:0:0") –> date "2013年2月1日金曜日 0:00:00" |