---
title: "Introduction to Date and Time Programming in Swift, Part 1"
description: "Learn how to create dates and times using Swift’s powerful date and time objects."
authors:
  - name: "Joey deVilla"
    url: "https://auth0.com/blog/authors/joey-devilla/"
date: "Dec 21, 2023"
category: "Developers,Tutorial,iOS"
tags: ["mobile", "date", "time", "swift"]
url: "https://auth0.com/blog/introduction-date-time-programming-swift-1/"
---

# Introduction to Date and Time Programming in Swift, Part 1

At first glance, working with dates and times in Swift seems unnecessarily complicated. While JavaScript manages to work with the `Date` class, Swift has this collection of classes and structs:

![Chart showing the relationships between Swift’s date and time objects: Date, DateComponents, Calendar, DateFormatter, TimeZone, Locale, and String.](https://images.ctfassets.net/23aumh6u8s0i/7nd4rKcL0fjySWGO3quKdR/1aa0f8769a4e171dcace52d62b1a13f4/swift_date_and_time_objects.png)

Some developers think that Swift’s system for working with dates and times is overengineered, but that’s because [they hold mistaken beliefs about time](https://gist.github.com/timvisee/fcda9bbdff88d45cc9061606b4b923ca). Swift provides a powerful system for storing, displaying, and performing calculations on dates and times that’s flexible enough to work across date and time formats, time zones, languages, and even different calendar systems. 

For example, in a handful of lines of Swift code, you can determine the date for the third Wednesday of July at 3:30 p.m. Pacific Time and then display that date as it would appear in the Coptic calendar system in Melbourne, Australia’s time zone. In fact, the final task in this tutorial will be to write this code. (I don’t want to even _think_ about what it would take to write the equivalent code in JavaScript.)

This tutorial will introduce you to the objects that Swift provides for working with dates and times. You’ll learn how to create date/time objects in Swift, extract information from them, and display their values to your users. It’s an interactive exercise that you’ll perform in a Swift playground so that you can learn by doing.

> 👀 Look for the 🛠 emoji if you’d like to skim through the content while focusing on the build and execution steps.
> 
> 💻 You can find an Xcode playground with all the code in this article in [this GitHub repository](https://github.com/auth0-blog/swift-date-time-intro) — it’s `intro-dates-times-swift-1.playground`.


## Creating Dates: The Basics

![A number line with an arrow pointing at “0” that says “Reference Date: January 1, 2001, 00:00:00 UTC and key dates in phone and iOS history.](https://images.ctfassets.net/23aumh6u8s0i/5g1svUijxRZyydWH3U4dhE/af6d17eb9401135f5b5eaa6039a93000/dates_and_times_in_swift.png)

Swift uses the [`Date`](https://developer.apple.com/documentation/foundation/date) struct to represent dates and times. Every `Date` instance stores a [`Double`](https://developer.apple.com/documentation/swift/double) value representing seconds relative to the start of the [Third Millennium](https://en.wikipedia.org/wiki/3rd_millennium) — January 1, 2001, 00:00:00 UTC. Positive values represent dates and times _after_ this reference point, while negative values represent dates and times _before_ this reference point.


### Creating an object representing the current date and time

Let’s create a `Date` instance representing the current date and time.

🛠️ Open Xcode, start a new blank macOS playground (I find them more reliable and less crash-prone than iOS playgrounds), then add and run the following code:

```swift
import Cocoa

let momentInTime = Date()        // Current date and time
print("momentInTime contains the current date and time!")
print("• momentInTime.description: \(momentInTime.description)")
```

Here’s how the output looked on my computer when I ran it:

```
momentInTime contains the current date and time!
• momentInTime.description: 2023-12-13 16:44:32 +0000
```

`Date`’s `description` property returns the date and time value as a string specifying the date, time, and time zone stored in the `Date` instance. You’ll be running the code on a different day and time, so its output will be different. However, they’ll have the same “date-time-time zone” format. Note that the time zone is `+0000`, or 0 hours and 0 minutes apart from [Coordinated Universal Time](https://en.wikipedia.org/wiki/Coordinated_Universal_Time), or UTC for short.


### Getting the value of a `Date`

`Date` has very few properties for extracting the date and time, and the values they provide aren’t convenient:

<style>
  table {
    width: 100%;
    border-collapse: collapse;
  }
  table, td, th {
    border: 1px solid;
  }
  td {
    padding: 5px;
  }
</style>
<table>
<tr>
<th><code>Date</code> property</th>
<th>What it does</th>
</tr>
<tr>
<td><code>timeIntervalSinceNow</code></td>
<td>Returns the number of seconds between the date and time represented by the `Date` instance and the current date and time. If the `Date` instance is in the past, this is a negative number.</td>
</tr>
<tr>
<td><code>timeIntervalSinceReferenceDate</code></td>
<td>Returns the number of seconds between the date and time represented by the `Date` instance and Swift’s reference date, January 1, 2001 at 00:00:00 UTC. If the `Date` instance represents a date and time before the reference date, this is a negative number.</td>
</tr>
<tr>
<td><code>timeIntervalSince1970</code></td>
<td>Returns the number of seconds between the date and time represented by the `Date` instance and the start of the Unix epoch, January 1, 1970 at 00:00:00 UTC. Many Unix-based systems and programming languages (such as JavaScript) use this as their reference date. If the `Date` instance represents a date and time before the start of the Unix epoch, this is a negative number.</td>
</tr>
</table>

🛠️ Try them out by adding the following to the playground and running it:

```swift
let secondsAgo = -momentInTime.timeIntervalSinceNow
print("• momentInTime happened \(secondsAgo) seconds ago,")
let secondsSinceReferenceDate = momentInTime.timeIntervalSinceReferenceDate
print("• \(secondsSinceReferenceDate) seconds since January 1, 2001,")
let secondsSinceUnixEpochDate = momentInTime.timeIntervalSince1970
print("• \(secondsSinceUnixEpochDate) seconds since January 1, 1970.")
```

The output should tell you that `momentInTime` happened:

* a number of seconds since you ran the previous code snippet,
* over 724 million seconds since January 1, 2001, and
* over 1.7 billion seconds since January 1, 1970.

These values, while correct, aren’t meaningful to most people. The exercises in this tutorial will cover better ways of getting the values out of a `Date` instance.


### Getting localized strings for `Date` objects

`Date` has a `description(with:)` method that returns the date and time value as a string based on the [`Locale`](https://developer.apple.com/documentation/foundation/locale) object that you pass to it. Think of `Locale` as a way of describing the language, culture, and conventions that should be used when presenting information to the user.

🛠️ Add this code to the playground and run it:

```swift
print("Date descriptions in different locales:")
// US English
print("• en-US: \(momentInTime.description(with: Locale(identifier: "en-US")))")
// UK English
print("• en-GB: \(momentInTime.description(with: Locale(identifier: "en-GB")))")
// Spanish (general)
print("• es: \(momentInTime.description(with: Locale(identifier: "es")))")
// Simplified Chinese
print("• zh-Hans: \(momentInTime.description(with: Locale(identifier: "zh-Hans")))")
```

You’ll see `momentInTime` displayed in four locale’s languages, in the format appropriate for that locale. `description(with:)` displays a `Date` instance’s date and time using the time zone of the system it’s running on instead of UTC.

> `Locale`’s `availableIdentifiers` property contains the identifiers for all the locales supported by iOS. These identifiers are also listed in [this chart](https://woosignal.com/docs/app/ios-locale-identifiers-list).


### Creating dates and times the hard way

In addition to the default initializer, `Date` also has a set of initializers for creating dates and times by specifying the number of seconds before or after a reference date and time. They’re listed in the table below:

<table>
<tr>
<th>Initializer</th>
<th>What it does</th>
</tr>
<tr>
<td><code>Date(timeIntervalSinceNow:)</code></td>
<td>Creates a <code>Date</code> representing the date and time for the given number of seconds before or after the current date and time.</td>
</tr>
<tr>
<td><code>Date(timeIntervalSinceReferenceDate:)</code></td>
<td>Creates a <code>Date</code> representing the date and time for the given number of seconds before or after Swift’s reference date, January 1, 2001 at 00:00:00 UTC.</td>
</tr>
<tr>
<td><code>Date(timeIntervalSince1970:)</code></td>
<td>Creates a <code>Date</code> representing the date and time for the given number of seconds before or after the start of the Unix epoch, January 1, 1970 at 00:00:00 UTC. Many Unix-based systems and programming languages (such as JavaScript) use this as their reference date.</td>
</tr>
<tr>
<td><code>Date(timeInterval:since:)</code></td>
<td>This one takes _two_ arguments: a number of seconds and a `Date` instance. It creates a <code>Date</code> representing the date and time for the given number of seconds before or after the date and time represented by the given `Date` instance.</td>
</tr>
</table>

Let’s use these initializers to create `Date` objects for the following events:

* 5 seconds in the past
* 8 minutes in the future
* The start of Steve Jobs’ keynote (“Stevenote”) where he introduced the first iPhone: January 9, 2007 at 10:00 a.m. Pacific Standard Time (UTC-8)
* The start of [Steve Jobs’](https://en.wikipedia.org/wiki/Steve_Jobs) keynote where he introduced the first iPad: January 27, 2010 at 10:00 a.m. Pacific Standard Time (UTC-8)
* The start of [Tim Cook’s](https://en.wikipedia.org/wiki/Tim_Cook) keynote (“Timnote”) where he introduced Apple Silicon: June 22, 2020 at 10:00 a.m. Pacific Daylight Time (UTC-7)

🛠️ Add the following to the playground and run it:

```swift
// We’ll use the user’s current locale over and over,
// so let’s put it into a handy variable.
// `Locale.autoupdatingCurrent` always contains the current locale,
// even when the user changes their settings.
var userLocale = Locale.autoupdatingCurrent

// Let’s create some dates by...

// ...specifying a number of seconds before or after the current time:
let fiveSecondsAgo = Date(timeIntervalSinceNow: -5)
let eightMinutesFromNow = Date(timeIntervalSinceNow: 8 * 60)
print("\nCreating dates and times the hard way:")
print("• 5 seconds ago, it was \(fiveSecondsAgo.description(with: userLocale)).")
print("• 8 minutes from now, it will be \(eightMinutesFromNow.description(with: userLocale)).")

// ...specifying the number of seconds before or after
// the start of the Third Millennium:
let iPhoneStevenoteSwiftInterval = 190_058_400.0
// (Swift ignores underscores in numbers, so we’re using them
// to group digits to make the number easier to read.)
var iPhoneStevenoteDate = Date(timeIntervalSinceReferenceDate: iPhoneStevenoteSwiftInterval)
print("• The iPhone Stevenote took place on \(iPhoneStevenoteDate.description(with: userLocale)).")

// ...specifying the number of seconds before or after
// the start of the Unix epoch:
let iPadStevenoteUnixInterval = 1_264_615_200.0
var iPadStevenoteDate = Date(timeIntervalSince1970: iPadStevenoteUnixInterval)
print("• The iPad Stevenote took place on \(iPadStevenoteDate.description(with: userLocale)).")

// ...specifying the number of seconds before or after
// another date. The Apple Silicon Timnote took place
// 328,230,000 seconds after the iPad Stevenote:
let appleSiliconTimnoteIPadStevenoteInterval = 328_230_000.0
var appleSiliconTimnoteDate = Date(
    timeInterval: appleSiliconTimnoteIPadStevenoteInterval,
    since: iPadStevenoteDate
)
print("• The Apple Silicon Timnote took place on \(appleSiliconTimnoteDate.description(with: userLocale)).")
```

You should see the dates and times for five seconds ago, eight minutes in the future, and for the keynotes announcing the original iPhone, the original iPad, and Apple Silicon. These dates and times will be expressed in your system’s local time, in a format determined by your system’s `Locale` settings.

The code works, but once again, most people don’t tell time in terms of seconds before or after a reference date. Let’s look at a more human-friendly way to define dates and times.


### Creating dates and times the simpler way with `DateFormatter`

The `DateFormatter` class works in conjunction with `Date` to do two things:

* It converts strings containing various formats of date and time information into `Date` instances, and
* it also creates string representations of `Date` instances in various formats.

Let’s use `DateFormatter` to create `Date` instances using parameters that are much easier to understand. Let’s use the date and time of [“The Mother of All Demos,”](https://invention.si.edu/mother-all-demos) where computer engineer [Doug Englebart](https://en.wikipedia.org/wiki/Douglas_Engelbart) demonstrated so many elements of modern computing for the first time. It happened on December 9, 1968, at 3:45 p.m. Pacific Standard Time (UTC-8).

🛠️ Add this code to the playground and run it:

```swift
let myDateFormatter = DateFormatter()

// DateFormatter's format string uses the date format specifiers
// spelled out in Unicode Technical Standard #35 (located at
// http://www.unicode.org/reports/tr35/tr35-25.html#Date_Format_Patterns)
myDateFormatter.dateFormat = "MMMM d, y 'at' h:mm a, zzzz"

var motherOfAllDemosDate = myDateFormatter.date(from: "December 9, 1968 at 3:45 PM, Pacific Standard Time")!
print("\nCreating dates and times with DateFormatter:")
print("• The Mother of All Demos took place on \(motherOfAllDemosDate.description(with: userLocale)).")
```

When you run the playground, the last line of its output will be the date and time of the Mother of All Demos, displayed in your local time and system locale’s language and format.

Let’s take a closer look at the first two lines of the code you just entered:

```swift
let myDateFormatter = DateFormatter()
myDateFormatter.dateFormat = "MMMM d, y 'at' h:mm a, zzzz"
```

The first line is pretty straightforward: it creates a new instance of `DateFormatter` named `myDateFormatter`. I mention it only to point out that there’s some general agreement among Swift developers that creating `DateFormatter` objects is computationally expensive. If you need to use a `DateFormatter` often, it’s better to create a dedicated instance for each use case and reuse it when needed.

The second line specifies the format of the string that `myDateFormatter` should expect to convert into a `Date`. Here are the formatting strings used in setting `myDateFormatter`’s `dateFormat` property:

* `MMMM`: The name of a month, spelled out in full. For locales whose language is English, this is one of a set of full month names from `January` through `December`.
* `d`: The day of the month. A single `d` means that this can either be a single digit (e.g.: `1`) or a double-digit with a leading zero for single-digit days (e.g.: `01`).
* `y`: The year. A single `d` means that this can either be a single digit long and up to four digits long.
\
* `h`: The hour. A single `h` means that this can either be a single digit (e.g.: `1`) or a double-digit with a leading zero for single-digit hours (e.g.: `01`).
* `mm`: The minute. The double `m` means single-digit minutes should be zero-padded (e.g.: `01`).
* `zzzz`: The time zone name, spelled out in full (you may want to consult [this list of time zone abbreviations and full names](https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations)).

For a full list of the formatting strings for `DateFormatter`, consult the [Unicode standard for specifying date format patterns](http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns). 

Let’s look at the last two lines of that code:

```swift
var motherOfAllDemosDate = myDateFormatter.date(from: "December 9, 1968 at 3:45 PM, Pacific Standard Time")!
print("The Mother of All Demos took place on \(motherOfAllDemosDate.description(with: userLocale)).")
```

The first line uses `myDateFormatter`’s `date(from:)` method to create a `Date` based on the argument provided to the `from:` parameter. This method’s return type is the optional `Date?`, which means it returns a `Date` if the provided argument is in the expected format and can be converted into a valid `Date`, or `nil` otherwise.

The second line prints the date when the Mother of All Demos took place.

If you’re given the task of converting many date strings in some arbitrary format — perhaps your app has to process a CSV file or database table — you’ll find `DateFormatter`’s string-to-`Date` conversion capability very useful.


### Creating dates and times in an even simpler way with `ISO8601DateFormatter`

Given that there are several different formats for dates and times, we’re fortunate that many applications and services follow the [ISO 8601 standard](https://en.wikipedia.org/wiki/ISO_8601) for expressing date and time information in string form.

<table>
<tr>
<th>Information</th>
<th>ISO 8601 format</th>
</tr>
<tr>
<td>Date of the Mother of All Demos</td>
<td>1968-12-09</td>
</tr>
<tr>
<td>Date and time of the Mother of All Demos in UTC</td>
<td>1968-12-09T23:45:00Z<br />or<br />1968-12-09T23:45:00+00:00</td>
</tr>
<tr>
<td>Date and time of the Mother of All Demos in Pacific Standard Time (UTC-8)</td>
<td>1968-12-09T15:45:00-08:00</td>
</tr>
</table>

`ISO8601DateFormatter` is a class specifically for converting date strings in ISO 8601 format into `Date` instances and vice versa. Let’s redefine `motherOfAllDemosDate` using `ISO8601DateFormatter`.

🛠️ Add the following to the playground and run it:

```swift
let iso8601DateFormatter = ISO8601DateFormatter()
motherOfAllDemosDate = iso8601DateFormatter.date(from: "1968-12-09T15:45:00-08:00")!
print("\nOnce again, the Mother of All Demos took place on \(motherOfAllDemosDate.description(with: userLocale)).")
```

Once again, the last line of output will be the date and time of the Mother of All Demos, displayed in your local time and system locale’s language and format.

Creating dates with `ISO8601DateFormatter` requires one less line than doing so with `DateFormatter`.


## Creating `Date`s with `Calendar` and `DateComponents`

Given a specific date like “December 9, 1968” or a specific date and time like “December 9, 1968 at 3:45 p.m. Pacific Standard Time,” it’s a fairly straightforward process to create a `Date` using a `DateFormatter` or `ISO8601DateFormatter`. 

However, you may be asked to create dates and times based on information that doesn’t include a given month or day in the [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian_calendar) (also known as “the Western calendar”). Here are some examples:

* The 10,000th hour of the year
* The 234th day of the year
* The first Friday of the year
* The first Friday in June (National Donut Day #1)
* Thursday on the 33rd week of the year
* An “overflow” date, such as September 50

For cases like these, we’ll need `Calendar` and `DateComponents`. Let’s look at these two structs and then build some `Date`s with them.


### `Calendar`

We tell time using units such as years, months, days, hours, and minutes, all of which evolved over thousands of years and are based on the relative positions and motions of the sun, earth, and moon. It’s much easier for us to understand “January 9, 2007, 10:00 a.m. Pacific Standard Time” than “190,058,400 seconds after the start of the Third Millennium, UTC.”

The [`Calendar`](https://developer.apple.com/documentation/foundation/calendar) struct provides much-needed context for `Date` instances. It allows us to convert back and forth between computer-friendly `Date` objects and human-friendly units like years, months, days, and so on. Think of it as a ruler or tape measure that you can place beside `Date`’s time system. Most of the time, you’ll use the Gregorian calendar; if you picture it alongside the way `Date` measures time, it would look like this:

![Swift’s reference timeline, shown lined up with the Gregorian calendar](https://images.ctfassets.net/23aumh6u8s0i/7rnWeTaw87OquP7ieiVBhj/773c1464aee886fb029bfd8222540384/swift_calendar_2.png)

In addition to the Gregorian calendar, `Calendar` [supports 15 other calendar systems](https://developer.apple.com/documentation/foundation/calendar/identifier), including the Buddhist and Hebrew calendars, which are shown below alongside the Gregorian calendar and `Date`’s time system:

![Swift’s reference timeline, shown lined up with the Gregorian, Hebrew, and Buddhist calendars](https://images.ctfassets.net/23aumh6u8s0i/7ATQ8wIhSEXGxc5VjjI7WZ/2ad9357ca07fb8984f0d69d38455b80d/swift_calendar_3.png)

Let’s start with `Calendar` by determining what your system’s current calendar is:

🛠️ Add this code to the playground and run it:

```swift
print("\nCalendar:")
print("• The current calendar is \(Calendar.current).")
print("• The current calendar’s time zone is \(Calendar.current.timeZone) ")
```

On my system, the output is: 

```
Calendar:
• The current calendar is gregorian (current).
• The current calendar’s time zone is America/New_York (fixed (equal to current))
```

`Calendar.current` (and by extension, its properties, including `Calendar.current.timeZone`) is a static read-only property based on the user’s settings. Your system is probably set to the `gregorian` calendar, and its time zone is set to your system’s time zone settings.

`Calendar` doesn’t do much on its own. It simply provides a human-friendly set of references to Swift’s system for telling time. It requires a companion class that allows us to make use of the years, months, days, hours, and minutes that a `Calendar` provides.


### Creating a `Date` with `Calendar` and `DateComponents`

The [`DateComponents`](https://developer.apple.com/documentation/foundation/datecomponents) struct allows us to assemble either...

* a point in time, or 
* an interval of time

...out of components such as year, month, day, hour, minute, and more. For now, we’ll use `DateComponents` to assemble a point in time.

![Diagram showing that we can take a set of DateComponents and then use a Calendar to create a Date.](https://images.ctfassets.net/23aumh6u8s0i/1Xifrm9sis16bGFEftP0uX/270283fb63d0c8f0e462179b68bdccd0/datecomponents_and_calendar_into_date.png)

Here’s the complete set of components that `DateComponents` uses:

<table>
<tr>
<th>Component</th>
<th>Description</th>
</tr>
<tr>
<td><code>calendar</code></td>
<td>The calendar system of the date. Its default value is the system’s calendar, which is usually <code>gregorian</code>.</td>
</tr>
<tr>
<td><code>day</code></td>
<td>The day number of the date. For January 9, 2007, 18:00 UTC, this value is <code>9</code>.</td>
</tr>
<tr>
<td><code>era</code></td>
<td>The era of the date, which depends its calendar system. In this case, we’re using the Gregorian calendar, which has two eras:
<ul><li>BCE (a.k.a. BC), represented by the integer value <code>0</code></li>
<li>CE (a.k.a. AD), represented by the integer value <code>1</code></li></ul></td>
</tr>
<tr>
<td><code>hour</code></td>
<td>The hour number of the date. For January 9, 2007, 18:00 UTC, this value is <code>18</code>.</td>
</tr>
<tr>
<td><code>minute</code></td>
<td>The minute number of the date. For January 9, 2007, 18:00 UTC, this value is <code>0</code>.</td>
</tr>
<tr>
<td><code>month</code></td>
<td>The month number of the date, with month numbers starting at <code>1</code>. For January 9, 2007, 18:00 UTC, this value is <code>1</code>.</td>
</tr>
<tr>
<td><code>nanosecond</code></td>
<td>The nanosecond number of the date. For January 9, 2007, 18:00 UTC, this value is <code>0</code>.</td>
</tr>
<tr>
<td><code>quarter</code></td>
<td>The quarter number of the date, with quarter numbers starting at <code>0</code>. January 9, 2007, 18:00:00 UTC is in the first quarter of the year, so this value is <code>0</code>.</td>
</tr>
<tr>
<td><code>second</code></td>
<td>The second number of the date. For January 9, 2007, 18:00 UTC, this value is <code>0</code>.</td>
</tr>
<tr>
<td><code>timeZone</code></td>
<td>The time zone of the date. This will depend on the time zone of the calendar used.</td>
</tr>
<tr>
<td><code>weekday</code></td>
<td>The day of the week of the date. In the <code>gregorian</code> calendar, Sunday is <code>1</code>, Monday is <code>2</code>, Tuesday is <code>3</code>, and so on. January 9, 2007, was a Wednesday, so this value for that date is <code>3</code>.</td>
</tr>
<tr>
<td><code>weekdayOrdinal</code></td>
<td>The position of the weekday within the next larger specified calendar unit.
<ul><li>If the next larger specified unit is <code>month</code>, this is the position of the weekday within that month. If this value is set to <code>1</code> and <code>weekday</code> is set to <code>4</code> (Wednesday), this will specify the first Wednesday of the given month.</li><li>If the next larger specified unit is <code>year</code>, this returns the position of the weekday within that year. If this value is set to <code>1</code> and <code>weekday</code> is set to <code>4</code> (Wednesday), this will specify the first Wednesday of the given year.</li></ul></td>
</tr>
<tr>
<td><code>weekOfMonth</code></td>
<td>The week of the month of the date, where the first week of the month is <code>1</code>. January 9, 2007, 18:00 UTC fell on the 2nd week of January 2007, so this value is <code>2</code>.</td>
</tr>
<tr>
<td><code>weekOfYear</code></td>
<td>The week of the year of the date, where the first week of the year is <code>1</code>. January 9, 2007, 18:00 UTC fell on the 2nd week of 2007, so this value is <code>2</code>.</td>
</tr>
<tr>
<td><code>year</code></td>
<td>The year number of the date. For January 9, 2007, 18:00 UTC, this value is <code>2007</code>.</td>
</tr>
<tr>
<td><code>yearForWeekOfYear</code></td>
<td>Oh wow, this is so hard to explain that <a href="https://developer.apple.com/documentation/foundation/nsdatecomponents/1413809-yearforweekofyear">I’ll leave it to Apple’s docs.</a></td>
</tr>
</table>

You don’t have to specify all the components in a `DateComponents` instance; you have to specify just enough to define a date.


Let’s use `DateComponents` to construct a `Date` object using a year, month, day, and time. We’ll do this by rebuilding the date and time of the original iPhone Stevenote: January 9, 2007 at 10:00 a.m., Pacific Standard Time (UTC-8).

🛠️ Add the following to the playground and run it:

```swift
print("\nCreating a Date with Calendar and DateComponents:")

var gregorianCalendar = Calendar(identifier: .gregorian)
gregorianCalendar.locale = userLocale

let iPhoneStevenoteComponents = DateComponents(
  calendar: gregorianCalendar,
  timeZone: TimeZone(identifier: "America/Los_Angeles"),
  year: 2007,
  month: 1,
  day: 9,
  hour: 10,
  minute: 00
)
iPhoneStevenoteDate = gregorianCalendar.date(from: iPhoneStevenoteComponents)!
print("• Once again, the iPhone Stevenote took place on \(iPhoneStevenoteDate.description(with: userLocale)).")
```

On my system, the code above results in this output:

```
Once again, the iPhone Stevenote took place on Tuesday, January 9, 2007 at 1:00:00 PM Eastern Standard Time.
```

The date and time that you’ll see will depend on your time zone, but it will be the local equivalent date and time of January 9, 2007 at 10:00:00 AM UTC-8.

Let’s take a closer look at the newly-added code. Here are the first two lines:

```swift
var gregorianCalendar = Calendar(identifier: .gregorian)
gregorianCalendar.locale = userLocale
```

In the first line, we’re creating a `Calendar` instance using the `Calendar(identifier:)` initializer. We’re specifying that the calendar’s date system is `.gregorian`, which is the shorthand form of the full calendar identifier, `Calendar.Identifier.gregorian`.

Newly-instantiated `Calendar` instances don’t have a set `locale`, so we set it to the user’s current locale in the second line. Doing this sets the `Calendar` to the user’s preferred language, which is useful when we want to get a list of weekday and month names.

Here’s the third line:

```swift
let iPhoneStevenoteComponents = DateComponents(
  timeZone: TimeZone(identifier: "America/Los_Angeles"),
  year: 2007,
  month: 1,
  day: 9,
  hour: 10,
  minute: 00
)
```

This line creates a set of date components that represent January 9, 2007 at 10:00 a.m., Pacific Standard Time (UTC-8). Note that I’ve specified the time zone with a geographic identifier — `America/Los_Angeles` — instead of a time zone identifier like `PST` or a time offset from UTC like `-08:00`. I prefer to use geographic identifiers because they let me delegate figuring out if an event happened during Standard Time or Daylight Saving Time to Foundation, which will always get it right.

`DateComponents`’ initializer has a lot of optional parameters. In the code above, we used only those parameters we needed to specify the date, time, and time zone of the original iPhone Stevenote. We’ll look at some of the other parameters shortly.

Here are the final two lines of the code:

```swift
iPhoneStevenoteDate = gregorianCalendar.date(from: iPhoneStevenoteComponents)!
print("\nOnce again, the iPhone Stevenote took place on \(iPhoneStevenoteDate.description(with: userLocale)).")
```

The first line uses `gregorianCalendar` and the `DateComponents` we just created to create a new `Date`, which we assigned to `iPhoneStevenoteDate`. `iPhoneStevenoteComponents` provides the values corresponding to the date and time of the iPhone Stevenote, and `gregorianCalendar` provides the context for those values and creates the `Date`.

Let’s create a `DateComponents` instance in a slightly different way. We’ll do it for the date of the original iPad Stevenote, which took place on January 27, 2010 at 10:00 a.m. Pacific Standard Time.

🛠️ Add this code to the playground and run it:

```swift
var iPadStevenoteComponents = DateComponents()
iPadStevenoteComponents.year = 2010
iPadStevenoteComponents.month = 1
iPadStevenoteComponents.day = 27
iPadStevenoteComponents.hour = 10
iPadStevenoteComponents.minute = 0
iPadStevenoteComponents.timeZone = TimeZone(identifier: "America/Los_Angeles")
iPadStevenoteDate = gregorianCalendar.date(from: iPadStevenoteComponents)!
print("• Once again, the iPad Stevenote took place on \(iPadStevenoteDate.description(with: userLocale)).")
```

The code above takes a different approach to set up a `DateComponents` instance by using the default initializer to instantiate `DatComponents`, followed by setting its various properties to specify the desired date’s year, month, day, hour, minute, and time zone. The process of creating a `Date` from `DateComponents` remains the same: using `Calendar`’s `date(from:)` method.


### What will the day and time be 10,000 hours into 2024?

So far, we’ve created `Date`s based on known dates and times. How about Dates where we don’t have a specific date but have enough criteria to specify a date? This is where `Calendar` and `DateComponets` shine. `Calendar` does its best to work with the `DateComponents` that you give it, and `DateComponents` gives you all sorts of ways to specify a date.

You’ve probably heard of the [“10,000 Hour Rule,”](https://www.listenmoneymatters.com/the-10000-hour-rule/) which states that on average, it takes a person about 10,000 hours of directed practice to become an expert at something. We’re going to ignore [the debate over whether it’s true](https://www.vox.com/science-and-health/2019/8/23/20828597/the-10000-hour-rule-debunked) and focus on the 10,000 hours instead. If you could practice for 10,000 hours non-stop, without having to take a break to eat, sleep, or do anything else, and you started on January 1, 2024 at midnight, what would the date and time be when you had completed your practice?

🛠️ Add the following to the playground and run it:

```swift
let tenThousandHoursComponents = DateComponents(
    year: 2024,
    hour: 10000
)
let tenThousandHoursInto2023Date = gregorianCalendar.date(from: tenThousandHoursComponents)!
print("\n• 10,000 hours into 2024, the date and time will be \(tenThousandHoursInto2023Date.description(with: userLocale)).")
print("• In UTC, that’s \(tenThousandHoursInto2023Date.description).")
```

Here’s what my system displayed when I ran the code:

```
• 10,000 hours into 2024, the date and time will be Thursday, February 20, 2025 at 4:00:00 PM Eastern Standard Time.
• In UTC, that’s 2025-02-20 21:00:00 +0000.
```

You may have trouble believing that a 10,000-hour practice session that started at the very start of 2023 would end nearly three months into 2024, but it’s true. 10,000 hours is 8 hours short of 417 days. You can’t practice for that length of time continuously, which is why many people prefer to say it takes 10 years to become an expert — that’s how long it takes to accumulate 10,000 hours by breaking it into sessions of three hours every day.


### What will the 234th day of 2024 be?

`DateComponents` makes this calculation easy.

🛠️ Add this code to the playground and run it:

```swift
let day234Components = DateComponents(
    year: 2024,
    day: 243
)
let day234Date = gregorianCalendar.date(from: day234Components)!
print("\n• The 234th day of 2024 will be \(day234Date.description(with: userLocale)).")
```

On my system, this code produces the following output: 

```
• The 234th day of 2024 will be Friday, August 30, 2024 at 12:00:00 AM Eastern Daylight Time.
```


### What date is the first Friday of 2024?

Let’s use a couple of `DateComponents` properties to find out what date the first Friday of 2024 will fall on. These properties are:

* `weekday`: An integer representing a day of the week. The first day of the week, Sunday, is represented by 1, and the last day of the week, Saturday, is represented by 7. We want a Friday, so we’ll set this value to `6`.
* `weekdayOrdinal`: The ordinal, or order number, of the given weekday. We want the first Friday, so we’ll set this value to `1`.

🛠️ Add the following to the playground and run it:

```swift
let firstFriday2024Components = DateComponents(
    year: 2024,        // We want a date in 2024
    weekday: 6,        // It’s a Friday
    weekdayOrdinal: 1  // The first one
)
let firstFriday2024Date = gregorianCalendar.date(from: firstFriday2024Components)!
print("\n• The first Friday of 2024 will be \(firstFriday2024Date.description(with: userLocale)).")
```

Here’s what my system displayed when I ran the code:

```
• The first Friday of 2024 will be Friday, January 5, 2024 at 12:00:00 AM Eastern Standard Time.
```


### What date is the first National Donut Day of 2023?

Apparently, just _one_ National Donut Day isn’t enough. The second one of the year is a stationary day; [it always happens on November 5](https://nationaldaycalendar.com/national-donut-day-november-5/). But the first one of the year is a moving day — [it’s the first Friday in June](https://nationaldaycalendar.com/national-doughnut-day-first-friday-in-june/). Let’s let Swift tell us what that date is for 2023.

🛠️ Add this code to the playground and run it:

```swift
let firstDonutDay2024Components = DateComponents(
    year: 2024,        // We want a date in 2024
    month: 6,          // in June
    weekday: 6,        // It’s a Friday
    weekdayOrdinal: 1  // The first one
)
let firstDonutDay2024Date = gregorianCalendar.date(from: firstDonutDay2024Components)!
print("\n• The first National Donut Day of 2024 will be \(firstDonutDay2024Date.description(with: userLocale)).")
```

On my system, this code produces the following output: 

```
• The first National Donut Day of 2024 will be Friday, June 7, 2024 at 12:00:00 AM Eastern Daylight Time.
```


### What date is the Thursday of the 33rd week of the year?

We’ll use `DateComponents`’ `weekOfYear` property to solve this one.

🛠️ Add the following to the playground and run it:

```swift
let thursday33rdWeek2024Components = DateComponents(
    year: 2024,     // We want a date in 2024
    weekday: 5,     // It’s a Thursday
    weekOfYear: 33  // on the 33rd week of the year
)
let thursday33rdWeek2024Date = gregorianCalendar.date(from: thursday33rdWeek2024Components)!
print("\n• The Thursday of the 33rd week of 2024 will be \(thursday33rdWeek2024Date.description(with: userLocale)).")
```

Here’s what my system displayed when I ran the code:

```
• The Thursday of the 33rd week of 2024 will be Thursday, August 15, 2024 at 12:00:00 AM Eastern Daylight Time.
```

### What happens if you set `DateComponents` to September 50, 2024?

Let’s look at the case of overflow. What happens if you try to create a `Date` using components that define the nonsense date “September 50, 2024?”

🛠️ Add this code to the playground and run it:

```swift
var sept50DateComponents = DateComponents(
  year: 2024,
  month: 9,
  day: 50)
let sept50Date = gregorianCalendar.date(from: sept50DateComponents)!
print("\n• September 50, 2024 is actually \(sept50Date.description(with: userLocale)).")
```

On my system, this code produces the following output: 

```
• September 50, 2024 is actually Sunday, October 20, 2024 at 12:00:00 AM Eastern Daylight Time.
```

These date components we provided are treated as “the start of September, plus 50 days” — September’s 30 days, plus an additional 20 days into October.


## Extracting `DateComponents` from a `Date` with `Calendar`

Just as we can use a `Calendar` and `DateComponents` to make a `Date`, we can also use `Date` and a `Calendar` to extract its `DateComponents`.

![Diagram showing that we can take a Date and then use a Calendar to create a set of DateComponents.](https://images.ctfassets.net/23aumh6u8s0i/5Fd3UtjKSGKrTfUNdLa79f/11edc136b113ea9f1bbf327f1dcb3eac/date_and_calendar_into_datecomponents.png)


### Extracting all the components from a `Date`

Let’s extract all the components from a `Date` we’ve already defined: `iPhoneStevenoteDate`, which is January 9, 2007, 10:00 a.m. Pacific Standard Time.

🛠️ Add the following to the playground and run it:

```swift
var iPhoneStevenoteDateComponents = gregorianCalendar.dateComponents(
    [
        .calendar,
        .day,
        .era,
        .hour,
        .minute,
        .month,
        .nanosecond,
        .quarter,
        .second,
        .timeZone,
        .weekday,
        .weekdayOrdinal,
        .weekOfMonth,
        .weekOfYear,
        .year,
        .yearForWeekOfYear
    ],
    from: iPhoneStevenoteDate
)
print("\nThe date components for the iPhone Stevenote date:")
print("• Calendar: \(iPhoneStevenoteDateComponents.calendar!.identifier)")
print("• Day: \(iPhoneStevenoteDateComponents.day!)")
print("• Era: \(iPhoneStevenoteDateComponents.era!)")
print("• Hour: \(iPhoneStevenoteDateComponents.hour!)")
print("• Minute: \(iPhoneStevenoteDateComponents.minute!)")
print("• Month: \(iPhoneStevenoteDateComponents.month!)")
print("• Nanosecond: \(iPhoneStevenoteDateComponents.nanosecond!)")
print("• Quarter: \(iPhoneStevenoteDateComponents.quarter!)")
print("• Second: \(iPhoneStevenoteDateComponents.second!)")
print("• Time zone: \(iPhoneStevenoteDateComponents.timeZone!)")
print("• Weekday: \(iPhoneStevenoteDateComponents.weekday!)")
print("• Weekday ordinal: \(iPhoneStevenoteDateComponents.weekdayOrdinal!)")
print("• Week of month: \(iPhoneStevenoteDateComponents.weekOfMonth!)")
print("• Week of year: \(iPhoneStevenoteDateComponents.weekOfYear!)")
print("• Year: \(iPhoneStevenoteDateComponents.year!)")
print("• Year for week of year: \(iPhoneStevenoteDateComponents.yearForWeekOfYear!)")
```

Here’s what my system displayed when I ran the code:

```
The date components for the iPhone Stevenote date:
• Calendar: gregorian
• Day: 9
• Era: 1
• Hour: 13
• Minute: 0
• Month: 1
• Nanosecond: 0
• Quarter: 0
• Second: 0
• Time zone: America/New_York (fixed (equal to current))
• Weekday: 3
• Weekday ordinal: 2
• Week of month: 2
• Week of year: 2
• Year: 2007
• Year for week of year: 2007
```

The component values that you’ll see are determined by your system’s time zone. If you want to see the system components in the time zone where the Stevenote took place (Steve Jobs gave his keynote in San Francisco, which is in the `America/Los_Angeles` time zone), use a `Calendar` whose `timeZone` property is set to `America/Los_Angeles`.

🛠️ Add this code to the playground and run it:

```swift
var pacificCalendar = Calendar(identifier: .gregorian)
pacificCalendar.timeZone = TimeZone(identifier: "America/Los_Angeles")!
pacificCalendar.locale = Locale.autoupdatingCurrent
iPhoneStevenoteDateComponents = pacificCalendar.dateComponents(
    [
        .calendar,
        .day,
        .era,
        .hour,
        .minute,
        .month,
        .nanosecond,
        .quarter,
        .second,
        .timeZone,
        .weekday,
        .weekdayOrdinal,
        .weekOfMonth,
        .weekOfYear,
        .year,
        .yearForWeekOfYear
    ],
    from: iPhoneStevenoteDate
)
print("\nThe date components for the iPhone Stevenote date - for the Pacific Calendar — are:")
print("• Calendar: \(iPhoneStevenoteDateComponents.calendar!.identifier)")
print("• Day: \(iPhoneStevenoteDateComponents.day!)")
print("• Era: \(iPhoneStevenoteDateComponents.era!)")
print("• Hour: \(iPhoneStevenoteDateComponents.hour!)")
print("• Minute: \(iPhoneStevenoteDateComponents.minute!)")
print("• Month: \(iPhoneStevenoteDateComponents.month!)")
print("• Nanosecond: \(iPhoneStevenoteDateComponents.nanosecond!)")
print("• Quarter: \(iPhoneStevenoteDateComponents.quarter!)")
print("• Second: \(iPhoneStevenoteDateComponents.second!)")
print("• Time zone: \(iPhoneStevenoteDateComponents.timeZone!)")
print("• Weekday: \(iPhoneStevenoteDateComponents.weekday!)")
print("• Weekday ordinal: \(iPhoneStevenoteDateComponents.weekdayOrdinal!)")
print("• Week of month: \(iPhoneStevenoteDateComponents.weekOfMonth!)")
print("• Week of year: \(iPhoneStevenoteDateComponents.weekOfYear!)")
print("• Year: \(iPhoneStevenoteDateComponents.year!)")
print("• Year for week of year: \(iPhoneStevenoteDateComponents.yearForWeekOfYear!)")
```

You’ll see the following output:

```
The date components for the iPhone Stevenote date - for the Pacific Calendar — are:
• Calendar: gregorian
• Day: 9
• Era: 1
• Hour: 10
• Minute: 0
• Month: 1
• Nanosecond: 0
• Quarter: 0
• Second: 0
• Time zone: America/Los_Angeles (fixed)
• Weekday: 3
• Weekday ordinal: 2
• Week of month: 2
• Week of year: 2
• Year: 2007
• Year for week of year: 2007
```

This time, the output lists the components for the date of the Stevenote in its local date and time, regardless of your system’s time zone.


### What day of the week and week of the year will April Fools’ Day 2024 fall on?

In many parts of the world, April 1 is a day for playing pranks on others. In the English-speaking world, it has a name: [April Fools’ Day](https://en.wikipedia.org/wiki/April_Fools'_Day).

Since it has an assigned date, we already know its what month and day it will fall on. But it takes effort to determine what weekday it will be on a given April 1, or what week of the year it will be. `DateComponents` can help us. We can use a `DateComponents` instance to construct a `Date` for April 1, 2024 and another `DateComponents` instance to extract the `weekday` and `weekOfYear` values for that `Date`.

🛠️ Add the following to the playground and run it:

```swift
// Create the date
let aprilFoolsDay2024Components = DateComponents(
    year: 2024,
    month: 4,
    day: 1
)
let aprilFoolsDay2024Date = gregorianCalendar.date(from: aprilFoolsDay2024Components)!

// Extract the weekday and week of the year from the date
let wantedComponents = gregorianCalendar.dateComponents(
    [
        .weekday,
        .weekOfYear,
    ],
    from: aprilFoolsDay2024Date
)
let aprilFools2024Weekday = wantedComponents.weekday!
let aprilFools2024WeekdayName = gregorianCalendar.weekdaySymbols[aprilFools2024Weekday - 1]
let aprilFools2024WeekOfYear = wantedComponents.weekOfYear!
print("\nApril Fools’ Day 2024:")
print("• happens on day \(aprilFools2024Weekday) of the week (\(aprilFools2024WeekdayName)),")
print("• on week \(aprilFools2024WeekOfYear) of 2024.")
```

Running this code reveals that April 1, 2024 will fall on weekday 2 (Monday), and that it will occur on the 14th week of the year. To specify which weekday day 2 is, I used `Calendar`’s [`weekdaySymbols`](https://developer.apple.com/documentation/foundation/calendar/2293235-weekdaysymbols) array to access the name of the corresponding weekday, which in this case is `Monday`.


## The Big Challenge

At the start of this chapter, I said that Swift’s date and time system lets you do the following without having to do the calculations yourself, while using only a few lines of code:

* Get the date for the third Wednesday of July at 3:30 p.m. Pacific Time
* Display it as it would appear in the Coptic calendar system in Melbourne, Australia’s time zone with a few lines of code.

🛠️ Let’s give it a try! Add this code to the playground and run it:

```swift
print("\nThe Big Challenge!")

// First, create the the date —
// third Wednday of July at 3:30 p.m. Pacific Time
let challengeDateComponents = DateComponents(
    calendar: gregorianCalendar,
    timeZone: TimeZone(identifier: "America/Los_Angeles")!,
    year: 2024,
    month: 7,
    hour: 15,
    minute: 30,
    weekday: 4,
    weekdayOrdinal: 3
)
let challengeDate = gregorianCalendar.date(from: challengeDateComponents)!
print("• The challenge date in the Gregorian calendar is \(challengeDate.description(with: userLocale)).")

var melbourneCalendar = Calendar(identifier: .gregorian)
melbourneCalendar.timeZone = TimeZone(identifier: "Australia/Melbourne")!
let melbourneDateComponents = melbourneCalendar.dateComponents(
  [
    .year,
    .month,
    .day,
    .weekday,
    .hour,
    .minute
  ],
  from: challengeDate)
print("• melbourneDateComponents: \(melbourneDateComponents)")

// Create the Coptic calendar and set its locale to Arabic(Egypt)
// so that it us Arabic month nam,
// and its time zone to Melbourne.
var copticCalendar = Calendar(identifier: .coptic)
copticCalendar.locale = Locale(identifier: "ar_EG")
copticCalendar.timeZone = TimeZone(identifier: "Australia/Melbourne")!

// Extract the date components from the date using the Coptic calendar
let challengeCopticComponents = copticCalendar.dateComponents(
  [
    .year,
    .month,
    .day,
    .weekday,
    .hour,
    .minute
  ],
  from: challengeDate)
let challengeYear = challengeCopticComponents.year!
let challengeMonth = challengeCopticComponents.month!
let challengeMonthName = copticCalendar.monthSymbols[challengeMonth - 1]
let challengeDay = challengeCopticComponents.day!
let challengeWeekday = challengeCopticComponents.weekday!
let challengeWeekdayName = copticCalendar.weekdaySymbols[challengeWeekday - 1]
let challengeHour = challengeCopticComponents.hour!
let challengeMinute = challengeCopticComponents.minute!
print("• The challenge date in the Coptic calendar happens on: ")
print("••• year \(challengeYear)")
print("••• month \(challengeMonth) (\(challengeMonthName))")
print("••• day \(challengeDay)")
print("••• weekday \(challengeWeekday) (\(challengeWeekdayName))")
print("••• hour \(challengeHour)")
print("••• minute \(challengeMinute) (Melbourne time).")
```

You’ll see the following output:

```
The Big Challenge!
• The challenge date in the Gregorian calendar is Wednesday, July 17, 2024 at 6:30:00 PM Eastern Daylight Time.
• melbourneDateComponents: year: 2024 month: 7 day: 18 hour: 8 minute: 30 weekday: 5 isLeapMonth: false 
• The challenge date in the Coptic calendar happens on: 
••• year 1740
••• month 11 (أبيب)
••• day 11
••• weekday 5 (الخميس)
••• hour 8
••• minute 30 (Melbourne time).
```

The output shows that:

* In my time zone (US Eastern), the challenge date is Wednesday, July 17, 2024 at 6:30 p.m.. 
* In Melbourne, Australia, that date is Thursday (weekday 5), July 18, 2024 at 8:30 a.m. in the Gregorian calendar.
* In the Coptic calendar, the date is 11th day of أبيب (“Epip” or “Abib”, month 11), which is a Thursday (الخميس). I verified that this lines up with July 20, 2024 using [this calendar page](https://calendar.zoznam.sk/coptic_calendar-en.php).


## Next Steps

> 💻 Once again, you can find an Xcode playground with all the code in this article in [this GitHub repository](https://github.com/auth0-blog/swift-date-time-intro) — it’s `intro-dates-times-swift-1.playground`.

In the next chapter of this tutorial, we’ll take a closer look at ways of converting `Date`s into strings to display to the user.