4

I'm struggling to find a way to use NSDate for time only purposes. I was trying to do the following code:

- (void)awakeFromInsert
{
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    comps.minute = 45;
    comps.second = 0;

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    self.periodDuration = [calendar dateFromComponents:comps];
    NSLog(@"periodDuration: %@",self.periodDuration);

    comps = [[NSDateComponents alloc] init];
    comps.hour = 8;
    comps.minute = 0;
    self.firstPeriodStartTime = [calendar dateFromComponents:comps];
    NSLog(@"firstPeriodTime: %@",self.periodDuration);
}

But the result I get is:

periodDuration: 0001-12-31 22:24:04 +0000
firstPeriodTime: 0001-12-31 22:24:04 +0000

The result I was expecting:

periodDuration: 45:00
firstPeriodTime: 08:00

What am I doing wrong? How can I fix this? Thank you.

icodebuster
  • 8,890
  • 7
  • 62
  • 65
Noam Solovechick
  • 1,127
  • 2
  • 15
  • 29

4 Answers4

13

The log of date is misleading you, if you are forming a date with only a few components you will not get a proper date instance which uniquely identifies a date and time.

If you try with this code snipped you can find that if you are just converting the dates back to string it is just as you expect

NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.minute = 45;
comps.second = 0;

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *periodDate = [calendar dateFromComponents:comps];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss"];
NSLog(@"periodDuration: %@",[dateFormatter stringFromDate:periodDate]);

comps = [[NSDateComponents alloc] init];
comps.hour = 8;
comps.minute = 0;
NSDate *firstPeriodDate = [calendar dateFromComponents:comps];
[dateFormatter setDateFormat:@"HH:mm"];
NSLog(@"firstPeriodTime: %@",[dateFormatter stringFromDate:firstPeriodDate]);

periodDuration: 45:00

firstPeriodTime: 08:00

Anupdas
  • 10,211
  • 2
  • 35
  • 60
  • I feel so idiot right now... I can't believe that my problem was not using NSDateFormatter. Anyway, now I have your method and @Andreas_Ley method. What do you think will be better to implement? Saving time as seconds or as a NSDate object (using core data)? – Noam Solovechick May 04 '13 at 09:25
  • @NoamSolovechick It's your decision. As coredata supports storing date as such, you can directly store it without any hazzle. – Anupdas May 04 '13 at 09:58
3

You can use NSDateFormatter

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];    
[dateFormatter setDateFormat:@"HH:mm"];
NSLog(@"%@",[dateFormatter stringFromDate:[NSDate date]]);
Anupdas
  • 10,211
  • 2
  • 35
  • 60
Ayush
  • 3,989
  • 1
  • 26
  • 34
  • I know that, but I don't think it's the right choice for storing time in NSDate. I don't want to represent the date in a string. I want to store it in Core Data... The NSLog is just to see if everything is alright. – Noam Solovechick May 04 '13 at 08:29
3

Use a NSTimeInterval (which is, basically, a double containing the number of seconds). To store it in CoreData:

[NSNumber numberWithDouble:myTimeInterval];

As for formatting: If you want more than 24h displayed, use this:

NSUInteger seconds = (NSUInteger)round(myTimeInterval);
NSString *formattedDate = [NSString stringWithFormat:@"%02u:%02u:%02u",
                           seconds / 3600, (seconds / 60) % 60, seconds % 60];
NSLog(@"%@", formattedDate);

If you don't want more than 24h, you can use NSDate and NSDateFormatter again:

NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:myTimeInterval];
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:@"HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSString *formattedDate = [dateFormatter stringFromDate:date];
NSLog(@"%@", formattedDate);
Andreas Ley
  • 9,109
  • 1
  • 47
  • 57
  • This is very messy. Don't use magic numbers, period. A day may not always have 24 hours and a year will not always have 365 days. – Pavan Jan 15 '15 at 13:36
  • @Pavan While I agree with your sentiment, I don't see why you think it's a problem in this case. Part of the OPs question was how to store a time interval in CoreData, and I still believe that using NSTimeInterval is the best way to do so. – Andreas Ley Jan 16 '15 at 08:41
0
NSString *timeString;
timeString = [NSDateFormatter localizedStringFromDate:[NSDate date]
                                            dateStyle:NSDateFormatterNoStyle
                                            timeStyle:NSDateFormatterMediumStyle];

12:03:54 PM

Alex Zavatone
  • 4,106
  • 36
  • 54