将日期(年、月、日)转换为儒略日数并返回日期
Convert date (year, month, day) to Julian Day Number and back to date
我正在尝试实现两个功能,1) 将日期转换为 Julian Day Number 和 2) 将 Julian Day Number 转换回日期(年、月和日)。结果我的代码 returns 关闭了一天。我不熟悉该算法的工作原理,但我可以看到,如果我采用 Julian 数的 Math.Ceiling
它可以工作,但我不确定这是修复代码的最佳方法。任何帮助将不胜感激。谢谢。
public class Program
{
/// <summary>
/// Converts year, month and day to a Julian number
/// </summary>
/// <param name="year"></param>
/// <param name="month"></param>
/// <param name="day"></param>
/// <returns></returns>
public static decimal JulianNumber(int year, int month, int day)
{
decimal a, b, c, e, f;
if (month == 1 || month == 2)
{
year -= 1;
month += 12;
}
a = Math.Truncate((decimal) year / 100);
b = Math.Truncate(a / 4);
c = 2 - a + b;
e = Math.Truncate((365.25m * (year + 4716)));
f = Math.Truncate((30.6001m * (month + 1)));
return (c + day + e + f - 1524.5m);
// return Math.Ceiling(c + day + e + f - 1524.5m);
}
/// <summary>
/// Converts Julian number to year, month and day
/// </summary>
/// <param name="julianNumber"></param>
/// <returns></returns>
public static (int year, int month, int day) GregorianDate(decimal julianNumber)
{
int l, n, i, j, k;
l = (int)julianNumber + 68569;
n = 4 * l / 146097;
l = l - (146097 * n + 3) / 4;
i = 4000 * (l + 1) / 1461001;
l = l - 1461 * i / 4 + 31;
j = 80 * l / 2447;
k = l - 2447 * j / 80;
l = j / 11;
j = j + 2 - 12 * l;
i = 100 * (n - 49) + i + l;
return (i, j, k);
}
public static void Main(string[] args)
{
var (year1, month1, day1) = (2010, 1, 2);
var (year2, month2, day2) = GregorianDate(JulianNumber(year1, month1, day1));
Console.WriteLine(year1 == year2); // True
Console.WriteLine(month1 == month2); // True
Console.WriteLine(day1 == day2); // False!
}
}
问题出在儒略日的定义上。取自您链接的页面:
Following Herschel's lead astronomers adopted this system and took noon GMT -4712-01-01 JC (January 1st, 4713 B.C.) as their zero point
所以 2018-05-28 的 00.00 是 2458266.5,而 2018-05-28 的 12.00 是 2458267。如果你看你的 JulianNumber
而没有 Math.Ceiling
事实上 returns 2458266.5。现在,the page you linked(您从中获取了 second 方法 GregorianDate
,仅使用整数,因此它适用于中午 (12.00) 的日期。所以通过向上舍入(上限)JulianNumber
的结果,您将日期移动到 12.00 小时,并使 "compatible" 与 GregorianDate
。
可能的解决方案:对 JulianNumber
使用 same page 中存在的算法,并在所有地方仅使用 int
(以表明您忽略了小时、分钟、秒),或搜索 GregorianDate
.
的另一种算法
我正在尝试实现两个功能,1) 将日期转换为 Julian Day Number 和 2) 将 Julian Day Number 转换回日期(年、月和日)。结果我的代码 returns 关闭了一天。我不熟悉该算法的工作原理,但我可以看到,如果我采用 Julian 数的 Math.Ceiling
它可以工作,但我不确定这是修复代码的最佳方法。任何帮助将不胜感激。谢谢。
public class Program
{
/// <summary>
/// Converts year, month and day to a Julian number
/// </summary>
/// <param name="year"></param>
/// <param name="month"></param>
/// <param name="day"></param>
/// <returns></returns>
public static decimal JulianNumber(int year, int month, int day)
{
decimal a, b, c, e, f;
if (month == 1 || month == 2)
{
year -= 1;
month += 12;
}
a = Math.Truncate((decimal) year / 100);
b = Math.Truncate(a / 4);
c = 2 - a + b;
e = Math.Truncate((365.25m * (year + 4716)));
f = Math.Truncate((30.6001m * (month + 1)));
return (c + day + e + f - 1524.5m);
// return Math.Ceiling(c + day + e + f - 1524.5m);
}
/// <summary>
/// Converts Julian number to year, month and day
/// </summary>
/// <param name="julianNumber"></param>
/// <returns></returns>
public static (int year, int month, int day) GregorianDate(decimal julianNumber)
{
int l, n, i, j, k;
l = (int)julianNumber + 68569;
n = 4 * l / 146097;
l = l - (146097 * n + 3) / 4;
i = 4000 * (l + 1) / 1461001;
l = l - 1461 * i / 4 + 31;
j = 80 * l / 2447;
k = l - 2447 * j / 80;
l = j / 11;
j = j + 2 - 12 * l;
i = 100 * (n - 49) + i + l;
return (i, j, k);
}
public static void Main(string[] args)
{
var (year1, month1, day1) = (2010, 1, 2);
var (year2, month2, day2) = GregorianDate(JulianNumber(year1, month1, day1));
Console.WriteLine(year1 == year2); // True
Console.WriteLine(month1 == month2); // True
Console.WriteLine(day1 == day2); // False!
}
}
问题出在儒略日的定义上。取自您链接的页面:
Following Herschel's lead astronomers adopted this system and took noon GMT -4712-01-01 JC (January 1st, 4713 B.C.) as their zero point
所以 2018-05-28 的 00.00 是 2458266.5,而 2018-05-28 的 12.00 是 2458267。如果你看你的 JulianNumber
而没有 Math.Ceiling
事实上 returns 2458266.5。现在,the page you linked(您从中获取了 second 方法 GregorianDate
,仅使用整数,因此它适用于中午 (12.00) 的日期。所以通过向上舍入(上限)JulianNumber
的结果,您将日期移动到 12.00 小时,并使 "compatible" 与 GregorianDate
。
可能的解决方案:对 JulianNumber
使用 same page 中存在的算法,并在所有地方仅使用 int
(以表明您忽略了小时、分钟、秒),或搜索 GregorianDate
.