【问题标题】:Convert date (year, month, day) to Julian Day Number and back to date将日期(年、月、日)转换为儒略日数并返回日期
【发布时间】:2018-05-29 01:11:44
【问题描述】:

我正在尝试实现两个功能,1)将日期转换为儒略日数和 2)将儒略日数转换回日期(年、月和日)。我的代码返回的结果是一天。我不熟悉该算法的工作原理,但我可以看到,如果我采用 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!
    }
}

【问题讨论】:

  • 作为其中一种可能算法的可能实现之一,您应该向我们展示您从哪里获取算法...
  • @xanatos 我从这里得到它:hermetic.ch/cal_stud/jdn.htm
  • @nodejs 您的 JulianNumber 与链接网址中的完全不同。那是jd = ( 1461 * ( y + 4800 + ( m - 14 ) / 12 ) ) / 4 + ( 367 * ( m - 2 - 12 * ( ( m - 14 ) / 12 ) ) ) / 12 - ( 3 * ( ( y + 4900 + ( m - 14 ) / 12 ) / 100 ) ) / 4 + d - 32075,只有整数除法(除法被理解为整数算术,余数被丢弃,并且 (m-14)/12 对于 m )
  • 请注意,您的舍入问题可能是由于儒略日从中午开始的事实引起的......所以 28 May 2018 00.00 是 2458266.5 。例如onlineconversion.com/julian_date.htm

标签: c# calendar julian-date


【解决方案1】:

问题在于儒略日的定义。取自您链接的页面:

继赫歇尔的主要天文学家之后,他们采用了这个系统,并以格林威治标准时间 -4712-01-01 JC(公元前 4713 年 1 月 1 日)中午为零点

所以 2018-05-28 在 00.00 是 2458266.5,而 2018-05-28 在 12.00 是 2458267。如果你看你的 JulianNumber 而没有 Math.Ceiling 实际上返回 2458266.5。现在,the page you linked(您从中采用 second 方法,GregorianDate 仅使用整数,因此它适用于中午 (12.00) 的日期。因此,通过向上取整(上限) JulianNumber 的结果是将日期移至 12.00 小时,并使其与 GregorianDate“兼容”。

可能的解决方案:为JulianNumber 使用same page 中存在的算法,并且在任何地方只使用int(以表明您忽略了小时、分钟、秒),或搜索另一种算法GregorianDate.

【讨论】:

    猜你喜欢
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 2013-07-21
    • 2015-11-08
    • 2020-01-11
    • 1970-01-01
    相关资源
    最近更新 更多