I am working on a bit of code at present which will return all the days in between 2 dates. The method will then return 2 dates, one date with the time set to the start of the day, and one at the end of the day. This is required for a api call I need to make which returns some data for that day.
However I am having an issue caused by daylight savings, as the clocks go back on the 26th, I am not getting the correct dates returned for 25th - 26th. Below is my code
func dateTesting()
{
let day = -86400
let startDate = Date().addingTimeInterval(TimeInterval(day * 5))
let endDate = Date()
let tuples = daysBetweenDates(startDate: startDate, endDate: endDate)
print(tuples)
}
func daysBetweenDates(startDate: Date, endDate: Date) -> [(startDate: Date, endDate: Date)]
{
let calendar = Calendar.current
let components = calendar.dateComponents([.day, .month,.year], from: startDate)
let components2 = calendar.dateComponents([.day,.month,.year], from: endDate)
let daysDifferent = abs(components.day! - components2.day!)
var tupleList:[(startDate: Date, endDate: Date)] = []
let day = -86400
for index in stride(from: daysDifferent, to: 0, by: -1) {
let date = Date().addingTimeInterval(TimeInterval(day * index))
let tuple = createFetchRequestDates(date: date)
tupleList.append(tuple)
}
return tupleList
}
func createFetchRequestDates(date : Date) -> (startDate: Date, endDate: Date)
{
let calendar = Calendar.current
var components = calendar.dateComponents([.hour, .minute, .day, .month, .year], from: date)
var components2 = calendar.dateComponents([.hour, .minute, .day, .month, .year], from: date)
components.hour = 1
components.minute = 0
components2.hour = 24
components2.minute = 59
let start = calendar.date(from: components)
let end = calendar.date(from: components2)
//debugging
print(date)
print(start!)
print(end!)
print(" ")
let tuple = (startDate : start!, endDate : end!)
return tuple
}
In the createFetchRequestDates code, when I print out the codes for any non daylight savings day code, it works as expected, i.e.
2017-03-29 09:52:37 +0000
2017-03-29 00:00:00 +0000
2017-03-29 23:59:00 +0000
However when the code is called between the 25th-26th when daylight savings occurred, the following is printed
2017-03-25 09:52:37 +0000
2017-03-25 01:00:00 +0000
2017-03-26 00:59:00 +0000
2017-03-26 09:52:37 +0000
2017-03-26 01:00:00 +0000
2017-03-26 23:59:00 +0000
Does anyone know the best way to fix this? I want to make sure I get the correct start and end time of each day, and the clocks going back is causing a bit of an issue.
I could do an if statement to check if the particular date is daylight savings day, and then modify my components code for those particular days. However I was hoping there would perhaps be a cleaner approach.
Any help would be much appreciated
Edit:
Just to give another example of the problem
let calendar = Calendar.current
var components = calendar.dateComponents([.day, .month,.year], from: Date())
var components2 = calendar.dateComponents([.day, .month,.year], from: Date())
components.day = 26
components.hour = 0
components.minute = 0
components2.day = 26
components2.hour = 23
components2.minute = 59
print(calendar.date(from: components)!)
print(calendar.date(from: components2)!)
This is printed out
2017-03-26 00:00:00 +0000
2017-03-26 22:59:00 +0000
I want it to print out 23:59:00, but the daylight savings knocks it back an hour unfortunately.
Edit 2:
Here is example of the updated code
func daysBetweenDates(startDate: Date, endDate: Date) -> [(startDate: Date, endDate: Date)]
{
let calendar = Calendar.current
let components = calendar.dateComponents([.day, .month,.year], from: startDate)
let components2 = calendar.dateComponents([.day,.month,.year], from: endDate)
let daysDifferent = abs(components.day! - components2.day!)
var tupleList:[(startDate: Date, endDate: Date)] = []
for index in stride(from: daysDifferent, to: 0, by: -1) {
let calendar = Calendar.current
var components = calendar.dateComponents([.hour, .minute, .day, .month, .year], from: Date())
components.day = components.day! - index
let date = calendar.date(from: components)
let tuple = createFetchRequestDates(date: date!)
tupleList.append(tuple)
}
return tupleList
}
So instead of subtracting 86400 seconds, I instead use components and just subtract one full day.