Hey team I'm facing an issue where startDate is 1 January 2025 and endDate is 31 March 2025 between this 2 dates is 90 days, but on my code is being taken as 89 days I've seen the math of the code excludes the first partial day (from midnight to 06:00) on 2025-01-01, which results in 89 full days instead of 90 days.
startDate: 2025-01-01 06:00:00 +0000 endDate: 2025-03-31 06:00:00 +0000
this is my function
func daysBetweenDates() -> Int? {
guard let selectedStartDate = selectedStartDate?.date else { return nil }
guard let selectedEndDate = selectedEndDate?.date else { return 0 }
let calendar = Calendar.current
let dateComponents = calendar.dateComponents([.day], from: selectedStartDate, to: selectedEndDate)
return dateComponents.day
}
what I've tried is reset the hours to 0 so it can take the full day and return 90 days like this
func daysBetweenDates() -> Int? {
guard let selectedStartDate = selectedStartDate?.date else { return nil }
guard let selectedEndDate = selectedEndDate?.date else { return 0 }
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(secondsFromGMT: 0) ?? .current
let cleanMidNightStartDate = calendar.startOfDay(for: selectedStartDate)
let cleanMidNightEndDate = calendar.startOfDay(for: selectedEndDate.addingTimeInterval(24 * 60 * 60))
let dateComponents = calendar.dateComponents([.day], from: cleanMidNightStartDate, to: cleanMidNightEndDate)
let daysCount = dateComponents.day ?? 0
return daysCount
}
this worked for that date specifically but when I tried to change the date for example startDate: 18 December 2024. endDate: 18 March 2025. between those dates we have 90 days but this function now reads 91.
what I'm looking is a cleaver solution for this problem so I can have the best posible quality code, thanks in advance!
It seems to me that 89
is the correct answer to your question. Almost all frameworks APIs that have a "to/from" range are inclusive of the "to" and exclusive of the "from". That means you're asking for the number of days in the range whose first day is 2025-1-1 and whose last day is 2025-3-30 (up to but not including 2025-3-31).
If you want the answer to be 90
, you'll have to change the question.
The simplest solution is to keep your first solution and add 1 to the result, effectively making the end date inclusive instead of exclusive.
However, you'll need to consider what you think is the correct answer for some edge cases. If the time on the end date is 0 (well, start of day), should that day also be included? If the times on the start and end dates are different, does that ever make a difference to the inclusive/exclusive decision?