在目标C中将格里高利日期转换为儒略日计数

wod*_*wod 6 iphone objective-c nsdate gregorian-calendar julian-date

我需要Objective C方法将Gregorian日期转换为Julian天,就像这个PHP方法(GregorianToJD)一样.

Mar*_*n R 8

根据http://en.wikipedia.org/wiki/Julian_day,2000年 1月1日的朱利安日数为2,451,545.因此,您可以计算日期与此参考日期之间的天数.例如(2014年1月1日):

NSUInteger julianDayFor01012000 = 2451545;
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[cal setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.year = 2014;
comp.month = 1;
comp.day = 1;
NSDate *date = [cal dateFromComponents:comp];
comp.year = 2000;
comp.month = 1;
comp.day = 1;
NSDate *ref = [cal dateFromComponents:comp];

NSDateComponents *diff = [cal components:NSDayCalendarUnit fromDate:ref toDate:date options:0];
NSInteger julianDays = diff.day + julianDayFor01012000;
NSLog(@"%ld", (long)julianDays);
// Output: 2456659
Run Code Online (Sandbox Code Playgroud)

这与http://www.php.net/manual/en/function.gregoriantojd.php的结果相同:

<?php
$jd = GregorianToJD(1, 1, 2014);
echo "$jd\n";
?>
Run Code Online (Sandbox Code Playgroud)

反方向(朱利安天到格里高利年/月/日):

NSInteger julianDays = 2456659; // From above example
NSUInteger julianDayFor01012000 = 2451545;
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[cal setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.year = 2000;
comp.month = 1;
comp.day = 1;
NSDate *ref = [cal dateFromComponents:comp];
NSDateComponents *diff = [[NSDateComponents alloc] init];
diff.day = julianDays - julianDayFor01012000;

NSDate *date = [cal dateByAddingComponents:diff toDate:ref options:0];
comp = [cal components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:date];
NSLog(@"%04ld-%02ld-%02ld", (long)comp.year, (long)comp.month, (long)comp.day);
// Output: 2014-01-01
Run Code Online (Sandbox Code Playgroud)

更新:正如Hot Licks在评论中正确陈述的那样,使用"g"格式的日期格式化程序更容易:

NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.year = 2014;
comp.month = 1;
comp.day = 1;
NSDate *date = [cal dateFromComponents:comp];
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"g"];
NSInteger julianDays = [[fmt stringFromDate:date] integerValue];
NSLog(@"%ld", (long)julianDays);
// Output: 2456659
Run Code Online (Sandbox Code Playgroud)

而反方向:

NSInteger julianDays = 2456659;
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"g"];
NSDate *date = [fmt dateFromString:[@(julianDays) stringValue]];
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comp = [cal components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:date];
NSLog(@"%04ld-%02ld-%02ld", (long)comp.year, (long)comp.month, (long)comp.day);
// Output: 2014-01-01
Run Code Online (Sandbox Code Playgroud)


cle*_*ght 6

精确度:将时间整合到Julian Date转换中

这些朱利安日期转换方法产生的结果与 美国海军天文台的 在线朱利安日期转换器相同,后者比NSDateFormatter's朱利安日期转换更精确.具体来说,下面的函数包含时间(例如小时,分钟和秒),而NSDateFormatter轮次到GMT中午.

斯威夫特的例子:

func jdFromDate(date : NSDate) -> Double {
    let JD_JAN_1_1970_0000GMT = 2440587.5
    return JD_JAN_1_1970_0000GMT + date.timeIntervalSince1970 / 86400
}

func dateFromJd(jd : Double) -> NSDate {
    let JD_JAN_1_1970_0000GMT = 2440587.5
    return  NSDate(timeIntervalSince1970: (jd - JD_JAN_1_1970_0000GMT) * 86400)
}
Run Code Online (Sandbox Code Playgroud)

Objective-C示例:

double jdFromDate(NSDate *date) {
   double JD_JAN_1_1970_0000GMT = 2440587.5;
   return JD_JAN_1_1970_0000GMT + date.timeIntervalSince1970 / 86400;
}

NSDate dataFromJd(double jd) {
   double JD_JAN_1_1970_0000GMT = 2440587.5;
   return [[NSDate alloc] initWithTimeIntervalSince1970: (jd - JD_JAN_1_1970_0000GMT) * 86400)];        
}
Run Code Online (Sandbox Code Playgroud)

注意:研究确认接受的答案将日期舍入为24小时间隔,因为它使用g格式说明符,该格式说明符NSDateFormatter返回修改后的朱利安日,根据Apple日期格式化API遵循的UNICODE标准的日期格式模式(根据到日期格式指南).

  • 我没有这样做,因为上次我尝试只更改一个字符时,我得到一个编辑说我必须更改更多,如果你问我的话,这是一个荒谬的编辑。 (2认同)