I am attempting to convert a UTC formatted date from an API to a human-readable approximation format using Swift.
I'm looking for something like the following:
2015-07-14T13:51:05.423Z
to
About two weeks ago
What is the best approach to this in Swift? While optimally this could format strings directly, I understand that this will probably require casting the string to a NSDate object.
Any help would be greatly appreciated.
EDIT: My question had been identified as a possible duplicate of another question. Tom's solution below is written for Swift and much more elegant than creating a new method in regards to my situation.
dateFormat = "yyyy-MM-dd'T'HH:mm:ss.
In most cases the best locale to choose is "en_US_POSIX", a locale that's specifically designed to yield US English results regardless of both user and system preferences.
Get current time in “YYYY-MM–DD HH:MM:SS +TIMEZONE” format in Swift. This is the easiest way to show the current date-time.
ISO 8601 is the YYYY-MM-DD format to represent date. In ISO8601DateFormatter , Swift expects the time as well: YYYY-MM-DDTHH:MM:SSZ. If we simply need the date without the time, we can set the . withFullDate format option.
You need two steps. First, convert your date string to an NSDate
:
let dateString = "2015-07-14T13:51:05.423Z"
let df = NSDateFormatter()
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = df.dateFromString(dateString)
(If that's not an exact representation of the strings you get, you'll have to change the date format string to get this to convert).
Next, use NSDateComponentsFormatter
to get your desired string:
let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyle.Full
formatter.includesApproximationPhrase = true
formatter.includesTimeRemainingPhrase = false
formatter.allowedUnits = NSCalendarUnit.WeekOfMonthCalendarUnit
if let pastDate = date {
let dateRelativeString = formatter.stringFromDate(pastDate, toDate: NSDate())
}
Today is July 28, so the result for that string is "About 2 weeks". The allowedUnits
attribute is a bit field, so you can specify as many unit types as you want to allow.
As Tom Harrington's answer notes, you can produce a colloquial representation of a moment or a time interval using NSDateComponentsFormatter
.
However, if you want to do exactly what the question asks in its example, which is to produce a colloquial representation of a moment in the past, relative to the present moment, like for a timeline-oriented UI, then it seems like NSDateComponentsFormatter
is not suitable. As the documentation for stringFromTimeInterval(_:)
says, the time interval value "must be a finite number. Negative numbers are treated as positive numbers when creating the string."
As near as I can tell, the best choice is TTTTimeIntervalFormatter
, a standalone class in Mattt Thompson's FormatterKit.
I have produced an Xcode 7 playground, RelativeDatePlayground, that compares the outputs of NSDateFormatter
output to TTTTimeIntervalFormatter
. Here is a table showing output for different relative times in seconds. As you can see, NSDateComponentsFormatter
does not seem to handle past moments or the present moment well:
-1488010 | 2 weeks ago | -1 week remaining
-1468800 | 2 weeks ago | -1 week remaining
-864000 | 1 week ago | 0 seconds remaining
-86400 | 1 day ago | -1 day remaining
-36000 | 10 hours ago | -10 hours remaining
-3600 | 1 hour ago | -1 hour remaining
-600 | 10 minutes ago | -10 minutes remaining
-60 | 1 minute ago | -1 minute remaining
-10 | 10 seconds ago | -10 seconds remaining
-1 | 1 second ago | -1 second remaining
-0 | just now | 0 seconds remaining
0 | just now | 0 seconds remaining
1 | 1 second from now | 1 second remaining
10 | 10 seconds from now | 10 seconds remaining
60 | 1 minute from now | 1 minute remaining
600 | 10 minutes from now | 10 minutes remaining
3600 | 1 hour from now | 1 hour remaining
36000 | 10 hours from now | 10 hours remaining
86400 | 1 day from now | 1 day remaining
864000 | 1 week from now | 1 week remaining
1468800 | 2 weeks from now | 2 weeks remaining
1488010 | 2 weeks from now | 2 weeks remaining
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