Explanation of Date object and timezones please

I've read the Date struct docs but not sure I understand. It says that it's a specific time independent of a timezone.
However when I take a Date() instance, and format it with the DateFormatter.timeZone as UTC the resultant date I get is the same exact date as print(Date()).
Does this mean that a Date() instance is always UTC even though the docs say there is no timezone association?

https://developer.apple.com/documentation/foundation/date

A Date value is a timestamp, and timestamps count the number of seconds from January 1, 1970 (edit: brain fart) January 1, 2001 in the UTC timezone.

This, fundamentally, is the only thing a Date is: a number of seconds.

If you want to interpret that value relative to a calendaring system (like the Gregorian or Islamic or Buddhist etc calendars), you'll need a Calendar value for extracting "components" (component = numeric calendrical value. For example, the current "month" component on the Gregorian calendar is 11, which we interpret as "November").

If you want to "render" a Date into some text to show the user, then you use a DateFormatter, which gets configured with a Calendar and TimeZone (defaulting to the machine's current values for those types) and a style for rendering the date and time portions of the timestamp.

I'd suggest avoiding printing a Date directly, since that ends up relying on its description value and it can lead to some false assumptions about the value. Basically, I would recommend always using a DateFormatter (and similarly-based formatting APIs) for getting a "human readable" version of a Date.

9 Likes

To add, I think a lot of the confusion stems from the implementation of Date.description (as used by print, for example) and how it “maintains the illusion”.

It won’t print the raw Double value (num seconds since the reference date), it’ll instead format to your local timezone. Convenient, but can confuse beginners.

5 Likes

UTC is not just an "ordinary" timezone: Usually, timezones are defined by their offset to UTC, which is basically world time.
When you create an instance with Date(), this will always be the current time in UTC, no matter where you are, and when you instantiate it with a year, month, day etc and a timezone, all that is converted to UTC.

1 Like

Another way to think about it is that Date is the "time" version of latitude and longitude.

Latitude and longitude can get you to the exact right spot on the globe, but they won't tell you what the name of the street there is; you need a geographic map to do that.

A Date can get you to the exact right spot in time, but it won't tell you what the name of year/month/day/hour/minute/second it is then; you need a temporal map to do that: that's Calendar.

12 Likes

I am pretty sure Date’s epoch is the instant UTC reached A.D. 2001.

(I also suspect the number of seconds is measured in UT1, not UTC, although the documentation does not specify and it has been a while since I have worked on anything where the difference mattered.)

1 Like

it’ll instead format to your local timezone.

It stopped doing that a while back (r. 7094236). Starting with Apple’s 2010 OS releases, this code:

import Foundation

print(TimeZone.current)
print(Date())

prints this [1]:

America/Los_Angeles (current)
2021-11-02 09:33:24 +0000

While there’s still a lot of confusion about Date, we have at least fix this specific issue (unless you happen to be in GMT).

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

[1] And I just tested this with a command-line tool target built using Xcode 13.1 on macOS 11.6 with System Preferences > Date & Time > Time Zone set to Cupertino.

4 Likes

:man_facepalming: ugh silly mistake. You're absolutely right. Thanks for the correction.