Swift Date Formatting: 10 Steps Guide

In this tutorial, I will guide you through 10 steps to master handling dates in Swift. We will cover everything from generating date instances to working with time zones, handling locale-specific date formats, parsing strings into dates, storing dates in a database, and performing date and time calculations.

One key component is Swift DateFormatter which helps you convert a date type to string. It allows you to set a specific formatting style. Additionally, if you are using SwiftUI, Text view makes it easier to show date information in your apps.

By the end of this tutorial, you will have a solid understanding of Swift date handling and be able to confidently convert dates to strings and format them according to your app’s requirements. Let’s dive in!

Understanding Date and Time in Swift

The Date type in Swift represents a single point in time, down to the fraction of a second. It’s a fundamental type that’s used to handle and manipulate dates and times. Think of it as a timestamp that uniquely identifies a single moment.

But here’s something interesting: the Date type in Swift doesn’t have a concept of time zones, calendars, or locales. It’s just a specific point in time, and all those other details are handled separately. That’s why you’ll often need to use other types, like DateFormatter, when you’re working with dates.

Step 1: Generating Date instances

Creating a current date in Swift can be done in several ways. The most common methods are using Date() and Date.now.

  • Date() creates a Date object that represents the current date and time based on the system clock. It captures the precise moment you call this method.
  • Date.now is a more expressive alternative introduced in recent versions of Swift. It provides a more readable way to create a Date object representing the current date and time.
let currentDate = Date.now
print(currentDate) // prints something like Optional(2023-05-19 07:30:00 +0000)

Create dates using date components

When you need to create a date with specific components or from a time interval, Swift provides convenient methods and initializers to accomplish this.

To create a date by specifying its individual components, you can use the Calendar and DateComponents classes. Here’s an example of how to create a Date object representing February 14, 2023, at 10:30 AM:

let calendar = Calendar.current
var components = DateComponents()
components.year = 2023
components.month = 2
components.day = 14
components.hour = 10
components.minute = 30

if let date = calendar.date(from: components) {
    print(date)
    // prints 2023-02-14 08:30:00 +0000
}

In this example, we first create an instance of Calendar.current, which represents the current calendar used by the system. Then, we initialize a DateComponents object and set the desired year, month, day, hour, and minute values. Finally, we use the date(from:) method of the calendar to create the Date object. If the components are valid and represent a valid date, the date constant will hold the resulting date object.

Creating Dates from Time Intervals

If you have a time interval representing seconds since the Unix epoch (January 1, 1970), you can use the Date(timeIntervalSince1970:) initializer to create a Date object. Here’s an example:

let timeInterval: TimeInterval = 1654432800
let date = Date(timeIntervalSince1970: timeInterval)

print(date)
// prints 2022-06-05 12:40:00 +0000

In this example, we create a TimeInterval variable representing a specific time interval since the Unix epoch. Then, we use the Date initializer timeIntervalSince1970: to create the corresponding Date object.

These methods allow you to create Date objects with specific components or based on time intervals, giving you the flexibility to work with dates in a precise and customizable way.

Step 2: Using a Date Picker in SwiftUI

A Date Picker in SwiftUI allows users to select a date (and optionally, time) visually, either through a scrolling wheel, a calendar-style display, or even a combination of these input methods. It’s an essential element for any app that needs to gather date-related information from users, such as birth dates, appointment dates, or deadlines.

Here’s a basic example of how to use a DatePicker:

struct ContentView: View {

    @State private var selectedDate: Date = Date()

    private let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        return formatter
    }()

    var body: some View {
        VStack(spacing: 30) {
            DatePicker("Select a Date",
                       selection: $selectedDate,
                       displayedComponents: .date) // hourAndMinute

            Text("Selected Date: \(selectedDate, formatter: dateFormatter)")
        }
        .padding()
    }
}
Example impemenation to use Swiftui picker to allow date selection.

The $selectedDate binds the Date Picker to a selectedDate state property. This means that whenever a user chooses a date with the Date Picker, the selectedDate property is updated.

The DatePicker allows for customization. You can limit the date range that a user can select by using the in: parameter, and you can even change the components the user can select (like only showing the date and not the time) by using the displayedComponents parameter.

DatePicker("Select a date",
           selection: $selectedDate,
           in: Date()...,
           displayedComponents: .date)

In this case, the DatePicker will only allow selection of dates from the current date (Date()) into the future (using the range operator), and will only display the date portion for selection.

If you want to learn more about SwiftUI picker, check out this post SwiftUI Picker Made Easy: Tutorial With Example.

Free SwiftUI Layout Book

Get Hands-on with SwiftUI Layout.

Master SwiftUI layouts with real-world examples and step-by-step guide. Building Complex and Responsive Interfaces.

Step 3: Recognizing the Default Date Format in Swift

When working with dates in Swift, it’s essential to understand the default date and time format. Swift follows the Unicode Technical Standard #35 (UTS #35) for date and time representation. The default format is based on the ISO 8601 standard, which provides a clear and unambiguous way to represent dates and times.

In Swift, the default date and time format follow the pattern:

"yyyy-MM-dd HH:mm:ss +zzzz"

Let’s break down this format:

  • “yyyy”: Represents the four-digit year.
  • “MM”: Represents the two-digit month.
  • “dd”: Represents the two-digit day.
  • “HH”: Represents the two-digit hour in a 24-hour format.
  • “mm”: Represents the two-digit minute.
  • “ss”: Represents the two-digit second.
  • “+zzzz”: Represents the time zone offset from UTC in the format “+HHmm”.

For example, the default date format:

"2023-05-19 10:30:00 +0000"

represents May 19, 2023, at 10:30 AM UTC. You can see exactly this format in the above code examples, where I used a print statement.

It’s important to recognize this default format as it can be useful when working with date conversions, parsing, or displaying dates in their default representation.

In the next steps, we’ll explore how to work with DateFormatter to format dates according to different requirements and customize the date representation to match specific formatting needs. Let’s move on to Step 2 and dive deeper into using DateFormatter for date formatting in Swift.

Step 4: Using DateFormatter to Format Dates

DateFormatter is a super handy tool in Swift that lets you format dates exactly the way you want. To get started, you need to create an instance of `DateFormatter`. Here’s an example of how I do it:

let dateFormatter = DateFormatter()

Once you have your `dateFormatter` ready, you can customize its formatting options to match your desired date format. Here are some common format options you can tweak:

  • dateStyle: This option allows you to specify the style of the date portion. For example, you can choose from options like .short, .medium, .long, or .full to display the date in a concise or more descriptive format.
  • timeStyle: Similar to dateStyle, this option lets you set the style of the time portion. You can pick styles like .short, .medium, .long, or .full to show the time in various levels of detail.
  • dateFormat: This is where the real magic happens! With dateFormat, you can define a custom format using a combination of specific formatting symbols. For example, “yyyy-MM-dd” represents a date in the format “2023-05-19”.

Now, let’s put these options to use with some examples:

import Foundation
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short

let formattedDate = dateFormatter.string(from: Date())

print("Formatted date: \(formattedDate)")
// prints: Formatted date: May 20, 2023 at 10:53 AM

In this example, I’ve set the dateStyle to .medium and timeStyle to .short. Then, I use the string(from:) method to format the current date and time according to the specified date styles.

But wait, there’s more! You can get as creative as you want with dateFormat and create your own custom date formats. It lets you use formatting symbols like “yyyy” for the year, “MM” for the month, “dd” for the day, and many more.

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "d.M.yyyy"

let formattedDate = dateFormatter.string(from: Date())

print("Formatted date: \(formattedDate)")
// prints: Formatted date: 20.5.2023

So, whether you want to display dates in a specific style or come up with your unique format, DateFormatter has got your back.

How to show a formatted date string in SwiftUI?

When using DateFormatter in a SwiftUI app, you can leverage it to format and display dates within your views. Here’s an example of how you can incorporate DateFormatter in a SwiftUI app:

struct ContentView: View {

    let currentDate = Date()

    private let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .short
        return formatter
    }()

    var body: some View {
        VStack(spacing: 30) {
           Text("Current Date and Time:")
                .font(.title)
            Text(dateFormatter.string(from: currentDate))
        }
    }
}
swift data formatting example in swiftui

In this example, we define a dateFormatter property within the ContentView struct. The dateFormatter is created as a closure to ensure it’s initialized only once. We set the desired date style and time style to .medium and .short, respectively.

Within the body of the view, we utilize the dateFormatter.string(from: Date()) method to format the current date and time.

Step 5: Using the new formatted() method for Date

A newer and easier way to convert date types is available for macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0. Date has a new function formatted that returns a formatted string. The following code illustrates a simple example:

let birthday = Date()
print(birthday.formatted())
// 6/4/2021, 2:24 PM

The formatted function has 2 optional parameters that you can use to customize the formate of the returned string. Here is a simple example:

let currentDate = Date()

currentDate.formatted(date: .omitted, time: .standard)
// 9:42:14 AM

currentDate.formatted(date: .numeric, time: .omitted)
// 10/17/2022

Here is a short overview of the options you can set for the date and time styles:

Date.FormatStyle.DateStyle

  • omitted: don’t use date-related components
  • numeric: show month, day of month, and year components represented as numeric values
  • abbreviated: show some components abbreviated for space-constrained applications
  • long: use the full month, day of month, and year components
  • complete: use all date components

Date.FormatStyle.TimeStyle

  • omitted: don’t show time information
  • shortened: show only the hour, minute, and day period components
  • standard: show all components except the time zone
  • complete: use all components

This makes showing formatted dates inside a SwiftUI app very convenient:

struct ContentView: View {
    let currentDate = Date()

      var body: some View {
          VStack(spacing: 20) {
              Text("Current Date and Time:")
                  .font(.title)
              Text(currentDate.formatted(date: .abbreviated, time: .shortened))
          }
      }
}

Step 6: Working with Time Zones

When working with dates, it’s crucial to consider time zones to accurately represent dates across different regions. Swift provides robust support for handling time zones. Let’s explore how time zones are used in a SwiftUI app with a code example.

struct ContentView: View {

    let currentDate = Date()

    private let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .short
        return formatter
    }()

    var body: some View {
        VStack(spacing: 30) {
           Text("Current Date and Time:")
                .font(.title)
            Text(dateFormatter.string(from: currentDate))

            Text(currentDate.formatted(date: .abbreviated, time: .shortened))

            Divider()

            Text("Date and Time Description")
                .font(.title)
            Text(currentDate.description)
        }
    }
}
Swiftui handles time zones automatically to formate dates.

To demonstrate time zones, we display two pieces of information. The first Text view shows the formatted date and time using the dateFormatter.string(from: Date()) method. This representation is formatted according to the device’s time zone. SwiftUI gets the current value and pass its value in the environment:

@Environment(\.timeZone) var zone

The second Text view displays the description of the current Date object using the Date().description property. This description follows the UTC (Coordinated Universal Time) standard, which is a global time reference.

By including the second Text view, we can observe how the time zone affects the presentation of the date and time. It provides the same date and time description in the UTC time zone, which serves as a reference point for comparison.

Time Zone Conversions: How can you convert a date and time from one time zone to another in an iOS app?

To begin, you can access the user’s current time zone using the TimeZone.current property. This gives you the time zone that is currently set on the device.

let userTimeZone = TimeZone.current
print("User's Time Zone: \(userTimeZone.identifier)")

In the above example, I obtain the current time zone and print its identifier, which represents the specific time zone (e.g., “America/New_York” or “Asia/Tokyo”).

If you need to work with a specific time zone other than the user’s current time zone, you can create a TimeZone instance with a specific identifier.

let newYorkTimeZone = TimeZone(identifier: "America/New_York")
let tokyoTimeZone = TimeZone(identifier: "Asia/Tokyo")

Once you have a time zone, you can use it to convert dates from one time zone to another. DateFormatter allows you to set the desired time zone to use when formatting or parsing dates.

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = newYorkTimeZone

let date = dateFormatter.date(from: "2023-05-19 10:30:00")

dateFormatter.timeZone = tokyoTimeZone

let formattedDate = dateFormatter.string(from: date!)
print("Formatted Date in Tokyo: \(formattedDate)")

In the above example, I set the timeZone property of the dateFormatter to the New York time zone. Then, I convert a date string to a Date object using that time zone. Afterward, I set the dateformatter instance timeZone property to the Tokyo time zone and format the date accordingly.

By working with time zones, you can ensure that your app displays and handles dates correctly, taking into account the local time preferences of the user or the specific time zones you need to support.

Free SwiftUI Layout Book

Get Hands-on with SwiftUI Layout.

Master SwiftUI layouts with real-world examples and step-by-step guide. Building Complex and Responsive Interfaces.

Step 7: Handling Locale-Specific Date Format

Understanding locales is key when dealing with date and time formatting. A locale is essentially a specific geographical or cultural region. It affects the language, number, currency, date, and time formatting in your app.

Swift and SwiftUI offer great support for locale-specific formatting. The Locale struct in Swift represents cultural conventions, including the conventions for language, region, calendar, and units of measure.

In the realm of date formatting, locale determines the structure of the date string. When you use DateFormatter in Swift, you can specify a locale to be used for formatting dates:

let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.locale = Locale(identifier: "en_US")
let date = Date()

let formattedDate = dateFormatter.string(from: date)
print("Formatted Date: \(formattedDate)")
// prints: May 20, 2023

In the above example, I’ve set the locale of the DateFormatter to American English (“en_US”). You have to specify the shorthand name of the language and optional specify the local for different countries.

For example, changing the locale to German use the identifier “de”:

dateFormatter.locale = Locale(identifier: "de")

let formattedDate = dateFormatter.string(from: date)
print("Formatted Date in Germany: \(formattedDate)")
// prints: 20.05.2023

You don`t need to set the local. DateFormatter gets the user’s locale automatically.

Locale property in SwiftUI

For previewing layouts with different locales in SwiftUI, you can use the environment modifier to set the locale. This enables your app to adapt to different languages and region settings. Here’s how you can access the current locale:

@Environment(\.locale) var locale

This allows you to verify that your app correctly adapts to different cultural conventions:

Text(formattedDate)
   .environment(\.locale, .init(identifier: "en_US"))
   
Text(formattedDate)
    .environment(\.locale, .init(identifier: "en_GB"))

In summary, handling locale-specific date formats can make your app more flexible and accommodating to a wider user base. By using the tools provided by Swift and SwiftUI, you can ensure that your app accurately represents date and time information in a way that respects the cultural and geographical conventions of your users.

Step 8: Parsing Strings into Dates

Another crucial aspect of handling dates in Swift is parsing date strings into Date objects. This process becomes particularly important when interacting with APIs, which often transmit dates as strings.

For APIs, one of the most commonly used date formats is the ISO 8601 standard. ISO 8601 represents dates and times as strings in a format that is both human-readable and easy to parse, like so: “2023-05-20T10:30:00Z”. The “T” separates the date and time, and the “Z” indicates that the time is in Coordinated Universal Time (UTC).

To parse an ISO 8601 date string in Swift, you can use the ISO8601DateFormatter class. This class provides methods for converting between Date objects and their ISO 8601 string representations:

let iso8601String = "2023-05-20T10:30:00Z"
let formatter = ISO8601DateFormatter()
let date = formatter.date(from: iso8601String)

In the above code, I initialize an ISO8601DateFormatter and then use its date(from:) method to convert the ISO 8601 string into a Date object. The resulting date is a Date object that represents the date and time specified in the string.

Remember, if you need to convert Date objects back into ISO 8601 strings, you can use the string(from:) method of ISO8601DateFormatter:

let backToString = formatter.string(from: date!)

With these tools, Swift provides a straightforward way to parse strings into Date objects and format Date objects into strings. This ensures that you can effectively handle date information when interacting with APIs or other external data sources that use string representations of dates.

How to change string date format in Swift?

Let’s consider a scenario where you receive a date string in one format and need to parse it into a different format.

First, you’ll need a DateFormatter to parse the initial string into a Date object. This formatter’s dateFormat property should match the format of the original date string. If the formats dont match, the formatter will return nil:

let originalDateString = "2023-05-20 10:30:00"
let originalFormat = DateFormatter()

originalFormat.dateFormat = "yyyy-MM-dd HH:mm:ss"
let date = originalFormat.date(from: originalDateString)

In the code above, I have an original date string in “yyyy-MM-dd HH:mm:ss” format. The DateFormatter is set to this same format to correctly interpret the string as a Date object.

Next, if you need to output this Date object in a different format, you can use another DateFormatter. This second formatter should be set to your desired output format:

let outputFormat = DateFormatter()
outputFormat.dateFormat = "MM-dd-yyyy HH:mm"

if let date = date {
    let newDateString = outputFormat.string(from: date)
    print("New Date String: \(newDateString)")
}

Here, I’ve created a new DateFormatter with the desired output format, “MM-dd-yyyy HH:mm”. Using the string(from:)method, the Date object is converted into a new string format. The result is a new date string in the desired format.

Step 9: Storing a Date in a Database

Storing dates in a database when developing an iOS app is a common requirement. The best practice is to store dates in a universal standard format string that is not affected by time zone differences. For this, Unix timestamp or UTC formatted string are widely used.

A Unix timestamp is the number of seconds that have passed since 00:00:00 UTC on 1 January 1971, not counting leap seconds. It’s an integer and time zone-agnostic, making it easy to convert to any local time zone when retrieving from the database. To convert a Swift Date to a Unix timestamp, use the timeIntervalSince1970 property:

let date = Date()
let timestamp = date.timeIntervalSince1970
// shows something like 1684578555.8512502

Alternatively, you could use UTC formatted strings, especially when using SQL databases. ISO 8601 formatted strings as mentioned in the previous sections work well for this purpose.

As for Core Data, Apple’s object graph and persistence framework, it stores dates using the Date type, which internally represents a point in time relative to an absolute reference date—the same reference as Unix timestamps (00:00:00 UTC on 1 January 1971).

Remember, the Date type in Swift (and thereby Core Data) doesn’t contain any time zone information—it represents an absolute point in time. You should handle time zone conversion when you display dates to the user.

The best practice for storing dates in a database involves using a format that’s unaffected by time zone differences and then handling time zone conversion at the point where you present the date to the user.

Step 10: Date and Time Calculations

Swift provides robust APIs for performing date time calculations, ranging from simple date comparisons to more complex interval calculations.

Getting a Date in the Past or Future

You can use the DateComponents struct in combination with the Calendar API to calculate dates in the past or future. For instance, to calculate a date 7 days from now:

let now = Date()
let sevenDaysLater = Calendar.current.date(byAdding: .day, value: 7, to: now)

In this example, I’ve used the date(byAdding:value:to:) method to add 7 days to the current date.

Calculating the Difference Between Two Dates

To calculate the difference between two dates in terms of days, hours, minutes, or seconds, you can use the dateComponents(_:from:to:) method:

let now = Date()
let futureDate = Calendar.current.date(byAdding: .day, value: 7, to: now)!
let components = Calendar.current.dateComponents([.day, .hour, .minute, .second], 
                                                 from: now, to: futureDate)

print("future date is in \(components.day)days,\(components.hour)hours and  \(components.minute) min from now")

In this case, the dateComponents method is used to calculate the difference between now and futureDate.

Date Comparisons: How can you check if a date falls within a certain range in Swift?

To check if a date falls within a certain range or to compare two dates, Swift provides several methods like isInToday, isInTomorrow, isInYesterday, isInWeekend, isInPast, isInFuture, and more:

if date1.isInToday {
    print("Date is in today")
}

if date1 < date2 {
    print("Date1 is earlier than Date2")
}

Understanding date time calculations allow you to create more dynamic and user-friendly iOS applications, from scheduling notifications to limiting user actions based on time.

Conclusion

Working with dates and times is a fundamental part of iOS development. Whether you’re storing dates in a database, calculating time differences, scheduling notifications, or simply displaying dates and times, understanding Swift’s robust date time APIs is essential.

In this guide, we’ve explored various aspects of date time handling in Swift, including how to format dates, work with time zones, handle locale-specific formats, parse strings into dates, and more. We’ve also seen how to store dates in databases, perform date calculations, schedule notifications, and control user actions based on time.

Remember, the key to effectively handling dates and times in your app is to always work in UTC and convert to the local time zone only for display. Also, keep cultural differences in mind and make use of locale settings where needed.

By keeping these principles in mind and leveraging Swift’s powerful date and time capabilities, you’ll be well-equipped to handle any date and time requirements in your iOS app development projects. Keep practicing and exploring the many possibilities offered by Swift and SwiftUI to continue enhancing your skills and knowledge.

1 thought on “Swift Date Formatting: 10 Steps Guide”

Leave a Comment

Subscribe to My Newsletter

Want the latest iOS development trends and insights delivered to your inbox? Subscribe to our newsletter now!

Newsletter Form