【问题标题】:How to convert an official DateTime to the astronomically exact DateTime?如何将官方日期时间转换为天文精确的日期时间?
【发布时间】:2014-10-31 11:29:05
【问题描述】:

我一直试图弄清楚如何将生日 (DateTime) 转换为天文“精确”的 DateTime 值。时区:UTC+1。

示例:

我的朋友出生于 1984-01-27 11:35

1984 年是闰年。但 1700、1800 和 1900 年不是闰年。因此,直到 2000 年 2 月 29 日,我们在天文精确时间上都落后了。 1984 年,我们“几乎”落后了一天。所以天文学上的准确时间应该是在我朋友出生的官方日期时间之后,对吧?

这些是我所知道的公历调整:

  • 一年有365天
  • 每第 4 年为闰年(= 有 366 天而不是 365 天)
  • 每 100 年不是闰年
  • 每 400 年为闰年(尽管之前的规则)
  • 在 2 月底添加额外的一天(闰年 2 月有 29 天)

从天文上看,一年有 365,2422 天。 这意味着一天有 24,0159254794 小时。 官方时间和天文时间“完全相同”的时间值应该是 2000-03-01T00:00:00,对吧?

因此,我们需要弄清楚在给定的官方时间,官方时间和天文精确时间之间的差异有多大。

我已经考虑了好几个小时,直到我的头开始疼。我想我会和你分享我的头痛。也许你们知道任何可以计算这个的时间库?

【问题讨论】:

  • 这不仅仅是恒星年的长度。您的问题似乎是将UTC转换为“平均太阳时”(UT1)甚至“视太阳时”。后者需要“时间等式”(谷歌会帮助你)。对于第一个(UTC => UT1),您需要根据 IERS 发布的观测数据或基于近似公式(Jean Meeus 等人)了解 delta-T 关系。所以解决方案比你想象的要复杂得多。至少您还需要地理坐标,而不仅仅是天文计算不精确的时区。
  • “天文一年有 365,2422 天。这意味着一天有 24,0159254794 小时”,好吧,这不是真的。年和日是独立的概念。 (朔望)日与地球围绕其自身轴的自转有关,而年与地球围绕太阳公转有关。两种不同的动作。但是你当然可以用天作为时间单位来衡量一年的长度。
  • 感谢您的 cmets。我在下面发布了一个简单的“解决方案”。你怎么看?

标签: date datetime


【解决方案1】:

我想出了一个似乎相当准确的“解决方案”。它的作用如下:

  • 该方法从 1600-03-01T00:00 开始。在教皇格里高尔十三世之后 18 年。 (我们的公历系统以他的名字命名)在 1582 年修正了儒略历(以凯撒大帝命名),宣布 10 月 4 日(星期四)之后的第二天是 10 月 15 日(星期五) - 所以实际上没有 5 日到历史书籍中的 1582 年 10 月 14 日 - 并且还在日历系统中添加了第 100 年和第 400 年的规则。
  • 该方法总结了官方日期与确切日期之间的差异,直到到达给定日期。
  • 在闰年,它应用教皇格里高尔十三世添加的修正。它会在 2 月底这样做。

代码:

public static DateTime OfficialDateTimeToExactDateTime(DateTime dtOfficial)
{
    const double dExactDayLengthInHours = 24.0159254794;
    DateTime dtParse = new DateTime(1600, 3, 1, 0, 0, 0);
    double dErrorInHours = 0.0;

    while (dtParse <= dtOfficial)
    {
        dErrorInHours += dExactDayLengthInHours - 24;
        dtParse = dtParse.AddDays(1);
        if (dtParse.Month == 3 && dtParse.Day == 1 &&
            ((dtParse.Year % 4 == 0 && dtParse.Year % 100 != 0) ||
             (dtParse.Year % 400 == 0)) )
        {
            dErrorInHours -= 24;
        }
    }

    dErrorInHours += ((double)dtOfficial.Hour + (double)dtOfficial.Minute / 60 + (double)dtOfficial.Second / 3600) *  (dExactDayLengthInHours - 24);

    return dtOfficial.AddHours(dErrorInHours * -1);
}

我做了一些健全性测试:

  • 如果您在 2000-03-01T00:00 之前传递一个日期,您会得到一个负更正。因为我们测量的天数实际上更短。
  • 如果您在 2000-03-01T00:00 之后传递一个日期,您会得到一个正的更正。这是因为 2000 年是闰年(而 1700、1800 和 1900 年不是),但应用的修正太大。在 24 x 400 = 4800 年的时间里,这个修正大约会过大一天。因此,在 1600 + 4800 = 6400 年(如果人还活着),您需要将 6400 减为非闰年,尽管有公历规则。

【讨论】:

  • “因为我们测量的天数实际上更短。”嗯,没有。平均太阳日的长度与地球绕其自身轴的自转有关,并且与任何年份的长度无关。所以这样的一天总是 24 小时(在 UT1 尺度上)。您更愿意描述的是天文年和公历年之间以天为单位表示的差异。
  • 没错。这就是我想说的。但是计算应该从他们修好日历的那一天开始吧?!
  • 好的,所以我们有固定的天数(仅在分钟精度的情况下),但年份的长度不同。那就是比较持续时间。我们可以使用您的想法从 1600-01-01 作为参考点开始,然后将两个持续时间添加到该点以获得新的日期/时间戳。您可以使用类 TimeSpan 来评估 1600 和方法参数之间的天数,然后转换天数,最后将天文天数添加到 1600 以获得“天文”时间戳。这对我来说听起来仍然像一个黑客,但似乎比一个计数循环更好。请记住,1600 的选择仍然是任意的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 2010-11-03
  • 1970-01-01
  • 2013-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多