C:将朱利安日期转换成格里高利

时间:2014-10-02 17:06:37

标签: c matrix converter

这是我目前的代码,输出如下:

请输入大于2299160的朱利安日数

2299161

15 10 1582

然而,如果有例如小数2299161.1等,这并没有给我确切的时间。

如何在C中实现?我已经知道了数学:

0.1 days = 0.1 * 24 hours   = 2 hours    (remainder 0.4 hours),
       0.4 * 60 minutes = 24 minutes (remainder 0.0 seconds)
       0.0 * 60 seconds = 0 seconds

#include <stdio.h>

int main( ) {
   double jdn; /* you will need to store the user's input here... */
   long lc, kc, nc, ic, jc;
   int day, month, year;
   printf("Please Enter a Julian Day number greater than 2299160 \n");
   scanf("%lf",&jdn);


 if( jdn > 2299160 ){
   printf("%d\n",jdn);
   lc = jdn + 68569;
   nc = ((4 * lc) / 146097);
   lc = lc - ((146097 * nc + 3) / 4);
   ic = ((4000 * (lc + 1)) / 1461001);
   lc = lc - ((1461 * ic) / 4) + 31;
   jc = ((80 * lc) / 2447);
   day = lc - ((2447 * jc) / 80);
   lc = (jc / 11);
   month = jc + 2 - 12 * lc;
   year = 100 * (nc - 49) + ic + lc;

   printf("%d %d %d\n", day, month, year);
  }
  else {
  printf("Invalid number");
}
 return 0;
}

4 个答案:

答案 0 :(得分:1)

推荐@Paul R使用的floor()组合,@ user3386109和%使用的整数*round()

#include <math.h>

double frac_d = jdn - floor(jdn);  // @Paul R

#define SecPerDay (24L*60*60)
long  frac_l = (long) round(frac_d * SecPerDay);

int sec = frac_l % 60;  // @user3386109
frac_l /= 60;
int min = frac_l % 60;
frac_l /= 60;
int hrs = total;

如果发生负朱利安日期时间,则使用floor()modf()非常重要。

在分配整数之前舍入一个双保险,确保像12.99999999这样的值取整数值13而不是12。

出于便携性原因,对于可能超过32767的值,首选long而不是int


[edit]

我对以下声明的担忧并未得到证实。计算h,m,s的任何一种方法都会与一致的值同样出色。仍然更喜欢整数方法,因为代码更少,更容易控制舍入。

“从一个整数计算h,m,s可确保分数中的一致值。” (无效)

答案 1 :(得分:0)

您可以像这样采用小数部分:

#include <math.h>

double jdn_frac = jdn - floor(jdn);

然后将它转换为h:m:s:

非常简单
int h = (int)(jdn_frac * 24.0);
int m = (int)((jdn_frac * 24.0 - h) * 60.0);
int s = (int)(((jdn_frac * 24.0 - h) * 60.0 - m) * 60.0);

LIVE DEMO

答案 2 :(得分:0)

首先将输入数字分成整数和小数部分

double n, f;
f = modf( jdn, &n );

这将为f中的0.1和n中的2299161提供。

然后将小数部分转换为秒:

0.1 days = 0.1 * 24 hours = 0.1 * 24 * 3600 seconds

int total = f * 24 * 3600;

然后你可以使用modulo和division

分解它
seconds = total % 60;
total /= 60;
minutes = total % 60;
total /= 60;
hours = total;

答案 3 :(得分:0)

请注意,上述两个帖子中的秒数,分钟数和小时数将是平均太阳时时间单位。目前,平均太阳日长度为86400.002秒(http://tycho.usno.navy.mil/leapsec.html)。如果你需要4000万分之一的精度,你需要纠正这个问题。 : - )