Skip to content

Commit b746807

Browse files
tapimarksands
authored andcommitted
Adds support for the RFC2822 date format (#9)
1 parent aa8f6c6 commit b746807

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import Foundation
2+
3+
/// Decodes `String` values as an RFC 2822 `Date`.
4+
///
5+
/// `@RFC2822Date` decodes RFC 2822 date strings into `Date`s. Encoding the `Date` will encode the value back into the original string value.
6+
///
7+
/// 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
8+
/// after the 16th hour of December 24th, 2019 with an offset of -00:00 from UTC (Pacific Standard Time).
9+
public struct RFC2822Strategy: DateValueCodableStrategy {
10+
private static let dateFormatter: DateFormatter = {
11+
let dateFormatter = DateFormatter()
12+
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
13+
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
14+
dateFormatter.dateFormat = "EEE, d MMM y HH:mm:ss zzz"
15+
return dateFormatter
16+
}()
17+
18+
public static func decode(_ value: String) throws -> Date {
19+
if let date = RFC2822Strategy.dateFormatter.date(from: value) {
20+
return date
21+
} else {
22+
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "Invalid Date Format!"))
23+
}
24+
}
25+
26+
public static func encode(_ date: Date) -> String {
27+
return RFC2822Strategy.dateFormatter.string(from: date)
28+
}
29+
}

Tests/BetterCodableTests/DateValueTests.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ class CustomDateCodableValueTests: XCTestCase {
2121
let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData)
2222
XCTAssertEqual(fixture.rfc3339Date, Date(timeIntervalSince1970: 851042397))
2323
}
24+
25+
func testDecodingAndEncodingRFC2822DateString() throws {
26+
struct Fixture: Codable {
27+
@DateValue<RFC2822Strategy> var rfc2822Date: Date
28+
}
29+
let jsonData = #"{"rfc2822Date": "Fri, 27 Dec 2019 22:43:52 -0000"}"#.data(using: .utf8)!
30+
31+
let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData)
32+
XCTAssertEqual(fixture.rfc2822Date, Date(timeIntervalSince1970: 1577486632))
33+
}
2434

2535
func testDecodingAndEncodingUTCTimestamp() throws {
2636
struct Fixture: Codable {

0 commit comments

Comments
 (0)