0
votes

I am new to iOS development, being an Android developer I am used to use have an object that saves a datetime with a given timezone (from Joda-Time library).

After reading the iOS documentation about dates and times (https://developer.apple.com/documentation/foundation/dates_and_times) I still have doubts about which class should I use to save datetimes. Given the Date/NSDate class description "A specific point in time, independent of any calendar or time zone." it seems very useless because it is timezone independent and time without a timezone does not make any sense, since it does not have any context.

My real problem (TL;DR):

I have a database where date times are stored in UTC like this "yyyy-MM-dd hh:mm:ss". I would like to init an object with some kind of DateFormatter (string with this format "yyyy-MM-dd hh:mm:ss") plus a timezone (UTC) to easily convert to any Timezone that I want (to show to the user on his default timezone time). How can I accomplish this in iOS?

Edit: Imagine I have a class Event with a title and a start time. Title is a String, what start time should be?

2
You state "time without a timezone does not make any sense". That's plain wrong. Of course it makes sense. A Date is a point in time. If I say "now", that is a point in time that is the same for everyone in the world. The timezone is irrelevant until someone wants to know "what time was that 'now' in my timezone?". Then you simply format that Date into a String with the given timezone. - rmaddy
@rmaddy I might have to disagree with you. Imagine that someone gives you this time annotation "1970-12-12 11:40:30". You don't know when it started, it's inconclusive. What you are describing are seconds passed after an event, which is the same for all contexts. You have to give some start point, which is what timezone does. - Exprove
But the string "1970-12-12 11:40:30" isn't a Date. It's a string. You will convert that string to a Date based on a specific timezone. Once you have the Date, you store it. Later you retrieve it and you can convert that Date to a string again for any timezone you want. That's the point. The Date object has no specific timezone and it doesn't need one. - rmaddy
@Exprove No, don't think about Date being UTC. It's not any timezone. It's just a point in time. Period. - rmaddy
@LeoDabus The fact that internally a Date is represented as a time interval since a certain epoch in no way means that a Date can be thought of as being in UTC time. - rmaddy

2 Answers

1
votes

You use a DateFormatter for this.

let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = TimeZone(secondsFromGMT: 0)

The formatter.locale sets the current locale for the user and formatter.dateFormat sets the desired date format. In your case yyyy-MM-dd HH:mm:ss.

To call it simply:

let utcDateFromServer = "2017-01-01 22:10:10"
let date = formatter.date(from: utcDateFromServer)
0
votes

A Date is a point in time, as mentioned in other comments & in the documentation.

If you want to convert the UTC time into local time, you'll need to first convert the String "yyyy-MM-dd hh:mm:ss" from your database into a Date using DateFormatter.

let dateStringUTC = "2018-01-01 00:00:00"

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
//Set the input timezone (if you don't set anything, the default is user's local time)
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let date : Date = dateFormatter.date(from: dateStringUTC)! 

Then convert the Date back into String using DateFormatter with the respective TimeZone

let outputDateFormatter = DateFormatter()
outputDateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
//Set the output timezone (if you don't set anything, the default is user's local time)
//outputDateFormatter.timeZone = someTimeZone
let dateString = outputDateFormatter.string(from: date)

print(dateString)

Output: 2017-12-31 17:00:00

And you can just change the input and output timezone to do the opposite.