NSDateFormatter for Julian Day Number calculates with the incorrect hour in GMT.

Originator:dan
Number:rdar://11023565 Date Originated:Sat, 10 Mar 2012 00:29:31 GMT
Status:Closed Resolved:2012-05-18
Product:iPhone SDK Product Version:5.1
Classification:Other Bug Reproducible:Always
 
09-Mar-2012 05:28 PM Daniel Weeks:
Summary:

There exists for astronomical calculations a date format called the Julian Day Number (JDN, the integer count of the number of days since January 1, 4713 BCE). For example today's (2012-03-09) JDN is 2455996. The JDN is calculated from noon GMT.

The NSDateFormatter on iOS SDK and Mac OS X SDK provides a format of "g" to convert an NSDate to a Julian Day Number.

When using the NSDateFormatter to convert an NSDate to a JDN or a JDN to an NSDate the incorrect hour in GMT is used. The hour that should be used is 12:00:00 (in a 24-hour clock) and the hour of 08:00:00 is used instead.

Steps to Reproduce:

Compile the JulianDayNumber.m file with the command:

clang JulianDayNumber.m -o JulianDayNumber -std=c99 -framework Foundation -fobjc-arc

Run JulianDayNumber in a terminal. Witness the NSLog output.

Expected Results:

When converting from a string of numbers representing a JDN the resulting NSDate would be set to the day with 12:00:00 (noon) in GMT. A time of 08:00:00 would be the previous JDN.

Actual Results:

The NSDate returned is at 08:00:00 GMT when it should be at noon GMT. Any time of noon or after, until the next noon, should return a JDN of X. Any time prior to noon should return a JDN of X-1, but that only happens with times prior to 08:00:00 GMT.

Regression:


Notes:


09-Mar-2012 05:28 PM Daniel Weeks:
'JulianDayNumber.m' was successfully uploaded

Comments

Closed by Apple Engineering

Engineering has determined that this issue behaves as intended based on the following information:

This is the documented behavior of pattern character 'g' in the CLDR LDML spec, and thus in ICU. See http://www.unicode.org/reports/tr35/#Date_Field_Symbol_Table and scroll down to pattern character 'g'; it says: "Modified Julian day. This is different from the conventional Julian day number in two regards. First, it demarcates days at local zone midnight, rather than noon GMT. Second, it is a local number; that is, it depends on the local time zone. It can be thought of as a single number that encompasses all the date-related fields."

JulianDayNumber.m

import

int main(int argc, char *argv[]) { @autoreleasepool {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"g"];
    NSLog(@"default test");
    NSLog(@"string from date: %@", [dateFormatter stringFromDate:[NSDate date]]);
    NSLog(@"date from string: %@", [dateFormatter dateFromString:[dateFormatter stringFromDate:[NSDate date]]]);

    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [NSDateComponents new];
    components.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];
    components.year = 2012;
    components.month = 3;
    components.day = 9;
    components.hour = 8;
    components.minute = 0;
    components.second = 0;
    NSDate *testDate = [gregorian dateFromComponents:components];
    NSLog(@"test date: %@", testDate);
    NSLog(@"2012-03-09 08:00:00 +000 test");
    NSLog(@"string from date: %@", [dateFormatter stringFromDate:testDate]);
    NSLog(@"date from string: %@", [dateFormatter dateFromString:[dateFormatter stringFromDate:testDate]]);

    components.hour = 12;
    testDate = [gregorian dateFromComponents:components];
    NSLog(@"test date: %@", testDate);
    NSLog(@"2012-03-09 12:00:00 +000 test");
    NSLog(@"string from date: %@", [dateFormatter stringFromDate:testDate]);
    NSLog(@"date from string: %@", [dateFormatter dateFromString:[dateFormatter stringFromDate:testDate]]);

    components.hour = 3;
    testDate = [gregorian dateFromComponents:components];
    NSLog(@"2012-03-09 03:00:00 +000 test");
    NSLog(@"test date: %@", testDate);
    NSLog(@"string from date: %@", [dateFormatter stringFromDate:testDate]);
    NSLog(@"date from string: %@", [dateFormatter dateFromString:[dateFormatter stringFromDate:testDate]]);
}

}


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!