aftab ahmed
aftab ahmed

Reputation: 191

Set NSDate 0 seconds in swift

I'm trying to get NSDate from UIDatePicker, but it constantly returns me a date time with trailing 20 seconds. How can I manually set NSDate's second to zero in swift?

Upvotes: 16

Views: 11776

Answers (7)

George Filippakos
George Filippakos

Reputation: 16569

extension Date {

    var zeroSeconds: Date? {
        let calendar = Calendar.current
        let dateComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: self)
        return calendar.date(from: dateComponents)
    }

}

Usage:

let date1 = Date().zeroSeconds

let date2 = Date()
print(date2.zeroSeconds)

Upvotes: 43

Guilherme Matuella
Guilherme Matuella

Reputation: 2273

I know this doesn't address NSDate directly, but it might be worth anyways - I had this exact same problem with Date and also because I think this might be a more clean approach.

extension Calendar {
    /// Removes seconds `Calendar.Component` from a `Date`. If `removingFractional` is `true`, it also
    /// removes all fractional seconds from this particular `Date`.
    ///
    /// `removingFractional` defaults to `true`.
    func removingSeconds(fromDate date: Date, removingFractional removesFractional: Bool = true) -> Date? {
        let seconds = component(.second, from: date)
        let noSecondsDate = self.date(byAdding: .second, value: -seconds, to: date)

        if removesFractional, let noSecondsDate = noSecondsDate {
            let nanoseconds = component(.nanosecond, from: noSecondsDate)
            return self.date(byAdding: .nanosecond, value: -nanoseconds, to: noSecondsDate)
        }

        return noSecondsDate
    }
}

Now, to solve your problem, we created the function removingSeconds(fromDate: removingFractional). It's really simple - as you can see in the docs of the function. It removes the .second component and, if removingFractional is true, it also removes any fractional seconds that this Date may have - or the .nanosecond component.

Upvotes: 0

Martin R
Martin R

Reputation: 539685

Truncating a date to a full minute can be done with

let date = NSDate()

let cal = NSCalendar.currentCalendar()
var fullMinute : NSDate?
cal.rangeOfUnit(.CalendarUnitMinute, startDate: &fullMinute, interval: nil, forDate: date)
println(fullMinute!)

Update for Swift 4 and later:

let date = Date()
let cal = Calendar.current
if let fullMinute = cal.dateInterval(of: .minute, for: date)?.start {
    print(fullMinute)
}

This method can easily be adapted to truncate to a full hour, day, month, ...

Upvotes: 8

Jano
Jano

Reputation: 63667

import Foundation

let now = Date()
let calendar = Calendar.current
let date = calendar.date(bySettingHour: 0,
                         minute: 0,
                         second: 0,
                         of: now,
                         direction: .backward)

There is another way, with two more parameters: matchingpolicy and repeatedTimePolicy.

let date = calendar.date(bySettingHour: 0,
                         minute: 0,
                         second: 0,
                         of: now,
                         matchingPolicy: .strict,
                         repeatedTimePolicy: .first,
                         direction: .backward)

To check the result:

let formatter = ISO8601DateFormatter()
formatter.timeZone = TimeZone.current // defaults to GMT
let string = formatter.string(from: date!)
print(string) // 2019-03-27T00:00:00+01:00

Upvotes: 0

Lluis Gerard
Lluis Gerard

Reputation: 1661

This is how to do it in Swift 3.

In this example I remove the seconds in the date components:

let date = picker.date
let calendar = Calendar.current
let components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
let fullMinuteDate = calendar.date(from: components)!

Working on a playground: Removing the seconds component from a date

Upvotes: 7

oyalhi
oyalhi

Reputation: 3984

Just reformat the date:

func stripSecondsFromDate(date: NSDate) -> NSDate {
  let dateFormatter = NSDateFormatter()
  dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
  let str = dateFormatter.stringFromDate(date)
  let newDate = dateFormatter.dateFromString(str)!

  return newDate
}

Upvotes: 1

Vlad
Vlad

Reputation: 7260

From this answer in Swift:

var date = NSDate();
let timeInterval = floor(date .timeIntervalSinceReferenceDate() / 60.0) * 60.0
date = NSDate(timeIntervalSinceReferenceDate: timeInterval)

Upvotes: 12

Related Questions