Why is dateRemainingText2
giving different result from dateRemainingText
?
Obviously dateRemainingText2
is wrong.
Here's my code:
import Foundation
let startDate = Calendar.current.date(from: DateComponents(year: 2022, month: 5, day: 1)) ?? .now
let endDate = Calendar.current.date(from: DateComponents(year: 2020, month: 6, day: 2)) ?? .now
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.year, .month, .day]
dateComponentsFormatter.unitsStyle = .full
var dateRemainingText = dateComponentsFormatter.string(from: startDate, to: endDate)! // -1 year, 10 months, 29 days
let dateComponents = Calendar.current.dateComponents([.year, .month, .day], from: startDate, to: endDate)
var dateRemainingText2 = dateComponentsFormatter.string(from: dateComponents) // -1 year, 11 months, 1 day
CodePudding user response:
DateComponentsFormatter.string(from:to:)
and DateComponentsFormatter.string(from:)
are different methods and so they can do different things.
From some experimentation, we can see that string(from:)
outputs a string that describes the sum of all the date components in the DateComponent
s passed in.
This just happens to be the same as the output for string(from:to:)
for most of the cases where the components are all positive.
Examples:
// 1 month 7 days
var dateComponents = DateComponents()
dateComponents.month = 1
dateComponents.day = 7
// 1 month, 7 days
print(dateComponentsFormatter.string(from: dateComponents)!)
// 7 days - 1 month
dateComponents.month = -1
dateComponents.day = 7
// -24 days
print(dateComponentsFormatter.string(from: dateComponents)!)
// 1 month - 7 days
dateComponents.month = 1
dateComponents.day = -7
// 24 days
print(dateComponentsFormatter.string(from: dateComponents)!)
// 1 month 30 days
// note that adding 1 month, it's February, and there are only 28 days
dateComponents.month = 1
dateComponents.day = 30
// 2 months, 2 days
print(dateComponentsFormatter.string(from: dateComponents)!)
// -10 months - 30 days
// note that after subtracting 10 months, it is March of the previous year,
// which also happens to be a leap year, so February has 29 days
// Subtracting 30 days from that will bring us to January, with one day left
// which is, where the extra month and day came from
dateComponents.month = -10
dateComponents.day = -30
// -11 months, 1 day
print(dateComponentsFormatter.string(from: dateComponents)!)
// -1 year - 10 months - 30 days
// similar to above, except not a leap year
// so we have 2 days left after subtracting from a 28-day February.
dateComponents.year = -1
dateComponents.month = -10
dateComponents.day = -30
// -1 year, 11 months, 2 days
print(dateComponentsFormatter.string(from: dateComponents)!)
The DateComponents
used in that last case is what Calendar.dateComponents(_:from:to:)
in your code.
On the other hand, string(from:to)
is the designated method to format the period between two dates.