views:

70

answers:

3

I'm trying to use [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:date] on two different dates to see if they fall on the same day. However, if my time zone is different (say, somewhere in Germany), even though the dates are obviously the same, the days returned are different. If I use NSYearCalendarUnit instead of NSEraCalendarUnit on the same dates, the returned values are the same.

The only problem with using NSYearCalendarUnit is it returns the same value for the same day of different years, and it's not simple to determine the number of days between two dates if they fall on different years.

Any ideas what's wrong or how to more easily determine if two dates are on the same day, or to determine the number of days between them?

Example:

[NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Berlin"]];
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDate *date1 = [NSDate dateWithTimeIntervalSinceReferenceDate:300751200];
NSDate *date2 = [NSDate dateWithTimeIntervalSinceReferenceDate:300836062.388569];

NSLog(@"\nDate 1: %@\nDate 2: %@",date1,date2);
/*Output:
Date 1: 2010-07-14 00:00:00 +0200
Date 2: 2010-07-14 23:34:22 +0200
*/

int day1 = [cal ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit
                         forDate:date1];
int day2 = [cal ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit
                         forDate:date2];

NSLog(@"\nDay 1: %i\nDay 2: %i",day1,day2);
/*Output:
  Day 1: 733966
  Day 2: 733967
*/

day1 = [cal ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit
                     forDate:date1];
day2 = [cal ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit
                     forDate:date2];

NSLog(@"\nDay 1:%i\nDay 2: %i",day1,day2);
/*Output:
  Day 1: 195
  Day 2: 195
*/
A: 

See http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSCalendar_Class/Reference/NSCalendar.html: “Discussion

The ordinality is in most cases not the same as the decomposed value of the unit. Typically return values are 1 and greater. For example, the time 00:45 is in the first hour of the day, and for units Hour and Day respectively, the result would be 1. An exception is the week-in-month calculation, which returns 0 for days before the first week in the month containing the date.”

In other words: 23:34:22 belongs to the last hour of day, coming up to 240. Time running over the zero is equivalent to: next day.

Maybe this could be treated as a bug: hours in a day running from the first over the twentytird to the zeroth? I suggest: fill in a bug report.

Objective Interested Person
I'm not sure I understand... The two dates are obviously on the same day, but do not show up as the same day within the era, but DO show up as the same day within the year. I guess a bug report is in order, but is there any workaround in the mean time?
Ed Marty
It depends when the era starts doesn't it. If the era starts at midnight *GMT* some year, then your two dates are not on the same day (in era time).
JeremyP
A: 

@Ed Marty (“I'm not sure I understand...”): as I’m not so good in english, here just a small table to show you the (buggy as I think) counting:

00:00–00:59 ist first hour of the day; fine 01:00–01:59 the second one … 23:00–23:59 the 24th? Or the “zeroth” of the next day?

It’s just the old counting-problem: year 2001 started the new century because there ist no year zero. Here the hours are counted from one upwards – but 23 seems to be followed by 0! So they should either start counting with zero or they should end counting the hours by 24. Both would be fine, it’s just convenience, just like “what is the index of the first element of an array”.

Objective Intersted Person
The issue isn't only with these times. If I chose 1 AM and 11 PM, the issue would be the same
Ed Marty
A: 

“The issue isn't only with these times. …” Hmmm… just an idea: reference date is what? Can’t check this now, but I’d bet, you will look surprised for a moment, if you display this value when setting up some diferent time zones! Surprised just a bit like “Phileas Fogg” when he finds his counting of days had become a bit relative.

Why? Because reference time is just one point in time, not one for every time zone location! So if you come (within respect of the timezone-offset) close to the local days borders (0:00 or 24:00) you will cross day borders — and I’ll have to withdraw my hour-counting-assumption.

We still have to learn: „Eppur si muove“! :-/

Greetings

Objective Interrested Person