Date in Swift printed is wrong

Hello

I wanted to know why when I print(Date()) the date is printed but two hours before?

Example

If I print(Date()) and the actual date is 2021-09-10 22:33:41 +0000, it prints 2021-09-10 20:33:41 +0000 instead of 2021-09-10 22:33:41 +0000.

Why does this happen?

Thank You!

  • ??? Other comments and my examples that we exchanged disappeared from the thread. Have you got things working now the way you want? I'm getting an error when trying to add a new comment to the thread below.

Add a Comment

Accepted Reply

This is because the date is stored in Swift as UTC time, i.e. as at longitude 0.0 - which used to be called Greenwich Mean Time. It doesn't take into account your timezone, nor any Summertime adjustment. When you display the time to the user in your code, via UIKit or SwiftUI, you use a DateFormatter (in UIKit) or Text(date, style: .date) in SwiftUI and the system then recognises and applies your device's timezone (including summertime status) and language. SwiftUI has only limited date formatting capabilities, so I normally use my own formatting function e.g.in SwiftUI Text(myAppAPI.dateToString(date)) where myApAPI is a collection of useful functions I have in a class (myAppAPI) and dateToString is a function that applies the DateFormatter() function, with my applied options, of Swift.

When you use print(date) no formatting is applied, therefore you get the UTC time.

  • And what if I wanted to use if Date() > Date() + 86400 for example, is it formatted?

  • No, comparison of Date types is done on the UTC date-time. If the date-time of your user's timezone is important in decision making, e.g. how many times did the user do X before 10am each day, then you'd need to use the Calendar functions https://developer.apple.com/documentation/foundation/calendar

  • Can you please provide me an example?

Replies

This is because the date is stored in Swift as UTC time, i.e. as at longitude 0.0 - which used to be called Greenwich Mean Time. It doesn't take into account your timezone, nor any Summertime adjustment. When you display the time to the user in your code, via UIKit or SwiftUI, you use a DateFormatter (in UIKit) or Text(date, style: .date) in SwiftUI and the system then recognises and applies your device's timezone (including summertime status) and language. SwiftUI has only limited date formatting capabilities, so I normally use my own formatting function e.g.in SwiftUI Text(myAppAPI.dateToString(date)) where myApAPI is a collection of useful functions I have in a class (myAppAPI) and dateToString is a function that applies the DateFormatter() function, with my applied options, of Swift.

When you use print(date) no formatting is applied, therefore you get the UTC time.

  • And what if I wanted to use if Date() > Date() + 86400 for example, is it formatted?

  • No, comparison of Date types is done on the UTC date-time. If the date-time of your user's timezone is important in decision making, e.g. how many times did the user do X before 10am each day, then you'd need to use the Calendar functions https://developer.apple.com/documentation/foundation/calendar

  • Can you please provide me an example?

And what if I wanted to write if Date() > Date() + 86400 for example, is it formatted?

Mm, comments don't format very well. Here it is again....

let currentHour = Calendar.current.component(.hour, from: Date())
if currentHour < 12 {print("now is morning")}

This gets the hour, as an Integer, from the current local time, i.e. the Calendar function converts the UTC time to the user's current timezone and summertime (or not) settings. 

I suggest that you experiment with Date formatting and with Calendar in a Playground.

let date = Calendar.current.dateComponents(in: .current, from: Date()).date! 
print(date)

The .date! at the end of the first line converts the date back to UTC.

To format the date in local time do this:

let df = DateFormatter()
df.dateStyle = .full
df.timeStyle = .full
print(df.string(from: Date()))

You have options of full, medium, long, short and none for both time and date. If this doesn't suit, you can set your own formatting

df.dateFormat = "yyyy-MM-dd HH:mm:ss.SS"

which right now would give 2021-09-11 10:14:23.33 in Sydney time. You adjust the formatting tokens to suit your own needs, e.g. MM-dd-yy HH:mm would give 09-11-21 10:14

Regards, Michaela

  • Thank you very much for your help. It is true that formatting the date and then converting it to string prints the right date, however I cannot compare dates anymore if I convert them to strings. Because in my project I am trying to compare dates and not just integers.

    Thank you very much for your time.

  • Sorry for the delay: there seems to have been a problem with the forum software and I was getting an error when attempting to respond. You only format the dates at the point of displaying them to the user: for all other purposes, you must use the original dates for comparisons and computations - except where you want specific information about the local date-time e.g. whether it's morning or not, in which case you use the Calendar functions with the date (not the formatted string).

  • Thank you very much

Add a Comment