-1

I am trying to create a date with the time set to 12:00:01 am. Seconds and minutes set to their values correctly but the hour value always goes to whatever i set the value, + 4. Why 4? What is so special about that value? The minute and second values set to what I want correctly but it appears the hours value simply adds rather than replaces.

here is the code,

        NSDate *now = [NSDate date];
        NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
        [components setHour:0];
        [components setMinute:0];
        [components setSecond:1];

        NSDate *compareTime = [calendar dateFromComponents:components];
        NSLog(@"compareTime: %@", compareTime);
        NSLog(@"currentTime: %@", now);

output is :

compareTime: 2013-05-17 04:00:01 +0000

currentTime: 2013-05-17 15:00:37 +0000

Aaron
  • 7,055
  • 2
  • 38
  • 53
JMD
  • 1,540
  • 2
  • 24
  • 56
  • 1
    It's probably the difference between your local time and UTC. What time zone are you in? – Aaron May 17 '13 at 15:00
  • I'm in EST. But why would that make a difference? 0 should be 0 regardless of time zone. is it actually trying to auto adjust? and if so, what do I need to do in order to account for this issue? – JMD May 17 '13 at 15:00
  • By default [NSDate date] gives you a raw date and it doesn't assume the local time zone. – Aaron May 17 '13 at 15:02
  • I understand it gives me a raw date, but if I'm hard coding the hour to be 0, why is it not zero? – JMD May 17 '13 at 15:05
  • Again, again, again the same question. – Sulthan May 17 '13 at 15:13
  • @JMD - the time you set is for your local timezone. But when you log the date, the date is displayed in UTC. Everything is working just fine. – rmaddy May 17 '13 at 15:15
  • Check this post out: http://stackoverflow.com/questions/5214947/help-me-understand-nsdate-date – Aaron May 17 '13 at 15:26
  • 3
    It is amazing that many developers don't understand time and timezones. Time is time; its a measurement. Timezones tell how to format time. 4:00 pm in EST is not the same as 4:00 pm PST. – John May 17 '13 at 15:43
  • @John Amen. Welcome to SlashDot. An endless source for questions about `NSDate` and JSON parsing > – borrrden May 17 '13 at 17:17
  • @borrrden `/.` ? I think you mean `SO`. :) – rmaddy May 17 '13 at 21:02
  • @rmaddy Indeed, that's the second time I've done that!!! – borrrden May 18 '13 at 11:11

3 Answers3

0

EST is 4 hours ahead of GMT, hence your offset. Here's some code we use to create dates plus and minus the current time in the local time zone.

- (NSDate *) getDateWithHoursOffset : (int) aHourInt
{
CFGregorianDate gregorianStartDate, gregorianEndDate;
CFGregorianUnits startUnits = { 0,0,0, aHourInt,0,0 }; //2 hours before
CFGregorianUnits endUnits   = { 0,0,0, 8,0,0 }; //5 hours ahead
CFTimeZoneRef timeZone = CFTimeZoneCopySystem();

gregorianStartDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone, startUnits),timeZone);
gregorianStartDate.minute = 0;
gregorianStartDate.second = 0;

gregorianEndDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone,   endUnits),timeZone);
gregorianEndDate.minute = 0;
gregorianEndDate.second = 0;

NSDate* startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
CFRelease(timeZone);
return startDate;
}
Janene Pappas
  • 1,366
  • 12
  • 26
0

NSDates exist independently of timezones. If you need the date to display 12:00:01 in the application, you should use a NSDateFormatter.

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterFullStyle];

NSLog(@"formattedTime: %@", [dateFormatter stringFromDate:compareTime]);

This returns:

formattedTime: 12:00:01 AM Central Daylight Time
Sean Kladek
  • 4,396
  • 1
  • 23
  • 29
0

The problem is that your dates are correct but they're being logged in UTC relative to your device's time zone and that seems confusing. (It is, at first)

Your compare time is correct. It is set to midnight your time and outputted as UTC and if you're EST midnight would be 4am UTC:

compareTime: 2013-05-17 04:00:01 +0000

Current time is also correct, and again it is UTC time relative to your device's time zone:

currentTime: 2013-05-17 15:00:37 +0000

Your times are correct, its the output that is deceiving you.

This code (shamefully stolen from a thread listed below) should output compareTime's UTC date as 00:00:01 +0000. Though for date calculations UTC should be fine.

NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];

NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;

NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:compareTime];

Here are a few S.O. threads to help further explain:

Community
  • 1
  • 1
Aaron
  • 7,055
  • 2
  • 38
  • 53