Skip to content

Commit

Permalink
Handle daylight savings time properly
Browse files Browse the repository at this point in the history
  • Loading branch information
vishnuravi committed Dec 29, 2024
1 parent 6c703ee commit 7037548
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,21 @@ import ModelsR4

extension Observation {
func setEffective(startDate: Date, endDate: Date, timeZone: TimeZone) {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = timeZone
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"

if startDate == endDate {
effective = .dateTime(
FHIRPrimitive(
try? DateTime(
date: startDate,
timeZone: timeZone
)
try? DateTime(dateFormatter.string(from: startDate))
)
)
} else {
effective = .period(
Period(
end: FHIRPrimitive(try? DateTime(date: endDate, timeZone: timeZone)),
start: FHIRPrimitive(try? DateTime(date: startDate, timeZone: timeZone))
end: FHIRPrimitive(try? DateTime(dateFormatter.string(from: endDate))),
start: FHIRPrimitive(try? DateTime(dateFormatter.string(from: startDate)))
)
)
}
Expand Down
49 changes: 46 additions & 3 deletions Tests/HealthKitOnFHIRTests/TimeZoneTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ class TimeZoneTests: XCTestCase {
)
}

func createDSTDatesFor(timeZone: String) throws -> (start: Date, end: Date) {
let startComponents = DateComponents(year: 2024, month: 4, day: 1, hour: 9, minute: 00, second: 0)
let endComponents = DateComponents(year: 2024, month: 4, day: 1, hour: 10, minute: 45, second: 0)

return (
try getTimeZoneDate(startComponents, timeZoneName: timeZone),
try getTimeZoneDate(endComponents, timeZoneName: timeZone)
)
}

func createObservationFrom(
type quantityType: HKQuantityType,
quantity: HKQuantity,
Expand All @@ -51,7 +61,7 @@ class TimeZoneTests: XCTestCase {
return try XCTUnwrap(quantitySample.resource.get(if: Observation.self))
}

/// Tests specifying the pacific time zone (-08:00) in metadata
/// Tests specifying the pacific standard time zone (-08:00) in metadata
func testPSTTimeZone() throws {
let timeZone = "America/Los_Angeles"
let (startDate, endDate) = try createDatesFor(timeZone: timeZone)
Expand Down Expand Up @@ -84,6 +94,39 @@ class TimeZoneTests: XCTestCase {
)
}

/// Tests specifying the pacific daylight time zone (-7:00) in metadata
func testPSTTimeZoneWithDST() throws {
let timeZone = "America/Los_Angeles"
let (startDate, endDate) = try createDSTDatesFor(timeZone: timeZone)

let observation = try createObservationFrom(
type: HKQuantityType(.stepCount),
quantity: HKQuantity(unit: .count(), doubleValue: 42),
start: startDate,
end: endDate,
metadata: [HKMetadataKeyTimeZone: timeZone]
)

guard case let .period(period) = observation.effective else {
XCTFail("Expected period effective type")
return
}

let startTimestamp = try XCTUnwrap(period.start?.value?.description)
let endTimestamp = try XCTUnwrap(period.end?.value?.description)

XCTAssertEqual(
startTimestamp,
"2024-04-01T09:00:00-07:00",
"Start timestamp should match expected format with timezone"
)
XCTAssertEqual(
endTimestamp,
"2024-04-01T10:45:00-07:00",
"End timestamp should match expected format with timezone"
)
}

/// Tests specifying eastern standard time (-5:00) in metadata
func testESTTimeZone() throws {
let timeZone = "America/New_York"
Expand Down Expand Up @@ -153,12 +196,12 @@ class TimeZoneTests: XCTestCase {
/// Tests that the current time zone is added if a time zone is not specified in metadata
func testDefaultTimeZone() throws {
let startDate: Date = try {
let dateComponents = DateComponents(year: 2024, month: 3, day: 15, hour: 9, minute: 30, second: 0)
let dateComponents = DateComponents(year: 2024, month: 12, day: 1, hour: 9, minute: 00, second: 0)
return try XCTUnwrap(Calendar.current.date(from: dateComponents))
}()

let endDate: Date = try {
let dateComponents = DateComponents(year: 2024, month: 3, day: 15, hour: 10, minute: 45, second: 0)
let dateComponents = DateComponents(year: 2024, month: 12, day: 1, hour: 10, minute: 45, second: 0)
return try XCTUnwrap(Calendar.current.date(from: dateComponents))
}()

Expand Down

0 comments on commit 7037548

Please sign in to comment.