148

I am new to Swift and am trying a scheduler. I have the start time selected and I need to add 5 minutes (or multiples of it) to the start time and display it in an UILabel?

@IBAction func timePickerClicked(sender: UIDatePicker) {
    var dateFormatter = NSDateFormatter()
    dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
    var dateStr = dateFormatter.stringFromDate(startTime.date)
    let sttime = dateStr
    startTimeDisplay.text = dateStr
}

// How to advance time by 5 minutes for each section based on the   start time selected and display time 
// section 1 = start time + 5
// section 2 = start time + 10*
ricardopereira
  • 11,118
  • 5
  • 63
  • 81
try maadee
  • 1,493
  • 2
  • 9
  • 4

11 Answers11

341

Two approaches:

  1. Use Calendar and date(byAdding:to:wrappingComponents:). E.g., in Swift 3 and later:

    let calendar = Calendar.current
    let date = calendar.date(byAdding: .minute, value: 5, to: startDate)
    
  2. Just use + operator (see +(_:_:)) to add a TimeInterval (i.e. a certain number of seconds). E.g. to add five minutes, you can:

    let date = startDate + 5 * 60
    

    (Note, the order is specific here: The date on the left side of the + and the seconds on the right side.)

    You can also use addingTimeInterval, if you’d prefer:

    let date = startDate.addingTimeInterval(5 * 60)
    

Bottom line, +/addingTimeInterval is easiest for simple scenarios, but if you ever want to add larger units (e.g., days, months, etc.), you would likely want to use the calendrical calculations because those adjust for daylight savings, whereas addingTimeInterval doesn’t.


For Swift 2 renditions, see the previous revision of this answer.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Which of these 2 approaches is more performant? addingTimeInterval or calendar.date(byAdding... – Nishant Nov 12 '19 at 05:26
  • 4
    The `addingTimeInterval` is undoubtedly more performant (though likely not material unless you’re doing this millions of times). What is more critical, though, is if you’re talking about units of measure in days (or longer), then the calendrical rendition is preferable because it will do all of the daylight savings adjustments for you. – Rob Nov 12 '19 at 06:10
55

You can use Calendar's method

func date(byAdding component: Calendar.Component, value: Int, to date: Date, wrappingComponents: Bool = default) -> Date?

to add any Calendar.Component to any Date. You can create a Date extension to add x minutes to your UIDatePicker's date:

Xcode 8 and Xcode 9 • Swift 3.0 and Swift 4.0

extension Date {
    func adding(minutes: Int) -> Date {
        return Calendar.current.date(byAdding: .minute, value: minutes, to: self)!
    }
}

Then you can just use the extension method to add minutes to the sender (UIDatePicker):

let section1 = sender.date.adding(minutes: 5)
let section2 = sender.date.adding(minutes: 10)

Playground testing:

Date().adding(minutes: 10)  //  "Jun 14, 2016, 5:31 PM"
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Under what circumstances does `.date(byAdding:value:to)` return `nil`? Are we safe to force unwrap here? – Declan McKenna Jan 04 '18 at 10:42
  • @Deco How would adding minutes to a Date return nil? If the world doesn't come to an end in the resulting date you are safe :) – Leo Dabus Jan 05 '18 at 06:01
  • 3
    The documentation isn't clear on how this can return nil. This question explains it, you're right it's completely safe here. https://stackoverflow.com/questions/39358131/when-does-datebyaddingcomponentstodateoptions-return-nil – Declan McKenna Jan 05 '18 at 09:59
31

Swift 4:

// add 5 minutes to date

let date = startDate.addingTimeInterval(TimeInterval(5.0 * 60.0))

// subtract 5 minutes from date

let date = startDate.addingTimeInterval(TimeInterval(-5.0 * 60.0))

Swift 5.1:

// subtract 5 minutes from date
transportationFromDate.addTimeInterval(TimeInterval(-5.0 * 60.0))
OhadM
  • 4,687
  • 1
  • 47
  • 57
Gilad Brunfman
  • 3,452
  • 1
  • 29
  • 29
10
extension Date {
    func withAddedMinutes(minutes: Double) -> Date {
         addingTimeInterval(minutes * 60)
    }

    func withAddedHours(hours: Double) -> Date {
         withAddedMinutes(minutes: hours * 60)
    }
}

useCase

let anHourFromNow = Date().withAddedHours(hours: 1)
let aMinuteFromNow = Date().withAddedMinutes(minutes: 1)
marc
  • 914
  • 6
  • 18
6

You can use in swift 4 or 5

    let date = Date()
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd H:mm:ss"
    let current_date_time = dateFormatter.string(from: date)
    print("before add time-->",current_date_time)

    //adding 5 miniuts
    let addminutes = date.addingTimeInterval(5*60)
    dateFormatter.dateFormat = "yyyy-MM-dd H:mm:ss"
    let after_add_time = dateFormatter.string(from: addminutes)
    print("after add time-->",after_add_time)

output:

before add time--> 2020-02-18 10:38:15
after add time--> 2020-02-18 10:43:15
Enamul Haque
  • 4,789
  • 1
  • 37
  • 50
5

Save this little extension:

extension Int {

 var seconds: Int {
    return self
 }

 var minutes: Int {
    return self.seconds * 60
 }

 var hours: Int {
    return self.minutes * 60
 }

 var days: Int {
    return self.hours * 24
 }

 var weeks: Int {
    return self.days * 7
 }

 var months: Int {
    return self.weeks * 4
 }

 var years: Int {
    return self.months * 12
 }
}

Then use it intuitively like:

let threeDaysLater = TimeInterval(3.days)
date.addingTimeInterval(threeDaysLater)
Fitsyu
  • 860
  • 11
  • 19
  • 3
    Unfortunately, months and years are incorrect. 7 * 4 * 12 = 336, this is much less than 365. – KlimczakM Aug 13 '18 at 05:43
  • 1
    It can be improved by calculating months like this: `self.days * 30` and years: `self.days * 365`. This isn't perfect because the year can have 366 days, and month can be different than 30 days, but it is still better than 28/336. – KlimczakM Aug 15 '18 at 06:40
  • 3
    You should definitely not use this for all the reasons listed above, it's inaccurate in a bunch of different cases. Use the built-in data arithmetic functions – Steven Stefanik Mar 04 '19 at 20:36
  • 1
    Months are not always equal to 4 weeks, also how about leap years with this ? – Mehdi Chennoufi Jan 29 '20 at 15:24
4

You can do date arithmetic by using NSDateComponents. For example:

import Foundation

let comps = NSDateComponents()

comps.minute = 5

let cal = NSCalendar.currentCalendar()

let r = cal.dateByAddingComponents(comps, toDate: NSDate(), options: nil)

It is what you see when you try it in playground

enter image description here

Anthony Kong
  • 37,791
  • 46
  • 172
  • 304
4

NSDate.init with timeIntervalSinceNow:
Ex:

 let dateAfterMin = NSDate.init(timeIntervalSinceNow: (minutes * 60.0))
Kumar KL
  • 15,315
  • 9
  • 38
  • 60
3

Swift 3:

let minutes: TimeInterval = 1 * 60
let nowPlusOne = Date() + minutes
Alchi
  • 799
  • 9
  • 19
3

I think the simplest will be

let minutes = Date(timeIntervalSinceNow:(minutes * 60.0))
Sachin Nautiyal
  • 568
  • 4
  • 15
  • That's way easier than creating Calendar and doing the complex stuff, Thank you man! – MBH Feb 09 '23 at 13:30
0

In case you want unix timestamp

        let now : Date = Date()
        let currentCalendar : NSCalendar = Calendar.current as NSCalendar

        let nowPlusAddTime : Date = currentCalendar.date(byAdding: .second, value: accessTime, to: now, options: .matchNextTime)!

        let unixTime = nowPlusAddTime.timeIntervalSince1970
Pradeep Kumar Kushwaha
  • 2,231
  • 3
  • 23
  • 34