GMT, UTC, JST, エポック秒, UNIX時間, ISO8601,タイムゾーンなどの日付に関する概念を理解する
GMT
や UTC
など、なんとなくわかっているけど説明ができない「時間」に関する用語を理解したいと思い、調べてみました。
GMT(Greenwich Mean Time)
世界で時刻の基準を作る際に採用されていた時間。
日本では グリニッジ標準時(ぐりにっじひょうじゅんじ) 、または グリニッジ平均時(ぐりにっちへいきんじ) と呼ぶ。
経度0度(本初子午線)の位置にあるロンドンのグリニッチ天文台で恒星や日周運動に基づいて計算した時刻。
15度ごとに1時間ずれていて、日本は135度ずれているので9時間進んでいる事になる。
1884年に決められたもので、それまでは各国がバラバラな時刻を採用していたらしい。
その後、天体から計算すると自転速度の変化などによりズレが生じるため、後述のUTCが1982年に国際的な定義になった。
UTC(Coordinated Universal Time)
1982年から GMT に変わり採用されたもの。
今の世界で標準時として使われている時間。
日本では 協定世界時(きょうていせかいじ) と呼ぶ。
頭文字的には CUT だが、すでにあるものと被るので UTC と決めたとのこと。
UTC は天体ではなくセシウム原子時計というのが使われてズレが少ないらしい。
GMT を継承して作られた天体をもとにする世界時(UT)との誤差を1秒以内に保つため、閏秒を足したり削除したり調整をしている。
結果的には、GMT と同じ時刻を指しているので、プログラミングの分野ではイコールと思っても差し支えないとのこと。(多少の誤差はあるので、時計関係などの分野では厳密には違う扱いなのかも)
JST(Japan Standard Time)
UTC に9時間足した時間を指す日本の標準時で、UTC+9
や UTC+09:00
などと表す。(GMT+9
とされることもあるが同じものを差していると思って差し支えない)
日本では 日本標準時(にほんひょうじゅんじ) と呼ぶ。
日本で使っている時間は法律上は中央標準時と呼んでいるらしいが、これは本初子午線から東に135度の角度を指しているものなので同じ時間を差している。
UTC とは9時間の差があるので、例えば UTC の 10:00 は JST で 19:00 となる。
JST 以外にも、同じ UTC+9 は韓国の KST やインドネシアの WIT などがある。
他にも有名なものだと AST (Atlantic Standard Time、大西洋標準時)などがあり、これは UTC から西側に60度の角度を指す UTC-4
で、 UTC から4時間遅い。
UNIX時間(UNIX Time、エポック秒)
UTC の 1970年1月1日 0時0分0秒 から経過した秒数を指すコンピュータシステム上での時刻表現の一種。エポック秒(epoch seconds) とも呼ぶ。
また、この基準の時間のことを UNIXエポック(UNIX Epoch) と呼ぶ。
試しにこの記事を書いている2022年12月18日1時24分38秒に取得してみたら 1671294278
となった。つまり、1970年からこれだけの秒数がたったということ。
エポック秒は10桁だが、ミリ秒を足した エポックミリ秒(epoch milliseconds) もあり、その場合下3桁が足されて13桁になる(1671294278000
みたいな感じ)
ちなみに、エポック(epoch)は「新たな時代の始まり」や「紀元」という意味があるので、新たに定められた基準からの時間という意味で覚えると分かりやすそう。
js の場合、Date.prototype.getTime() や Date.now() で取得できる
const now = new Date('2022-01-01'); // 特定の日付のDateオブジェクトを作る
const epochMilliseconds = now.getTime(); // UNIXエポックからDateオブジェクトの日付までに経過したミリ秒を返す
const epochSeconds = Math.floor(epochMilliseconds / 1000); // ミリ秒を削って秒数に直す
const epochMilliseconds = Data.now(); // UNIXエポックから "今" まで経過したミリ秒を返す
const epochSeconds = Math.floor(epochMilliseconds / 1000); // ミリ秒を削って秒数に
ISO8601
日付と時刻を表記する国際規格。(日付のフォーマットのルール)
読み方は日本だと アイエスオー が多いらしいが、公式だと アイソ(Eye-so) らしい。
基本的な構造は 日付 + T + 時刻 + タイムゾーン
という形式。
UTC の場合は末尾に Z
が来て、それ以外のタイムゾーンの場合は +
または -
の後ろに時間が追加される。
基本形式と拡張形式の2種類あり、基本形式は YYYYMMDDThhmmss+0900
、拡張形式は視認性を上げるためにハイフンやコロンなどの区切り文字が入った YYYY-MM-DDThh:mm:ss+09:00
となる。
どちらでも問題ないが混在するのは良くないので、統一して使う必要があるとのこと。
プログラミング周りだと拡張形式が多いらしいので、多分基本こっちで良さそう。
// UTCの拡張形式
2022-12-15T06:12:47Z
// JSTの拡張形式
2022-12-15T06:12:47+09:00
js だと日付からこの形式のフォーマットを返す Date.prototype.toISOString() がある
このメソッドの場合、拡張形式でミリ秒も含まれるので YYYY-MM-DDThh:mm:ss.sss+09:00
ということになる。
基本のルールがこれなだけで、上記みたいにミリ秒を足したり、タイムゾーンの分の部分を削ったりと細かい違いはあるっぽい。
タイムゾーン(time zone)
同じ標準時を使う地域全体のこと。
日本だと 時間帯(じかんたい) や 標準時間帯(標準時間帯) 、 等時帯(とうじたい) と呼ぶらしい。
日本は UTC+9
なので、同じ時間帯の国は韓国、北朝鮮、インドネシア(東部)、パラオ、東ティモール、ロシアなどがある。
プログラミングだと Asia/Tokyo
とか America/New_York
とかが出てくるので、これらがどういうものなのかも調べた。
これは IANA(Internet Assigned Numbers Authority、アイアナ) が管理している Time Zone Database(tz database) と呼ばれるデータに含まれる、タイムゾーンの統一的命名規則とのことらしい。
この命名規則は人間が理解しやすいようにするため、 地域/地名
形式の固有の名称になっている。名称の句読点や共通の接尾辞は省かれ、アンダースコアはスペースの代わりに利用される。地名部分におけるハイフンはそのまま用いられる。( America/New_York
など)
データは Time Zone Database というサイトに圧縮されて置いてある。
ちなみに IANA とは、インターネットに関連する識別子(ドメイン名、IPアドレス、プロトコル番号など)を管理する団体の名前。
今は ICANN(The Internet Corporation for Assigned Names and Numbers、アイキャン) が設立されて、IANA が管理していた役割の一部を引き継いだが、歴史的経緯からインターネットの資源を管理する機能を表す意味として IANA と呼ぶらしい。
タイムスタンプ
ある 出来事が発生した日時、日付、時刻などを示す文字列
古くは手紙に押された物理的なスタンプが元だったらしいが、今ではコンピュータ上で日付を保存するときに用いられる。
プログラム上で明確に生成したりする場合もあれば、ファイルシステムにおいて、ファイルの作成、更新時などに自動で付与される日付を指す場合もある。
調べてて思ったけど、同じプログラミングと言っても分野によって、それぞれ違うニュアンスで使われていたりして、自分の関わってきた経歴によって「タイムスタンプ」という言葉のニュアンスが違うことがある気がした。
僕もあんまり多くの技術に触れていた訳ではないのでイメージですが...
DB
- 明確に
TIMESTAMP型
がある - 形式は
YYYY-MM-DD hh:mm:ss
とか - DB を良く触る人はタイムスタンプをその瞬間の時間プラスこの形式の意味も含めてで言うことがありそう
- 過去にDBの関係ないところで「日付はタイムスタンプ型で〜」と言われたことがあって、どういう形式だ?ってなったことがあったので
js
-
Date.prototype.getTime()
やDate.now()
で取得できるUNIX時間を指す - タイムスタンプにはフォーマットのニュアンスは含まれなそう(単純にその瞬間の時間)
- 実際に使うときはこの値を ISO8601 とかでフォーマットしたりして使う(用途に合わせて形は違う)
Firebase
- Firestore のフィールドに
timestamp型
がある - 管理画面の表示上は ISO8601 でフォーマットされた
2022年12月18日 0:00:00 UTC+9
のように表示されているが、実態はUNIX時間なので、プログラムで取得すると10桁の数値になる -
firebase.firestore.FieldValue.serverTimestamp()
やfirebase.firestore.Timestamp.now()
で返される値はUNIX時間なので、それを指す? - 実際に使うときは何かしらのライブラリを挟んで扱いやすい形に変換するはず
多分、他の言語とか分野でもそれぞれに「タイムスタンプ」というものがあって、フォーマットまで含むニュアンスがあったり、単純にUNIX時間だったりと、ニュアンスが違うことが多くありそう。
どの分野でも通じる意味としては、 出来事が発生した日時、日付、時刻などを示す文字列 というところ。
文脈によって何を指すかが変わりそうなので適宜確認するのが良さそう。
サマータイム
明るい時間を有効活用するために、春〜夏で時計を1時間進めて、秋〜冬でそれを戻すような時間制度。DST(daylight saving time)と呼ぶらしい。
アメリカ合衆国、ヨーロッパ、オーストラリアなどで行われていて、例えばアメリカであれば3月の第2日曜の2時に1時間ずらし、11月の第1日曜2時に1時間戻すらしい。
まだやった自分は経験はないけど、サマータイムを考慮すると気をつけないといけないことがたくさんありそう
まとめ
概念はわかった気がしたけど、実際にプログラムを組むときにどう考慮すればいいのかはまた今度調べることにします。
たくさんの記事に感謝します!
参考URL
Discussion