-1

I saw a few posts but they seemed a bit complex, so wanted to just phrase my question very specifically and see if there was a relatively easier way to achieve this.

I want to create an extension method in Swift for NSDate called changeTimeOfDay(hour: Int) that will change the time of a given NSDate to the time you pass in.

For example, if my current NSDate variable, d, happens to be a week from now, I'd like to specifically set that date to be at 8am (so it's a week from now, at 8AM).I already have an extension method that can add weeks to a particular date, and one that can add hours, but in this case I'd like to actually set the hours to 8AM.

Any thoughts on the way to go about this? I'd like to support ios7 and 8. I'm a little confused (based on what I was able to find so far) as to a simple way to do this.

Thanks!

NullHypothesis
  • 4,286
  • 6
  • 37
  • 79

2 Answers2

4

You can create some extensions to help you extract your date info from your NSDate object and combine it with the desired time as follow:

extension NSDate {
    var day:   Int { return NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitDay,   fromDate: self).day   }
    var month: Int { return NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitMonth, fromDate: self).month }
    var year:  Int { return NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitYear,  fromDate: self).year  }
    var at8am: NSDate {
        return NSCalendar.currentCalendar().dateWithEra(1, year: year, month: month, day: day, hour: 8, minute: 0, second: 0, nanosecond: 0)!
    }
}


NSDate().at8am   // "Jan 11, 2015, 8:00 AM"

You have a few problems with your function. There is no self value using it like this.You have to create this function as an extension NSDate function to use self. You should change your components to the new format. Thats how you should implement your function:

extension NSDate {
    func changeHourOfDay(hour: Int) -> NSDate {
        let calendar = NSCalendar.currentCalendar()
        let components = calendar.components(.CalendarUnitYear | .CalendarUnitDay | .CalendarUnitHour, fromDate: self)
        components.hour = hour
        return calendar.dateFromComponents(components)!
    }
}

NSDate().changeHourOfDay(8)  //  "Jan 11, 2015, 8:00 AM"
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • thanks for this I appreciate it! Alternately, what do you think of my post above? – NullHypothesis Jan 11 '15 at 21:18
  • Both methods have their advantages. Here you have several small methods that can easily be reused in other context. On the other hand, this `at8am` method requires 4 calls to `currentCalendar()` and 3 calls to `components()`, whereas the code in the other answer requires only one call each. – Martin R Jan 11 '15 at 22:08
  • @Martin R Thanks for the info. I have updated the answer with the one he should use. – Leo Dabus Jan 11 '15 at 22:15
  • @Martin R I have timed both of them. The first one takes a little bit longer at my playground "0.00578689575195312s" against "0.00478911399841309s". Should I really be concerned about it? – Leo Dabus Jan 11 '15 at 23:01
0
func changeHourOfDay(hour: Int) -> NSDate {
        let calendar: NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
        let components: NSDateComponents = calendar.components(.YearCalendarUnit | .DayCalendarUnit | NSCalendarUnit.HourCalendarUnit, fromDate: self)
        components.hour = hour
        return calendar.dateFromComponents(components)!
    }

This is what I ended up doing as per the link above. Does this seem good to you all?

// you have a few problems there. There is no self value using it like this.You have to create this function as an extension NSDate function to use self. You should change your components to the new format. Thats how you should implement your function:

extension NSDate {
    func changeHourOfDay(hour: Int) -> NSDate {
        let calendar = NSCalendar.currentCalendar()
        let components = calendar.components(.CalendarUnitYear | .CalendarUnitDay | .CalendarUnitHour, fromDate: self)
        components.hour = hour
        return calendar.dateFromComponents(components)!
    }
}

NSDate().changeHourOfDay(8)  //  "Jan 11, 2015, 8:00 AM"
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
NullHypothesis
  • 4,286
  • 6
  • 37
  • 79