I have dates saved in a database in this format - "yyyy-MM-dd'T'HH:mm:ssZ". For example, "2018-05-17T11:15:00+0330". The time zone varies, it is in whatever user's local time zone is.
I want to retrieve and display the date like "May 17, 2018 11.15AM", keeping the date/time in the same time zone as it was saved. How can I do that?
I tried this.
let dateString = "2018-05-17T11:15:00+0330"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
//formatter.timeZone = ???
print(formatter.date(from: dateString))
But I get the Date object in local timezone and converting that to date string displays the date in my local timezone as well.
Is there anything like this, https://stackoverflow.com/a/46216251/1373592, in Swift?
Thanks.
What you are really trying to do, is to ignore the time zone.
You can just strip off the last 5 characters from the date string, parse it in one format, and format it in another format:
let dateString = "2018-05-17T11:15:00+0330"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let date = formatter.date(from: String(dateString.dropLast(5)))! // note the stripping off here
formatter.dateFormat = "MMMM d, yyyy hh.mma"
print(formatter.string(from: date))
Note that you can't compare this date with other dates because you've stripped its time zone off.
Also, SwiftDate is a similar library to JodaTime.
Here's a little extension to TimeZone
I just whipped up. You can use it to create a TimeZone
from an ISO8601 date string. It will handle timezones in the string in the following formats:
Here is the extension:
extension TimeZone {
init?(iso8601: String) {
let tz = iso8601.dropFirst(19) // remove yyyy-MM-ddTHH:mm:ss part
if tz == "Z" {
self.init(secondsFromGMT: 0)
} else if tz.count == 3 { // assume +/-HH
if let hour = Int(tz) {
self.init(secondsFromGMT: hour * 3600)
return
}
} else if tz.count == 5 { // assume +/-HHMM
if let hour = Int(tz.dropLast(2)), let min = Int(tz.dropFirst(3)) {
self.init(secondsFromGMT: (hour * 60 + min) * 60)
return
}
} else if tz.count == 6 { // assime +/-HH:MM
let parts = tz.components(separatedBy: ":")
if parts.count == 2 {
if let hour = Int(parts[0]), let min = Int(parts[1]) {
self.init(secondsFromGMT: (hour * 60 + min) * 60)
return
}
}
}
return nil
}
}
And a test:
print(TimeZone(iso8601: "2018-05-17T11:15:00+0330"))
You can combine this parsing and formatting so the final result is in the original timezone.
let dateString = "2018-05-17T11:15:00+0330"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
formatter.locale = Locale(identifier: "en_US_POSIX")
if let date = formatter.date(from: dateString), let tz = TimeZone(iso8601: dateString) {
let newFmt = DateFormatter()
newFmt.dateStyle = .medium
newFmt.timeStyle = .short
newFmt.timeZone = tz
let newString = newFmt.string(from: date)
print(newString)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With