12

I try to compare two days ignoring time. So I use

calendar.compare(date1, to: date2, toGranularity: .day)

BUT when transfering the string date to Date type, it is transformed to UTC. So it will be "moved" from 1.1.2016 0:05 to 31.12.2015 11:05 pm. When comparing daywise, this includes only the remaining hour. Before conversion it was 24 hours. Any idea to handle this issue without much effort?

Additionally: The code:

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy hh:mm"
var date1 : Date = dateFormatter.date(from:  "01-01-2016 00:05")!
var date2 = dateFormatter.date(from:  "01-01-2016 03:30")

if let dateFromString = dateFormatter.date(from:  "01-01-2016 00:05") {
    print(dateFromString)
    dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
    let stringFromDate = dateFormatter.string(from: dateFromString)
}


Calendar.current.compare(date1, to: date2!, toGranularity: .day) == .orderedSame
Peter71
  • 2,180
  • 4
  • 20
  • 33
  • The above code compares if the given dates are on the same day or on different days according to the calendar. Please show a self-contained reproducible example with expected output and actual output. – Martin R Nov 16 '16 at 13:43
  • I added code and get more confused. I have to do some more tests before! :-) – Peter71 Nov 16 '16 at 14:06
  • Your not being very clear about what the actual problem is. Is the problem that it converts to UTC format which causes problems, or is it that when converted you loose the hour information, or is it that after conversion it is not in 24 hour format anymore? Try to rewrite and be clear about the problem(s) you are having, this will enable you to get this answered faster. – torinpitchers Nov 16 '16 at 14:19

1 Answers1

33

Details

  • Xcode 11.5 (11E608c), Swift 5.1

Idea

base on usage dateComponents(_:from:to:) function

Solution

import Foundation

extension Date {

    func fullDistance(from date: Date, resultIn component: Calendar.Component, calendar: Calendar = .current) -> Int? {
        calendar.dateComponents([component], from: self, to: date).value(for: component)
    }

    func distance(from date: Date, only component: Calendar.Component, calendar: Calendar = .current) -> Int {
        let days1 = calendar.component(component, from: self)
        let days2 = calendar.component(component, from: date)
        return days1 - days2
    }

    func hasSame(_ component: Calendar.Component, as date: Date) -> Bool {
        distance(from: date, only: component) == 0
    }
}

Full Sample

Do not forget to put here the Solution code (look above)

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy hh:mm:ss"
//dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

let smallerDate = dateFormatter.date(from: "01-01-2012 00:05:01")!
let biggerDate  = dateFormatter.date(from: "03-12-2019 09:30:01")!

print(smallerDate.fullDistance(from: biggerDate, resultIn: .day))       // Optional(2893)
print(biggerDate.fullDistance(from: smallerDate, resultIn: .day))       // Optional(-2893)
print(smallerDate.fullDistance(from: biggerDate, resultIn: .year))      // Optional(7)
print(biggerDate.fullDistance(from: smallerDate, resultIn: .year))      // Optional(7)
print(smallerDate.fullDistance(from: biggerDate, resultIn: .hour))      // Optional(69441)
print(biggerDate.fullDistance(from: smallerDate, resultIn: .hour))      // Optional(-69441)

print(smallerDate.distance(from: biggerDate, only: .day))               // -2
print(biggerDate.distance(from: smallerDate, only: .day))               // 2
print(smallerDate.distance(from: biggerDate, only: .year))              // -7
print(biggerDate.distance(from: smallerDate, only: .year))              // 7
print(smallerDate.distance(from: biggerDate, only: .hour))              // -9
print(biggerDate.distance(from: smallerDate, only: .hour))              // 9

print(smallerDate.hasSame(.day, as: biggerDate))                        // false
print(biggerDate.hasSame(.second, as: smallerDate))                     // true
Vasily Bodnarchuk
  • 24,482
  • 9
  • 132
  • 127