Skip to content

Commit

Permalink
Fix date conversion bug losing seconds adjustment
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryu0118 committed Apr 7, 2024
1 parent 326198a commit 16da2a2
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 2 deletions.
51 changes: 51 additions & 0 deletions Sources/TypedDate/TypedDate+components.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,54 @@ public extension TypedDate<(Year, Month, Day, Hour, Minute, Second, Nanosecond)>
calendar.dateComponents([.nanosecond], from: date).nanosecond ?? components.6.value
}
}

extension Date {
/// Returns the year component of `TypedDate<(Year, Month, Day, Hour, Minute, Second)>`.
/// - Parameter calendar: Calendar used for date calculations, defaults to the current calendar.
/// - Returns: Returns the year component of the date as an integer value.
func year(calendar: Calendar) -> Int? {
calendar.dateComponents([.year], from: self).year
}

/// Returns the month component of `TypedDate<(Year, Month, Day, Hour, Minute, Second)>`.
/// - Parameter calendar: Calendar used for date calculations, defaults to the current calendar.
/// - Returns: Returns the month component of the date as an integer value.
func month(calendar: Calendar) -> Int? {
calendar.dateComponents([.month], from: self).month
}

/// Returns the day component of `TypedDate<(Year, Month, Day, Hour, Minute, Second)>`.
/// - Parameter calendar: Calendar used for date calculations, defaults to the current calendar.
/// - Returns: Returns the day component of the date as an integer value.
func day(calendar: Calendar ) -> Int? {
calendar.dateComponents([.day], from: self).day
}

/// Returns the hour component of `TypedDate<(Year, Month, Day, Hour, Minute, Second)>`.
/// - Parameter calendar: Calendar used for date calculations, defaults to the current calendar.
/// - Returns: Returns the hour component of the date as an integer value.
func hour(calendar: Calendar = .current) -> Int? {
calendar.dateComponents([.hour], from: self).hour
}

/// Returns the minute component of `TypedDate<(Year, Month, Day, Hour, Minute, Second)>`.
/// - Parameter calendar: Calendar used for date calculations, defaults to the current calendar.
/// - Returns: Returns the minute component of the date as an integer value.
func minute(calendar: Calendar = .current) -> Int? {
calendar.dateComponents([.minute], from: self).minute
}

/// Returns the second component of `TypedDate<(Year, Month, Day, Hour, Minute, Second)>`.
/// - Parameter calendar: Calendar used for date calculations, defaults to the current calendar.
/// - Returns: Returns the second component of the date as an integer value.
func second(calendar: Calendar = .current) -> Int? {
calendar.dateComponents([.second], from: self).second
}

/// Returns the nanosecond component of `TypedDate<(Year, Month, Day, Hour, Minute, Second)>`.
/// - Parameter calendar: Calendar used for date calculations, defaults to the current calendar.
/// - Returns: Returns the nanosecond component of the date as an integer value.
func nanosecond(calendar: Calendar = .current) -> Int? {
calendar.dateComponents([.nanosecond], from: self).nanosecond
}
}
42 changes: 40 additions & 2 deletions Sources/TypedDate/TypedDate+init.swift
Original file line number Diff line number Diff line change
Expand Up @@ -209,27 +209,35 @@ public extension TypedDate {

extension TypedDate {
init(_ components: Components, calendar: Calendar = .current) {
self.components = components

switch components {
case let components as Year:
self.date = DateComponents(
calendar: calendar,
year: components.value
).date!
self.components = Year(date.year(calendar: calendar) ?? components.value) as! Components
case let components as (Year, Month):
self.date = DateComponents(
calendar: calendar,
year: components.0.value,
month: components.1.value
).date!
self.components = (
Year(date.year(calendar: calendar) ?? components.0.value),
Month(date.month(calendar: calendar) ?? components.1.value)
) as! Components
case let components as (Year, Month, Day):
self.date = DateComponents(
calendar: calendar,
year: components.0.value,
month: components.1.value,
day: components.2.value
).date!
self.components = (
Year(date.year(calendar: calendar) ?? components.0.value),
Month(date.month(calendar: calendar) ?? components.1.value),
Day(date.day(calendar: calendar) ?? components.2.value)
) as! Components
case let components as (Year, Month, Day, Hour):
self.date = DateComponents(
calendar: calendar,
Expand All @@ -238,6 +246,12 @@ extension TypedDate {
day: components.2.value,
hour: components.3.value
).date!
self.components = (
Year(date.year(calendar: calendar) ?? components.0.value),
Month(date.month(calendar: calendar) ?? components.1.value),
Day(date.day(calendar: calendar) ?? components.2.value),
Hour(date.hour(calendar: calendar) ?? components.3.value)
) as! Components
case let components as (Year, Month, Day, Hour, Minute):
self.date = DateComponents(
calendar: calendar,
Expand All @@ -247,6 +261,13 @@ extension TypedDate {
hour: components.3.value,
minute: components.4.value
).date!
self.components = (
Year(date.year(calendar: calendar) ?? components.0.value),
Month(date.month(calendar: calendar) ?? components.1.value),
Day(date.day(calendar: calendar) ?? components.2.value),
Hour(date.hour(calendar: calendar) ?? components.3.value),
Minute(date.minute(calendar: calendar) ?? components.4.value)
) as! Components
case let components as (Year, Month, Day, Hour, Minute, Second):
self.date = DateComponents(
calendar: calendar,
Expand All @@ -257,6 +278,14 @@ extension TypedDate {
minute: components.4.value,
second: components.5.value
).date!
self.components = (
Year(date.year(calendar: calendar) ?? components.0.value),
Month(date.month(calendar: calendar) ?? components.1.value),
Day(date.day(calendar: calendar) ?? components.2.value),
Hour(date.hour(calendar: calendar) ?? components.3.value),
Minute(date.minute(calendar: calendar) ?? components.4.value),
Second(date.second(calendar: calendar) ?? components.5.value)
) as! Components
case let components as (Year, Month, Day, Hour, Minute, Second, Nanosecond):
self.date = DateComponents(
calendar: calendar,
Expand All @@ -268,6 +297,15 @@ extension TypedDate {
second: components.5.value,
nanosecond: components.6.value
).date!
self.components = (
Year(date.year(calendar: calendar) ?? components.0.value),
Month(date.month(calendar: calendar) ?? components.1.value),
Day(date.day(calendar: calendar) ?? components.2.value),
Hour(date.hour(calendar: calendar) ?? components.3.value),
Minute(date.minute(calendar: calendar) ?? components.4.value),
Second(date.second(calendar: calendar) ?? components.5.value),
Nanosecond(date.nanosecond(calendar: calendar) ?? components.6.value)
) as! Components

default:
fatalError(
Expand Down
7 changes: 7 additions & 0 deletions Tests/TypedDateTests/TypedDateAddTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,11 @@ struct TypedDateAddTests {
let typedDate = testSupport.generateTypedSecondDate().add(\.second, 1)
#expect(typedDate.second(calendar: calendar) == testSupport.second.add(1))
}

@Test
func subtractSecond() {
let typedDate = testSupport.generateTypedSecondDate()
let yesterdayTypedDate = typedDate.add(\.second, Second(-(60 * 60 * 24)))
#expect(typedDate.erase(to: \.day) != yesterdayTypedDate.erase(to: \.day))
}
}

0 comments on commit 16da2a2

Please sign in to comment.