Home > Enterprise >  Timezone in swift
Timezone in swift

Time:02-22

I am struggling quite a bit with dates. I have the following code:

Current Date in Amsterdam: 22-Februari-2022 - 11:40

Current Date in New York: 22-Februari-2022 - 05:40

The dateBoughtString goes in as follows: 2022-02-18T19:50:47.081Z The current date is just the current date.

let dateFormatterNew = DateFormatter()
    dateFormatterNew.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
    dateFormatterNew.timeZone = TimeZone(abbreviation: "GMT 1:00")
    dateFormatterNew.locale = Locale(identifier: "nl-NL")
    let dateBoughtTemp = dateFormatterNew.date(from: positionStatsString[0])!

    print(dateBoughtTemp) // Prints: 2022-02-18 18:50:47  0000
    
    dateFormatterNew.timeZone = TimeZone(abbreviation: "GMT-5:00")
    dateFormatterNew.locale =  Locale(identifier: "en_US")
    let dateNowTemp = dateFormatterNew.string(from: Date())
    let dateBoughtTempTwo = dateFormatterNew.string(from: dateBoughtTemp)

    print(dateNowTemp) // Prints: 2022-02-22T05:41:49.973Z
    print(dateBoughtTempTwo) // Prints: 2022-02-18T13:50:47.081Z

    let dateNow = dateFormatterNew.date(from: dateNowTemp)
    let dateBought = dateFormatterNew.date(from: dateBoughtTempTwo)

    print(dateNow!)  // Prints: 2022-02-22 10:41:49  0000 **INCORRECT**
    print(dateBought!) // Prints: 2022-02-18 18:50:47  0000 **INCORRECT**

When I convert to string all seems fine and it works as it should. But when I convert those strings back to a date they just go back to Amsterdam time with the current date even being one hour off.

What am I missing here?

CodePudding user response:

Use the below code for formatter, Change the timezone and dateFormat according to your need. let formatter = DateFormatter() formatter.calendar = Calendar(identifier: Calendar.Identifier.iso8601) formatter.locale = Locale(identifier: "en_US_POSIX") formatter.timeZone = TimeZone(secondsFromGMT: 0) formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"

CodePudding user response:

The problem is in your's parameter 'Z': '' means that it's content doesn't involved in time formatting. So when you apply timeZone parameter date is printed in particular time zone without correct timeZone suffix and when it's scanned it's scanned in particular time zone, just expecting that there will by Z character at the end. So when you are formatting to date and then to string you are accumulating error caused by timezone difference.

Correct format will be "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" or better to use ISO8601DateFormatter because you can't set invalid format in it.

So your printed dates will have valid timezone suffix and timezone suffix will be considered in backward conversion.

Another moment: you shouldn't convert string back to date with localized formatter, if it's UI part, but for that you can use UIDatePicker instead of UITextField.

So full code will be:

let isoDateFormatter = ISO8601DateFormatter()
isoDateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let date = isoDateFormatter.date(from: "2022-02-18T19:50:47.081Z")!
let now = Date()

do {
    let amsterdamDateFormatter = DateFormatter()
    amsterdamDateFormatter.timeZone = .init(abbreviation: "GMT 1:00")
    amsterdamDateFormatter.dateStyle = .long
    amsterdamDateFormatter.timeStyle = .short

    print("now in Amsterdam: \(amsterdamDateFormatter.string(from: now))")
    print("time in Amsterdam: \(amsterdamDateFormatter.string(from: date))")
}

do {
    let newYourkDateFormatter = DateFormatter()
    newYourkDateFormatter.timeZone = .init(abbreviation: "GMT-5:00")
    newYourkDateFormatter.dateStyle = .long
    newYourkDateFormatter.timeStyle = .short

    print("now in NY: \(newYourkDateFormatter.string(from: now))")
    print("time in NY: \(newYourkDateFormatter.string(from: date))")
}
  • Related