32

I would like to subtract 4 hours from a date. I read the date string into an NSDate object use the following code:

NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate * mydate = [dateFormatter dateFromString:[dict objectForKey:@"published"]];

What do I do next?

  • 6
    (It's now 6 years, and 4 major versions of XCode later... and NSDate's functionality is still as unintuitive as in 2009 !!) – Mike Gledhill Mar 17 '15 at 12:56

7 Answers7

49
NSDate *newDate = [theDate dateByAddingTimeInterval:-3600*4];

Link to documentation.


NSDate *newDate = [[[NSDate alloc] initWithTimeInterval:-3600*4
                                              sinceDate:theDate]] autorelease];

Link to documentation.

Georg Schölly
  • 124,188
  • 49
  • 220
  • 267
23

NSCalendar is the general API for changing dates based on human time units. For this, you can use NSCalendar's -dateByAddingComponents:toDate:options: with a negative number of hours.

Chuck
  • 234,037
  • 30
  • 302
  • 389
  • NSCalendar is not a recommended API to use. http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSCalendarDate_Class/Reference/Reference.html – oberbaum Feb 15 '10 at 15:59
  • 10
    @norskben: That page is for NSCalendar**Date**. That's what it says not to use. It specifically recommends NSCalendar as a replacement in the same note. – Chuck Feb 15 '10 at 17:17
9

In Swift 4 :

var baseDate = ... // something
let dateMinus4Hours = Calendar.current.date(byAdding: .hour, value: -4, to: baseDate)

don't go with 24*3600 and stuff, that's asking for trouble.

Guillaume Laurent
  • 1,734
  • 14
  • 11
6

Since iOS 8 there is the more convenient dateByAddingUnit:

Swift 2.x

//subtract 3 hours
let calendar = NSCalendar.autoupdatingCurrentCalendar()
newDate = calendar.dateByAddingUnit(.Hour, value: -3, toDate: originalDate, options: [])
Bryan Bryce
  • 1,310
  • 1
  • 16
  • 29
Ben Packard
  • 26,102
  • 25
  • 102
  • 183
5
//in Swift 3
//subtract 3 hours
let calendar = NSCalendar.autoupdatingCurrent
newDate = calendar.date(byAdding:.hour, value: -3, to: originalDate)
Ning
  • 148
  • 1
  • 10
2

Here a function which might be useful as it returns the date -4 h considering that this may also change the date and the month and eventually the year. the .searchBackward option is the important part :)

public static func correctSecondComponent(date: Date, calendar: Calendar = Calendar(identifier: Calendar.Identifier.gregorian))->Date {

    let hour = calendar.component(.hour, from: date)

    let e = (calendar as NSCalendar).date(byAdding: NSCalendar.Unit.hour, value: -4, to: date, options:.searchBackwards)!

    return e
}
Pe Gra
  • 41
  • 7
1

dateFromString function returns NSDate, not NSString. you should change,

NSDate * theDate = [dateFormatter dateFromString:datetemp];

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Guvener Gokce
  • 804
  • 14
  • 20