Swift 3 Easy way to truncate Date to start of the day/month/year

Calendar has dedicated methods:

  • Start of the day

      let truncated = Calendar.current.startOfDay(for: Date())
    
  • Start of the month

      let now = Date()
      var startOfMonth = now
      var timeInterval : TimeInterval = 0.0
      Calendar.current.dateInterval(of: .month, start: &startOfMonth, interval: &timeInterval, for: now)
    
      print(startOfMonth)
    
  • Start of the year

      let now = Date()
      var startOfYear = now
      var timeInterval : TimeInterval = 0.0
      Calendar.current.dateInterval(of: .year, start: &startOfYear, interval: &timeInterval, for: now)
    
      print(startOfYear)
    

Or as Date extension

extension Date {
    
    func startOf(_ dateComponent : Calendar.Component) -> Date {
        var calendar = Calendar.current
        calendar.timeZone = TimeZone(secondsFromGMT: 0)!
        var startOfComponent = self
        var timeInterval : TimeInterval = 0.0
        calendar.dateInterval(of: dateComponent, start: &startOfComponent, interval: &timeInterval, for: now)
        return startOfComponent
    }
}

let now = Date()

let startOfDay = now.startOf(.day)
let startOfMonth = now.startOf(.month)
let startOfYear = now.startOf(.year)

Regarding the time zone issue you can set the time zone of the current calendar accordingly.


Note the +0000 at the end of the time in your sample.

The start of the day where? I updated the sample to show what you want.

var comp: DateComponents = Calendar.current.dateComponents([.year, .month, .day], from: Date())
comp.timeZone = TimeZone(abbreviation: "UTC")!
let truncated = Calendar.current.date(from: comp)!
print(truncated)

It prints 2017-06-14 00:00:00 +0000. Again, note the +0000 at the end.

By default the timezone is set to be the current timezone and the hour, minute, and second are 0 in that timezone.


I will assume that you want the current timezone. With that stipulation, your code is correct.