アプリで現在時刻を表示する際、「JST(日本標準時)」や「EST(東部標準時)」といったタイムゾーンの短縮名(Abbreviation)を使うことが多いと思います。しかし、実はこれらの短縮名には、世界的に統一された単一の厳密な規格が存在しません。
極端な話、各地域やコミュニティが慣習的に使っているだけの名前であり、重複すら存在します。例えば「CST」という全く同じ短縮名であっても、実際には以下のように複数の異なる地域の時間帯(と、その英語の正式名称)を指す可能性があります。
- 米国中部標準時(Central Standard Time:UTC-6)
- 中国標準時(China Standard Time:UTC+8)
- キューバ標準時(Cuba Standard Time:UTC-5)
このように、時差が全く異なる地域であっても、頭文字を取るとすべて「CST」としてシステム上で衝突してしまうわけです。
近年のライブラリの動向:短縮名からオフセット表示へ
こうした名前の曖昧さもあり、最近のプログラミング言語や標準ライブラリでは、短縮名を取得しようとしても「GMT+9」や「UTC-05:00」のような、単なる時差(オフセット)が返されることが主流になってきています(フォーマットの指定やライブラリによって形式は異なります)。
例えば、JavaScriptの標準機能である Intl.DateTimeFormat を使って、短いタイムゾーン名(timeZoneName: 'short')を取得するコードを見てみましょう。
// 指定したタイムゾーンの短い名前を取得するヘルパー関数
function getShortTzName(ianaTimeZone) {
const formatter = new Intl.DateTimeFormat('ja-JP', {
timeZone: ianaTimeZone,
timeZoneName: 'short'
});
const parts = formatter.formatToParts(new Date());
return parts.find(part => part.type === 'timeZoneName').value;
}
// パターン1: かつては期待通りにアルファベットの略称が返っていたケース
// (※最近のブラウザでは、東京を指定しても "GMT+9" が返る環境が増えています)
console.log(getShortTzName('Asia/Tokyo'));
// 出力例: "JST" または "GMT+9"
// パターン2: 略称ではなく、GMTオフセットが返ってしまうケース
console.log(getShortTzName('Asia/Dubai'));
// 出力: "GMT+4" (本来なら "GST" などを期待したいところ)
このように、まったく同じ設定(言語やフォーマット指定)で呼び出しているにもかかわらず、指定する都市(タイムゾーン)によって「JST」のような見慣れた略称が返ってくることもあれば、「GMT+4」のように単なる時差が返ってくることもあります。
※追記: 以前はどんなロケールでも Asia/Tokyo を指定すれば「JST」が取得できていた気がするのですが、最近のブラウザでは、より厳密な表示を優先してか、東京でも「GMT+9」と返されるケースが目立つようになってきました。もはや標準機能だけでアルファベットの略称を安定して得ることは、非常に困難になりつつあります。
システムとして正確性を期すためのライブラリ側の配慮(安全なフォールバック)ではあるのですが、私たち開発者からすると、ユーザーに親しみやすい「EST」や「JST」といった短縮名をアプリのUIに一貫して表示するのが、標準機能だけでは非常に困難になっているのが実情です。
なぜ「EST」などの名前だけで時間を管理できないのか?
時差計算アプリなどを開発していると、アプリ内の追加できる都市のデータベースに対して、ユーザーから「都市名だけでなく、”EST (Eastern Standard Time)” などのタイムゾーン名も登録して選べるようにしてほしい」という要望をいただくことがあります。直感的でとても自然な要望ですよね。
技術的には「EST」を単なる固定の時差(UTC-5)としてデータベースに登録すること自体は可能です。しかし、世界時計のような「特定の場所の正確な時間を知る」というアプリの用途を考えると、「EST」という名前だけで時間を管理・提供するのは適切ではありません。その最大の理由は「サマータイム(DST:Daylight Saving Time)」の存在です。
具体的な例を挙げてみましょう。アメリカのニューヨークの時間を知りたいとします。ニューヨークは冬の間は「EST(Eastern Standard Time:東部標準時)」ですが、夏になると時計の針が進み「EDT(Eastern Daylight Time:東部夏時間)」に切り替わります。
もしアプリ側がユーザーの要望通り「EST」という固定のタイムゾーンとして追加・保存してしまった場合、夏になっても「EST」のまま時差が切り替わらず、本来知りたいはずのニューヨークの現在時刻とはズレが生じてしまいます。
さらに厄介なことに、同じ「EST」という括りであっても、都市や地域によってESTとEDTをいつ切り替えるかのルールが異なったり、そもそも切り替えない地域が存在したりします。例えば、ジャマイカやパナマなどは、年間を通じてずっとUTC-5(EST)を採用し、サマータイムを導入していません。
時差計算アプリなどの主目的は、「とある場所の今の時間が、何時何分なのかを知りたい」ということですよね。しかし、「ESTとして追加する」という情報だけでは、そのユーザーが「サマータイムがあるニューヨーク」の時間を知りたいのか、「サマータイムがないジャマイカ」の時間を知りたいのかシステムには判断できません。結果として、正確な時間を提示するという主目的を果たせなくなってしまいます。
さらに踏み込むと、「過去や未来のルールの変更」という問題もあります。国や地域によっては、ある年から突然サマータイムを廃止したり、標準時のオフセット自体を変更したりすることがあります。
つまり、「特定の場所の、年間を通した正確な時間(過去から未来にわたる正確な時間)」を知りたい場合は、タイムゾーンの短縮名ではなく、必ず「America/New_York」のような都市・地域名(IANAタイムゾーンデータベース名)をベースにしなければならないのです。都市名が決まって初めて、今は夏だからEDT、冬だからEST、あるいは「この地域はずっとサマータイムがないからESTのまま」という正確な判定が可能になります。
独自の短縮名判定コードの実装例
標準ライブラリが親切な短縮名を安定して返してくれない以上、一般的に使用されているであろうタイムゾーンの短縮名を環境に依存せずに表示したい場合は、アプリ側で独自に短縮名を決定するアプローチが必要になります。
ここでは、IANAタイムゾーン名と現在のオフセット(時差)を組み合わせた「キー」を作り、そこから正確な短縮名を導き出す単純化されたJavaScriptのコード例をご紹介します。
/**
* タイムゾーン名(IANA)と現在のオフセット時間から短縮名を決定する
* ※ offsetMinutesは JavaScriptの getTimezoneOffset() の仕様に合わせ、
* UTCより進んでいる地域をマイナス、遅れている地域をプラスとしています。
*/
function getCustomTimezoneAbbr(ianaTimeZone, offsetMinutes) {
// タイムゾーン名とオフセット(分)を結合して一意のキーを作成
const key = `${ianaTimeZone}_${offsetMinutes}`;
// 独自のマッピング辞書(必要に応じて拡張します)
const abbrMap = {
'Asia/Tokyo_-540': 'JST', // UTC+9
'America/New_York_300': 'EST', // UTC-5 (冬: 標準時)
'America/New_York_240': 'EDT', // UTC-4 (夏: サマータイム)
'Europe/London_0': 'GMT', // UTC±0 (冬: 標準時)
'Europe/London_-60': 'BST' // UTC+1 (夏: サマータイム)
};
// マッピングが存在すれば短縮名を返し、なければ汎用的なGMTオフセットを返す
if (abbrMap[key]) {
return abbrMap[key];
} else {
const sign = offsetMinutes > 0 ? '-' : '+';
const hours = Math.floor(Math.abs(offsetMinutes) / 60);
return `GMT${sign}${hours.toString().padStart(2, '0')}:00`;
}
}
// 実行例(ニューヨークの冬)
console.log(getCustomTimezoneAbbr('America/New_York', 300)); // "EST"が出力される
// 実行例(ニューヨークの夏)
console.log(getCustomTimezoneAbbr('America/New_York', 240)); // "EDT"が出力される
この手法なら、同じニューヨークを指定していても「現在のオフセットが-5時間(300分)ならEST」「-4時間(240分)ならEDT」と、季節に応じて正確に短縮名を出し分けることが可能になります。
全てのタイムゾーンとオフセットの組み合わせの独自マッピング辞書を作成するのはかなり大変ですが、タイムゾーンの短縮名の世界標準の規格が決まっておらず、ライブラリが対応してくれていない以上、今のところはこの様な方法で頑張るしか無いというのが実情です。
タイムゾーンの扱いは奥が深く、ルールの変更という歴史的な背景も絡んできます。内部ではしっかり「都市(IANAタイムゾーン名)」で管理しつつ、表示層では独自のマッピングでユーザーに寄り添う、という工夫がアプリの使い勝手を大きく向上させるポイントになりそうです。