Search code examples
swiftcalendartimezonecountdown

Same Countdown in different TimeZone - Swift


I have already create a countdown that's working fine on CEST time zone, but I want that will show the same correct time remaining in all the countries with different Time Zone.

Any idea on how can I manipulate the code?

 // here we set the current date
    let date = NSDate()
    let calendar = Calendar.current

    let components = calendar.dateComponents([.hour, .minute, .month, .year, .day], from: date as Date)

    let currentDate = calendar.date(from: components)

    let userCalendar = Calendar.current

    // here we set the due date. When the timer is supposed to finish
    let competitionDate = NSDateComponents()
    competitionDate.year = year
    competitionDate.month = month
    competitionDate.day = day
    competitionDate.hour = hour
    competitionDate.minute = minute
    let competitionDay = userCalendar.date(from: competitionDate as DateComponents)!

    //here we change the seconds to hours,minutes and days
    let competitionDayDifference = calendar.dateComponents([.day, .hour, .minute], from: currentDate!, to: competitionDay)


    //finally, here we set the variable to our remaining time
    let daysLeft = competitionDayDifference.day
    let hoursLeft = competitionDayDifference.hour
    let minutesLeft = competitionDayDifference.minute

    print("day:", daysLeft ?? "N/A", "hour:", hoursLeft ?? "N/A", "minute:", minutesLeft ?? "N/A")

Solution

  • Your current code doesn't work because the competition day is not represented by a point in time (x seconds since 1970), but as a local date time (year, month, day, hour, minute etc) instead.

    To represent the competition date as a point in time, you need to associate it with a timezone, which you haven't provided. You can provide one to the Calendar that you use to get the Date from the date components:

    var userCalendar = Calendar.current
    userCalendar.timeZone = TimeZone(identifier: "...")!
    

    And then the competition date will be converted to the same point in time no matter what timezone the device is in.

    Alternatively, set competitionDate.timeZone:

    competitionDate.timeZone = TimeZone(identifier: "...")!