Open3

SwiftのDateについて

Shun UematsuShun Uematsu

Date

SwiftのDate型は、タイムゾーンやカレンダーから独立しており絶対時点を表している型です。
そして絶対時点はUTC(協定世界時)になります。
なのでprint(Date())で出力される値は、タイムゾーンがAsia/TokyoでもAmerica/New_Yorkでも常に同じになります。
実際にタイムゾーンをAmerica/New_Yorkに変更して以下を実行した場合、以下のようになりました。

import Foundation
// 日本時刻 2021-05-28 09:06:20 に実行した場合.
// このときのニューヨーク時刻は2021-05-27 20:06:20.
print(TimeZone.current) // America/New_York (current)
print(Date()) // 2021-05-28 00:06:20 +0000
Shun UematsuShun Uematsu

Calendar

Dateは絶対時点を表していることは分かりました、絶対があるということは相対もあるはずです。
では相対は何かというとタイムゾーンを考慮した時刻になります。
リファレンスには以下のように記載されています。

A definition of the relationships between calendar units (such as eras, years, and weekdays) and absolute points in time

つまり協定世界時を基準とし、そこからどのくらい時間が離れているのかを表すものになります。
また現実世界におけるカレンダーは当然国によって使われるものは異なります。日本のカレンダーをアメリカに持っていってもそれを見ただけでは使い物になりません。(タイムゾーンによる時差を計算したり、和暦は日本以外では通用しないので。)このように現実世界のカレンダーもタイムゾーンやロケールに依存しています。
Swiftの世界のカレンダーもこれと同様の考えになります。つまりCalendar型もタイムゾーンやロケールなどが考慮された情報です。

例えば以下のようなコードだと、タイムゾーンが考慮された値が出力されます。

import Foundation

let now = Date()
let calendar = Calendar.current
let components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: now)
print(now) // 2021-05-28 00:40:31 +0000
print(TimeZone.current) // America/New_York (current)
print(components) // year: 2021 month: 5 day: 27 hour: 20 minute: 40 second: 31 isLeapMonth: false 
Shun UematsuShun Uematsu

DateComponents

DateComponentsは名前の通り日付を構成する要素を表したものであり、そしてカレンダー(タイムゾーン)が考慮されたものです。