1

I working on an app that receives events from the backend. The dates are returned in UTC+0 timezone. The app has to show the starting time in the device time zone. So I have developed a function to recalculate the date.

So far I am in UK and I have changed the device time zone to be in Spain. The code I have written is:

static func reCalculateDeviceDate(from date: Date?) -> Date? {
    guard let date = date else { return nil }

    print("Input date: ", date)

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
    dateFormatter.timeZone = .current
    dateFormatter.locale = Locale.current

    let dateString = dateFormatter.string(from: date)
    let outputDate = dateFormatter.date(from: dateString)
    print("Recalculate date in string format: ", dateString)
    print("Output Date: ", outputDate!)

    return dateFormatter.date(from: dateString)
}

The output:

Input date:  2020-02-10 15:47:43 +0000
Recalculated date in string format:  2020-02-10 16:47:43
Output Date:  2020-02-10 15:47:43 +0000

Despite dateString shows the recalculated date, the outputDate it's wrongly created.

What am I missing?

Reimond Hill
  • 4,278
  • 40
  • 52
  • I quite don't understand why dateFormatter(from: dateString) returns a different date nor why it can't be done nor the down vote. My question was, is it possible and why I get a different output? – Reimond Hill Feb 10 '20 at 16:03

2 Answers2

2

Basically, your date is a date. You don't need to change it, and you must not change it. It makes a reference to an exact point in time. You might represent that date in myriads of formattings, for example, in UTC+1, but the date remains the same.

Imagine that right now you click a button and store a date. The stored date would be 17:00 10/02/2020 in UTC+0.

You mustn't change that date. You have to show it to your users accordingly to his timezone. For a spanish (UTC+1) user, when you pressed that button it was 18:00 10/02/2020. For a NYC (UTC-5) citizen, it was 12:00 10/02/2020. And so goes with each country and timezone. But the date remains intact, you only change the representation.

TL;DR: You're doing it right, your code is fine.

IloneSP
  • 429
  • 2
  • 13
1
  1. A time point is the same for different countries. But a string representation is different for different time zones
  2. You get the right string representation for Spain (dateString)
  3. The print function takes a string form the description property. This value is equal to representation for time zone +0000, i.e. for Greenwich, England
Emin A. Alekperov
  • 1,067
  • 1
  • 16
  • 26
  • Thank you for the answer. Should I just use the dateString? This app needs to work in other countries than UK. So far I see +0000. I wonder what people in Spain, Chicago ... will see and how I can test it. – Reimond Hill Feb 10 '20 at 16:46
  • It depends. If you need only a date string to show then you may use the dateString. But if you need to use different parts of a date (day, month, year), you should use an input date. And get an appropriate strings (parts) at place. There is no need to create a new date object. – Emin A. Alekperov Feb 10 '20 at 19:38