Skip to content

Instantly share code, notes, and snippets.

@hohl
Created June 13, 2016 19:50
Show Gist options
  • Save hohl/b7f74b7e8eb62d532b8aecfa9f4c4f57 to your computer and use it in GitHub Desktop.
Save hohl/b7f74b7e8eb62d532b8aecfa9f4c4f57 to your computer and use it in GitHub Desktop.
//
// rfc3339.swift
// Alwyzon for iPhone and iPad
//
import Foundation
/// Parse RFC 3339 date string to NSDate
///
/// :param: rfc3339DateTimeString string with format "yyyy-MM-ddTHH:mm:ss.SSS"
/// :returns: NSDate, or nil if string cannot be parsed
public func dateForRFC3339DateTimeString(rfc3339DateTimeString: String) -> NSDate? {
let formatter = getThreadLocalRFC3339DateFormatter()
return formatter.dateFromString(rfc3339DateTimeString)
}
/// Generate RFC 3339 date string for an NSDate
///
/// :param: date NSDate
/// :returns: String
public func rfc3339DateTimeStringForDate(date: NSDate) -> String {
let formatter = getThreadLocalRFC3339DateFormatter()
return formatter.stringFromDate(date)
}
// Date formatters are not thread-safe, so use a thread-local instance
private func getThreadLocalRFC3339DateFormatter() -> NSDateFormatter {
return cachedThreadLocalObjectWithKey("com.alwyzon.getThreadLocalRFC3339DateFormatter") {
let en_US_POSIX = NSLocale(localeIdentifier: "en_US_POSIX")
let rfc3339DateFormatter = NSDateFormatter()
rfc3339DateFormatter.locale = en_US_POSIX
rfc3339DateFormatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS"
rfc3339DateFormatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
return rfc3339DateFormatter
}
}
/// Return a thread-local object, creating it if it has not already been created
///
/// :param: create closure that will be invoked to create the object
/// :returns: object of type T
private func cachedThreadLocalObjectWithKey<T: AnyObject>(key: String, create: () -> T) -> T {
let threadDictionary = NSThread.currentThread().threadDictionary
if let cachedObject = threadDictionary[key] as? T {
return cachedObject
}
else {
let newObject = create()
threadDictionary[key] = newObject
return newObject
}
}
//
// rfc3339Tests.swift
// Alwyzon for iPhone and iPad
//
import UIKit
import XCTest
@testable import Alwyzon
class RFC3339Test: XCTestCase {
let en_US_POSIX = NSLocale(localeIdentifier: "en_US_POSIX")
let utcTimeZone = NSTimeZone(forSecondsFromGMT: 0)
lazy var calendar: NSCalendar = {
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
cal.locale = self.en_US_POSIX
cal.timeZone = self.utcTimeZone
return cal
}()
let calendarUnits: NSCalendarUnit = [.Year, .Month, .Day, .Hour, .Minute, .Second]
func testUTCStringToDate() {
let string = "1967-01-17T16:34:25.123"
let optDate = dateForRFC3339DateTimeString(string)
XCTAssertNotNil(optDate)
if let date = optDate {
let components = calendar.components(calendarUnits, fromDate: date)
XCTAssertEqual(1967, components.year)
XCTAssertEqual(1, components.month)
XCTAssertEqual(17, components.day)
XCTAssertEqual(16, components.hour)
XCTAssertEqual(34, components.minute)
XCTAssertEqual(25, components.second)
}
}
}