Try this:
import Foundation
func stringForDate(date: NSDate, includeTime: Bool = true) -> String {
var buffer = [Int8](count: 17, repeatedValue: 0)
var time = time_t(date.timeIntervalSince1970)
let format = includeTime ? "%Y%m%dT%H%M%SZ" : "%Y%m%d"
strftime_l(&buffer, buffer.count, format, localtime(&time), nil)
return String.fromCString(buffer)!
}
print(stringForDate(NSDate(timeIntervalSinceReferenceDate: 0.0)))
// prints "20010101T000000Z"
The trick is to realise that
time_t
is a
__darwin_time_t
is an
Int
, so you can just initialise it from the
NSTimeInterval
(aka
Double
) returned by
timeIntervalSince1970
.
Be aware that Swift will trap if that conversion is out of bounds. That’s unlikely on 64-bit systems but something to watch out for if you deploy to iOS (which supports Swift on 32-bit systems).
To answer the "Just use NSDateFormatter"...no. This code will be called tons of time where it's not convenient to pass in a date formatter, and so I don't want to constantly create them. Also, I need an EXACT date format spit out, and the documentation for NSDateFormatter says that setting the dateFormat property doesn't guarantee you'll get that exact format.
While I don’t want to be seen advocating NSDateFormatter for this sort of thing, neither of your objections is a showstopper:
On modern systems NSDateFormatter is thread safe, so you can have a single global date formatter and use that everywhere.
IMPORTANT For the details on the thread safety of NSDateFormatter, see NSDateFormatter Class Reference.
NSDateFormatter is intended to be used for localised dates, but it is possible to force it to create a fixed-format date. QA1480 NSDateFormatter and Internet Dates has the details.
Having said that,
strftime_l
is a good alternative, something that I pointed out at the bottom of QA1480.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
DTS will close for the winter holidays at the end of business on Wed, 23 Dec 2015 and re-open on Mon, 4 Jan 2016.