0

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 
3
  • Because you are using two different methods? Commented May 20, 2022 at 17:18
  • But I am using the same startDate and endDate Commented May 20, 2022 at 17:23
  • 1
    My explanation is that dateComponents(_,from:to:) calculates the absolute difference of each component. On the other hand string(from:to:) calculates the distance between the two dates. Commented May 20, 2022 at 17:23

1 Answer 1

1

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 DateComponents 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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.