ソフトウェアにおける日本時間のズレ
日本時間(JST)の時差は世界標準時(UTC)+9時間である。日本は国内時差は無いしサマータイムも採用していないので、それだけ覚えておけば大丈夫。
と思っていたのだが、この度そうでないことを知った。切っ掛けはWindowsのASPで動くバックエンドとChromeブラウザ間でUNIX時刻でやり取りをしていたとき。明治生まれの人の誕生日が微妙にずれる時があるのだ。
日本時間のブレ
調べた結果、日本時間は次の2パターンで+9時間でない場合がある。
1)~1888年
今の日本標準時が設定されたのがこの年(明治21年)だそうだ。ということはこれより前は日本時間自体が存在しないわけだが、システムによっては+9時間18分が採用されている。
2)1949年~1951年の夏
この時期は日本でもサマータイムが導入されていたらしい。なのでこの年の夏季はUNIX時刻も1時間ずれる。
環境による違い
例えばChromeブラウザでJavascriptを動かすと、上記の通りの結果が返ってる。
> new Date(1887, 0, 1, 0, 0, 0)
Sat Jan 01 1887 00:00:00 GMT+0918 (日本標準時)
> new Date(1950, 7, 1, 0, 0, 0)
Tue Aug 01 1950 00:00:00 GMT+1000 (日本標準時)
それぞれ+9時間18分、+10時間のタイムゾーンになっている。
今度はWindows PowerShellでやってみる。
> ((Date "1887/1/1") - (Date "1887/1/1" -AsUTC)).ToString()
09:00:00
> ((Date "1950/8/1") - (Date "1950/8/1" -AsUTC)).ToString()
09:00:00
両方ともUTCとの時間差は+9時間となっている。
ChromeブラウザやLinuxなどはタイムゾーンの設定をパブリックなデータベースの「tz database」から取得している。一方でWindowsの場合はMicrosoftが管理する時差データを使っている。Microsoftのデータベースでは上記2ケースの例外は考慮していないようだ。
各ミドルウェアやフレームワークがどうしているはそれぞれのようだ。ものよってはUNIX時刻0(=UTC 1970/1/1 00:00)より前の日時は無保証としているものもある。
.Net Core などはOSからタイムゾーン情報を取得しているため、同じプログラムでも実行時の環境によって差が出る。以下は.Net Core3.1で作成したテストプログラムとその実行結果だ。共にOSのタイムゾーン設定はAsia/Tokyoである。
using System;
using System.Diagnostics;
class Program
{
static void Main(string[] args) {
var today = DateTime.Today;
WriteDate(today.Year, today.Month, today.Day);
WriteDate(1868, 1, 1);
WriteDate(1888, 1, 1);
WriteDate(1950, 8, 3);
}
static void WriteDate(int y, int m, int d) {
var jd = new DateTime(y, m, d, 0, 0, 0, DateTimeKind.Local);
var ud = jd.ToUniversalTime();
var diff = new DateTime(jd.Year, jd.Month, jd.Day, jd.Hour, jd.Minute, jd.Second, DateTimeKind.Utc) - ud;
Console.WriteLine($"JST:{jd:yyyy/MM/dd HH:mm:ss} UTC:{ud:yyyy/MM/dd HH:mm:ss} ({diff})");
}
}
実行結果(RedHat)
JST:2022/11/20 00:00:00 UTC:2022/11/19 15:00:00 (09:00:00)
JST:1868/01/01 00:00:00 UTC:1867/12/31 14:42:00 (09:18:00)
JST:1888/01/01 00:00:00 UTC:1887/12/31 14:42:00 (09:18:00)
JST:1950/08/03 00:00:00 UTC:1950/08/02 14:00:00 (10:00:00)
実行結果(Windows)
JST:2022/11/20 00:00:00 UTC:2022/11/19 15:00:00 (09:00:00)
JST:1868/01/01 00:00:00 UTC:1867/12/31 15:00:00 (09:00:00)
JST:1888/01/01 00:00:00 UTC:1887/12/31 15:00:00 (09:00:00)
JST:1950/08/03 00:00:00 UTC:1950/08/02 15:00:00 (09:00:00)
というわけで開発機(Windows)と運用環境(Linux)で差が出てしまったという話。
コメント
コメントを投稿