我需要与此 PHP 方法(GregorianToJD)相同的将公历日期转换为儒略日的 Objective C 方法。
问问题
4091 次
2 回答
9
精度:在儒略日期转换中包含一天中的时间
这些儒略日期转换方法产生的结果与 美国海军天文台的在线儒略日期转换器相同,它比NSDateFormatter's
儒略日期转换更精确。具体来说,以下函数包含时间(例如小时、分钟和秒),而NSDateFormatter
四舍五入到格林威治标准时间中午。
更新:链接到美国海军天文台的在线朱利安日期转换器已被删除,因为它被移动到一个新的网站地址,该地址指的是在此编辑时离线或丢失的服务器。如果您想查看它是否再次可用,请搜索 Google。
快速示例:
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)
}
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)];
}
注意:研究证实,接受的答案将日期四舍五入为 24 小时间隔,因为它使用 的g
格式说明符,根据Apple 的日期格式 API 遵守的 UNICODE 标准的日期格式模式NSDateFormatter
,它返回修改后的 Julian Day (根据日期格式指南)。
于 2014-12-30T16:52:15.437 回答
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
这给出了与http://www.php.net/manual/en/function.gregoriantojd.php相同的结果:
<?php
$jd = GregorianToJD(1, 1, 2014);
echo "$jd\n";
?>
反向(儒略日到公历年/月/日):
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
更新:正如 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
而对于相反的方向:
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
于 2014-04-03T07:10:04.287 回答