Skip to content

Commit

Permalink
Explicit UTC settings and TZ tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriziodemaria committed Apr 5, 2024
1 parent a3a6b4d commit 3b76ca1
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
18 changes: 13 additions & 5 deletions Sources/Confidence/ConfidenceValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@ public class ConfidenceValue: Equatable, Encodable {
self.value = .double(double)
}

/// `date` should have at least precision to the "day".
/// If a custom TimeZone is set for the input DateComponents, the internal serializers
/// will convert the input to the local TimeZone before extracting the calendar day.
public init(date: DateComponents) {
self.value = .date(date)
}

/// If a custom TimeZone is set for the input Date, the internal serializers will convert
/// the input to the local TimeZone before extracting the date (i.e. the local offset
/// information is maintained rather than the one customly set in Date).
public init(timestamp: Date) {
self.value = .timestamp(timestamp)
}
Expand Down Expand Up @@ -211,17 +217,19 @@ extension ConfidenceValueInternal {
case .boolean(let boolean):
try container.encode(boolean)
case .date(let dateComponents):
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateFormatter = ISO8601DateFormatter()
dateFormatter.timeZone = TimeZone.current
dateFormatter.formatOptions = [.withFullDate]
if let date = Calendar.current.date(from: dateComponents) {
try container.encode(dateFormatter.string(from: date))
} else {
throw ConfidenceError.internalError(message: "Could not create date from components")
}
case .timestamp(let date):
let isoFormatter = ISO8601DateFormatter()
let formattedDate = isoFormatter.string(from: date)
try container.encode(formattedDate)
let timestampFormatter = ISO8601DateFormatter()
timestampFormatter.timeZone = TimeZone.current
let timestamp = timestampFormatter.string(from: date)
try container.encode(timestamp)
case .structure(let structure):
try container.encode(structure)
case .list(let list):
Expand Down
22 changes: 17 additions & 5 deletions Tests/ConfidenceTests/ConfidenceValueTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,14 @@ final class ConfidenceConfidenceValueTests: XCTestCase {
XCTAssertEqual(integerListValue.asList(), [ConfidenceValue(integer: 3), ConfidenceValue(integer: 4)])
XCTAssertEqual(doubleListValue.asList(), [ConfidenceValue(double: 3.14), ConfidenceValue(double: 4.0)])
XCTAssertEqual(stringListValue.asList(), [ConfidenceValue(string: "val1"), ConfidenceValue(string: "val2")])
XCTAssertEqual(timestampListValue.asList(), [ConfidenceValue(timestamp: date1), ConfidenceValue(timestamp: date2)])
XCTAssertEqual(dateListValue.asList(), [ConfidenceValue(date: dateComponents1), ConfidenceValue(date: dateComponents2)])
XCTAssertEqual(timestampListValue.asList(), [
ConfidenceValue(timestamp: date1),
ConfidenceValue(timestamp: date2)
])
XCTAssertEqual(dateListValue.asList(), [
ConfidenceValue(date: dateComponents1),
ConfidenceValue(date: dateComponents2)
])
}

func testStructShouldConvertToStruct() {
Expand Down Expand Up @@ -101,8 +107,8 @@ final class ConfidenceConfidenceValueTests: XCTestCase {
func testEncodeDecode() throws {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = TimeZone(abbreviation: "UTC")
let date = try XCTUnwrap(formatter.date(from: "2022-01-01 12:00:00"))
formatter.timeZone = TimeZone(abbreviation: "EDT") // Verify TimeZone conversion
let date = try XCTUnwrap(formatter.date(from: "2024-04-05 16:00:00"))
let dateComponents = DateComponents(year: 2024, month: 4, day: 3)

let value = ConfidenceValue(structure: ([
Expand All @@ -119,6 +125,10 @@ final class ConfidenceConfidenceValueTests: XCTestCase {
let encoder = JSONEncoder()
encoder.outputFormatting = .sortedKeys
let resultString = String(data: try encoder.encode(value), encoding: .utf8)

let isoFormatter = ISO8601DateFormatter()
isoFormatter.timeZone = TimeZone.current
let expectedSerializedTimestamp = isoFormatter.string(from: date)
let expectedString = """
{\"bool\":true,
\"date\":\"2024-04-03\",
Expand All @@ -128,9 +138,11 @@ final class ConfidenceConfidenceValueTests: XCTestCase {
\"null\":null,
\"string\":\"value\",
\"structure\":{\"int\":5},
\"timestamp\":\"2022-01-01T12:00:00Z\"}
\"timestamp\":\"\(expectedSerializedTimestamp)\"}
""".replacingOccurrences(of: "\n", with: "") // Newlines were added for readability

// The "base" timestamp is in UTC, but the local offset is added (e.g. "+002").
XCTAssertTrue(expectedSerializedTimestamp.starts(with: "2024-04-05T22:00:00"))
XCTAssertEqual(resultString, expectedString)
}
}

0 comments on commit 3b76ca1

Please sign in to comment.