0

How do you convert the .minute() and the .hour() to Objective-C ?

func nearestHour () -> Int {
    let halfHour = NSDate.minuteInSeconds() * 30
    var interval = self.timeIntervalSinceReferenceDate
    if  self.seconds() < 30 {
        interval -= halfHour
    } else {
        interval += halfHour
    }
    let date = NSDate(timeIntervalSinceReferenceDate: interval)
    return date.hour()
}

I tried this:

- (int) nearestHour {
NSInteger halfHour = [NSDate minuteInSeconds].intValue * 30;
NSTimeInterval interval = [self timeIntervalSinceReferenceDate];
if ([self seconds] < 30) {
    interval -= halfHour;
}
else {
    interval += halfHour;
}
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate: interval];
return [date hour];
}

I get the following errors on these lines:

if ([self seconds] < 30) {

no visible @interface for NSDate declares the selector seconds.

return [date hour];

no visible @interface for NSDate declares the selector hour.

  • Look at the docs for `NSDate`. There are no such methods as `seconds` or `hour`. They must be custom functions in your Swift code. – rmaddy Apr 14 '16 at 15:32
  • [Please do refer this link](http://stackoverflow.com/questions/743140/how-do-i-get-the-current-hour-using-cocoa) this shows the clear cut way to your conversion [Refer this link also][1] [1]: http://stackoverflow.com/questions/1739383/convert-seconds-integer-to-hhmm-iphone – Sridhar G.K Apr 14 '16 at 15:40
  • I actually had already seen that link. And I know the swift code has no custom function named hour() or seconds() , that's why I was surprised. And that's why I would like an answer to my question. –  Apr 14 '16 at 15:42
  • @SridharG.K That has nothing to do with this question. – rmaddy Apr 14 '16 at 15:42
  • @CodeOxO There is no `minuteInSeconds` method either on `NSDate` yet your code is calling such a method. It must also be some sort of category method. – rmaddy Apr 14 '16 at 15:44

2 Answers2

0

As mentioned NSDate doesn't have the interface you need. You need to break it out to a calendar interface. Then you can set the hour/minute/seconds and such individually or get them or whatever you need to do.

NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:self];

if ([components seconds] < 30) {

For your example :

- (int) nearestHour {
    NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:self];
    NSInteger halfHour = [NSDate minuteInSeconds].intValue * 30;
    NSTimeInterval interval = [self timeIntervalSinceReferenceDate];
    if ([components minutes] < 30) {
        interval -= halfHour;
    }
    else {
        interval += halfHour;
    }
    NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:    interval];
    return [date hour];
}

Lots of examples on SO and google : How do I get the current hour using Cocoa?

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DatesAndTimes/DatesAndTimes.html#//apple%5Fref/doc/uid/10000039

Community
  • 1
  • 1
LawfulEvil
  • 2,267
  • 24
  • 46
  • Explanation about why the new version (swift) is easier to use than the older version (xcode / objective c)? They improved things. – LawfulEvil Apr 14 '16 at 15:47
0

Apple recommends to do date math always with NSCalendar because for example when daylight saving time changes some dates calculated by adding/subtracting seconds might not exist.

nextDateAfterDate calculates the next date depending on the specified date components, in this case the next date where the minutes are zero. To get the nearest hour in the past you can also search backwards.

Swift

let now = NSDate()
let calendar = NSCalendar.currentCalendar()
let roundDown = calendar.component(.Minute, fromDate: now) < 30
let components = NSDateComponents()
components.minute = 0
let options : NSCalendarOptions = roundDown ? [.MatchNextTime, .SearchBackwards] : .MatchNextTime
let nearestDate = calendar.nextDateAfterDate(now, matchingComponents: components, options:  options)!
let nearestHour = calendar.component(.Hour, fromDate: nearestDate)

Objective-C

NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
BOOL roundDown = [calendar component:NSCalendarUnitMinute fromDate: now] < 30 ;
NSDateComponents *components = [[NSDateComponents alloc] init];
components.minute = 0;
NSCalendarOptions options = roundDown ? (NSCalendarMatchNextTime | NSCalendarSearchBackwards) : NSCalendarMatchNextTime;
NSDate *nearestDate = [calendar nextDateAfterDate:now matchingComponents: components options:  options];
NSInteger nearestHour = [calendar component:NSCalendarUnitHour fromDate: nearestDate];
vadian
  • 274,689
  • 30
  • 353
  • 361