Last active
March 7, 2017 12:25
-
-
Save MattCheetham/c717648e9604d19615d7ee89dbc695aa to your computer and use it in GitHub Desktop.
Swift date formatting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: Playground - noun: a place where people can play | |
import UIKit | |
/// We're working with appointments. | |
/// So I get this string from the server and in some places I need to display it in the users local timezone and in other places I need to display it as the time and date that it was booked | |
var serverTimeString = "2017-03-21T19:00:00-07:00" | |
let localisedDateFormatter = DateFormatter() | |
localisedDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" | |
// Displays as March 22nd, 2am (GMT) - CORRECT | |
var date = localisedDateFormatter.date(from: serverTimeString) | |
// TO DO: Output date as March 21st, 7pm. | |
// ?? |
That's not really how date formatting should work. I dunno the ins and outs of where the input date comes from but sounds like you want to discard the timezone completely and display it to the user as 2017-03-21T19:00:00
but nicely formatted?
Best way to do that would be to ignore the Z
component from the input string and then make sure the api date formatter and the ui date formatter have matching timezones but to do that you will need to update your input value (get them to change the API or manipulate the string)
Something like this:
/// We're working with appointments.
/// So I get this string from the server and in some places I need to display it in the users local timezone and in other places I need to display it as the time and date that it was booked
let serverTimeString = "2017-03-21T19:00:00-07:00"
// TODO: ensure the string is at least 19 chars before manipulating
let manipulatedString = serverTimeString.substring(to: serverTimeString.index(serverTimeString.startIndex, offsetBy: 19))
let timeZone = TimeZone(secondsFromGMT: 0)
// A formatter with a FIXED locale for formatting the input date (from the API?)
let apiFormatter = DateFormatter()
apiFormatter.locale = Locale(identifier: "en_US_POSIX")
apiFormatter.timeZone = timeZone
apiFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
// Ignores the concept of a time zone so formats as 19:00:00 GMT
let date = apiFormatter.date(from: manipulatedString)!
// A formatter for showing the date to the user
let uiFormatter = DateFormatter ()
uiFormatter.locale = Locale(identifier: "en_GB")
uiFormatter.timeZone = timeZone
uiFormatter.dateStyle = .medium
uiFormatter.timeStyle = .medium
let display = uiFormatter.string(from: date) // "21 Mar 2017, 19:00:00"
This works, I get Tuesday, 21 March 2017 at 19:00:00 GMT-07:00
do {
let serverTimeString = "2017-03-21T19:00:00-07:00"
let pattern = "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}([\\d:\\-].*)"
let rexp = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let matches = rexp.matches(in: serverTimeString, options: [], range: NSMakeRange(0,25))
let timezone = (serverTimeString as NSString).substring(with: matches.last!.rangeAt(1)) as NSString
let tzParts = timezone.components(separatedBy: ":")
let hours = tzParts[0] as NSString
let minutes = tzParts[1] as NSString
let secondsSinceGMT = (hours.integerValue * 60 * 60) + (minutes.integerValue * 60)
print(secondsSinceGMT)
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssxxxxx"
formatter.timeZone = TimeZone(secondsFromGMT: secondsSinceGMT)
let date = formatter.date(from: serverTimeString)
let displayFormatter = DateFormatter()
displayFormatter.dateStyle = .full
displayFormatter.timeStyle = .full
displayFormatter.timeZone = TimeZone(secondsFromGMT: secondsSinceGMT)
print(displayFormatter.string(from: date!))
} catch {
// something borked
}
Could likely tidy it up. I've used regex and timezone calculations to try and catch any timezone not just -7 hours
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@tmdvs Yeah that's kind of where I'm thinking of going but it feels overkill. I felt like there must have been a simpler way but maybe not. Various examples online of people using substrings to split out the time zone.