Skip to content

Commit

Permalink
Adds support for the RFC2822 date format (marksands#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
tapi authored and marksands committed Jan 8, 2020
1 parent aa8f6c6 commit b746807
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
29 changes: 29 additions & 0 deletions Sources/BetterCodable/RFC2822Strategy.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Foundation

/// Decodes `String` values as an RFC 2822 `Date`.
///
/// `@RFC2822Date` decodes RFC 2822 date strings into `Date`s. Encoding the `Date` will encode the value back into the original string value.
///
/// For example, decoding json data with a `String` representation of `"Tue, 24 Dec 2019 16:39:57 -0000"` produces a valid `Date` representing 39 minutes and 57 seconds
/// after the 16th hour of December 24th, 2019 with an offset of -00:00 from UTC (Pacific Standard Time).
public struct RFC2822Strategy: DateValueCodableStrategy {
private static let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "EEE, d MMM y HH:mm:ss zzz"
return dateFormatter
}()

public static func decode(_ value: String) throws -> Date {
if let date = RFC2822Strategy.dateFormatter.date(from: value) {
return date
} else {
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "Invalid Date Format!"))
}
}

public static func encode(_ date: Date) -> String {
return RFC2822Strategy.dateFormatter.string(from: date)
}
}
10 changes: 10 additions & 0 deletions Tests/BetterCodableTests/DateValueTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ class CustomDateCodableValueTests: XCTestCase {
let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData)
XCTAssertEqual(fixture.rfc3339Date, Date(timeIntervalSince1970: 851042397))
}

func testDecodingAndEncodingRFC2822DateString() throws {
struct Fixture: Codable {
@DateValue<RFC2822Strategy> var rfc2822Date: Date
}
let jsonData = #"{"rfc2822Date": "Fri, 27 Dec 2019 22:43:52 -0000"}"#.data(using: .utf8)!

let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData)
XCTAssertEqual(fixture.rfc2822Date, Date(timeIntervalSince1970: 1577486632))
}

func testDecodingAndEncodingUTCTimestamp() throws {
struct Fixture: Codable {
Expand Down

0 comments on commit b746807

Please sign in to comment.