iOS
ISO 8601
date formatting
Apple development
Swift programming

How do I get an ISO 8601 date on iOS?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

ISO 8601 is the standard date-time format you see in APIs such as 2025-03-08T14:30:00Z. On iOS, the safest way to produce or parse that format is to use Foundation’s ISO-aware APIs instead of hand-building locale-sensitive formatter strings.

The modern default choice is ISO8601DateFormatter, and on newer platforms you can also use the format-style APIs. Use a plain DateFormatter only when you need a custom variant that the ISO-specific formatter does not express cleanly.

Using ISO8601DateFormatter

ISO8601DateFormatter is designed for this exact format.

swift
1import Foundation
2
3let formatter = ISO8601DateFormatter()
4let now = Date()
5let text = formatter.string(from: now)
6
7print(text)

That produces a valid ISO 8601 string, typically in UTC with a timezone marker.

Parsing works the same way:

swift
1import Foundation
2
3let formatter = ISO8601DateFormatter()
4let value = "2025-03-08T14:30:00Z"
5
6if let date = formatter.date(from: value) {
7    print(date)
8}

This is usually the correct solution for API payloads and machine-readable timestamps.

Customizing the Formatter Options

ISO 8601 has variants, such as fractional seconds or different separators. ISO8601DateFormatter lets you control this through formatOptions.

swift
1import Foundation
2
3let formatter = ISO8601DateFormatter()
4formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
5
6let text = formatter.string(from: Date())
7print(text)

This is useful when your backend expects timestamps such as 2025-03-08T14:30:00.123Z rather than second-level precision.

The Newer Format Style API

On newer Apple platforms, Date.ISO8601FormatStyle is another good option.

swift
1import Foundation
2
3let text = Date().formatted(.iso8601)
4print(text)

You can also parse using the matching style:

swift
1import Foundation
2
3let value = "2025-03-08T14:30:00Z"
4let date = try Date(value, strategy: .iso8601)
5print(date)

This style-based approach fits nicely with modern Swift formatting APIs and is especially pleasant when you already use formatted(...) elsewhere.

When DateFormatter Is Still Useful

Sometimes you want a very specific shape that is ISO-like but not fully handled by the dedicated APIs. In that case, a regular DateFormatter can work, but configure it carefully.

swift
1import Foundation
2
3let formatter = DateFormatter()
4formatter.locale = Locale(identifier: "en_US_POSIX")
5formatter.timeZone = TimeZone(secondsFromGMT: 0)
6formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX"
7
8let text = formatter.string(from: Date())
9print(text)

The important parts are:

  • use en_US_POSIX locale
  • use an explicit timezone
  • treat the format as machine-readable, not user-facing

Without those settings, a DateFormatter can be influenced by user locale preferences in ways that break consistent API formatting.

Formatting for APIs Versus for UI

This distinction matters a lot:

  • use ISO 8601 for machine communication
  • use localized formatters for user-facing display

A raw ISO 8601 timestamp is great for JSON and logs, but usually not ideal for showing dates in the app’s interface. For the UI, use localized DateFormatter or formatted(date:time:) styles instead.

Fractional Seconds and Compatibility

One common compatibility issue is fractional seconds. Some services always include them; others reject them. If parsing fails unexpectedly, compare the incoming string with the formatter’s options.

For example, a formatter configured only for internet date time may reject a string that includes milliseconds unless you also enable .withFractionalSeconds.

Common Pitfalls

One common mistake is using DateFormatter with a custom format string but forgetting en_US_POSIX. That can produce locale-dependent behavior and break parsing or formatting in some regions.

Another issue is mixing user-interface formatting rules with API formatting rules. ISO 8601 is a transport format, not usually the best display format for people.

It is also easy to assume all ISO 8601 strings look identical. Some include fractional seconds, timezone offsets, or date-only variants, and the parser options must match what you expect.

Finally, do not forget timezone intent. A Date is an absolute point in time, but the string representation depends on the formatter configuration.

Summary

  • On iOS, ISO8601DateFormatter is the standard tool for ISO 8601 parsing and formatting.
  • Newer Foundation APIs also support .iso8601 format styles for a more modern Swift syntax.
  • Use DateFormatter only when you need custom behavior and configure it with en_US_POSIX plus an explicit timezone.
  • Keep API formatting separate from user-facing date formatting.
  • Most ISO 8601 bugs come from mismatched formatter options, timezone assumptions, or locale-sensitive formatter misuse.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.