在 C# 中计算未来纪元时间

Posted

技术标签:

【中文标题】在 C# 中计算未来纪元时间【英文标题】:Calculating Future Epoch Time in C# 【发布时间】:2010-10-28 16:59:41 【问题描述】:

我能够找到示例代码来获取 Linux Epoch 中的当前时间戳(自 1970 年 1 月 1 日午夜以来的秒数),但是我无法找到一个关于如何计算未来 Epoch 的示例,比如说例如从现在开始 10 分钟,那么我如何计算 Linux Epoch 中的未来时间?

【问题讨论】:

您声明“如何计算未来的纪元,例如从现在开始 10 分钟”是令人困惑的。 Unix 纪元总是 01/01/1970 00:00:00,即使是 10 分钟!您的意思是“如何计算自 Unix 纪元以后的秒数,例如从现在开始 10 分钟” 【参考方案1】:

这个扩展方法应该可以完成这项工作:

private static double GetUnixEpoch(this DateTime dateTime)

    var unixTime = dateTime.ToUniversalTime() - 
        new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    return unixTime.TotalSeconds;

你可以这样使用它:

var unixTime1 = DateTime.Now.GetUnixEpoch(); // precisely now
var unixTime2 = (DateTime.Now + new TimeSpan(0, 10, 0)).GetUnixEpoch(); // 10 minutes in future

请注意,您需要处理 UTC(世界标准时间)中的所有日期时间,因为这是定义 Unix 纪元开始的方式。

【讨论】:

请注意,ToUniversalTime() 将未指定种类的时间视为本地时间,这对于您的应用可能正确也可能不正确。这就是为什么在创建 DateTime 时最好指定 Kind 的原因。见msdn.microsoft.com/en-us/library/… @Matthew:是的,好点子(尽管如果您只是使用相对于现在的时间,则无需担心)。但是,您仍然需要转换为 UTC。 所以我终于真正阅读了您的代码并理解了它。我希望我可以再投票大约 10 次。谢谢:)【参考方案2】:

当您想知道 Windows 系统上 .Net 中的 Unix 纪元时间时,有一个有趣的转折。

对于几乎所有实际情况,并假设当前时间已超过 Unix 纪元,您确实可以采取

System.TimeSpan timeDifference = DateTime.UTCNow - 
            new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long unixEpochTime = System.Convert.ToInt64(timeDifference.TotalSeconds);

但是,

Unix Epoch Time 被定义为“......一个用于描述时间点的系统,定义为自 1970 年 1 月 1 日协调世界时 (UTC) 午夜以来经过的秒数,不计算闰秒。” (1)

自 1972 年以来,UTC 已包含“闰秒”,到目前为止,我们总共有 25 个。 (2)

.Net DateTime 没有关于闰秒的规定,而是仅依赖于操作系统时间。 Windows 很高兴地不知道闰秒 (3)(4),因此当它从其 NTP 主机接收到时间时,它只会有时间的概念(我相信非域连接机器的默认设置是 time.windows.com ) ,这可能正在提供包括闰秒在内的 UTC。

这意味着,为了准确地了解自 Unix 纪元以来经过的实际秒数,对于依赖于此的应用程序,您可能应该将闰秒添加到上面获得的结果中。您必须跟踪每次添加的秒数,因为闰秒并未提前宣布 (2)。但是,由于 Unix Epoch Time 的定义明确排除了闰秒,您可以放心地忽略这一点并简单地从当前 UTC 时间重新计算秒数。

有时,闰秒确实会导致软件混乱 (5)。关于是否保留或消除这种做法的辩论正在进行中 (6)(7)(8)。

回答时的最后一个闰秒发生在 2012 年 7 月 1 日 (9),并导致各种站点和应用程序出现问题 (10)

(1)http://en.wikipedia.org/wiki/Unix_time

(2)http://en.wikipedia.org/wiki/Leap_second

(3)http://support.microsoft.com/kb/909614

(4)http://www.meinberg.de/english/info/leap-second.htm

(5)http://www.networkworld.com/news/2009/010609-leap-second-snafu-affects-oracle.html

(6)http://www.pcworld.idg.com.au/article/358024/time_waits_no_one_leap_seconds_may_cut/

(7)http://queue.acm.org/detail.cfm?id=1967009

(8)http://arxiv.org/abs/1106.3141

(9)http://hpiers.obspm.fr/iers/bul/bulc/bulletinc.dat

(10)http://arstechnica.com/business/2012/07/one-day-later-the-leap-second-v-the-internet-scorecard/

(原答案有误,幸好被下方评论者 Edward Brey 和 Mormegil 发现)

【讨论】:

+1 因为这很有趣,但是因为我的工作时间是分钟(在大多数情况下更像是小时)并且操作不是非常精确,我不认为 24​​ 秒是将是一个大问题,但感谢您指出。 我不认为这是正确的。两种假设都很好(Unix 和 Windows 都没有计算/知道闰秒),但是您得出错误的结论,恕我直言。 Unix 时间忽略闰秒,这意味着它认为1973-01-01T00:00:00Z 是 Unix 时间 94694400,即(365 + 366 + 365) * 24 * 60 * 60,即使同时经过了两个闰秒。 Windows 也是如此。它从 NTP 主机知道它是1973-01-01T00:00:00Z,但它不知道两个闰秒。 Unix&Windows时间不是连续的时间尺度,但它们是相互同步的。 这就是为什么我说“迂腐正确”。我们与 Unix 纪元时间的官方定义进行比较,而不是与 Unix 系统上的实际实现进行比较,正如您所指出的那样窗户。 实用的 Unix 实现是迂腐正确的。它基于纪元的数学不考虑闰秒,这与官方定义相符。为了澄清,这里有一个迂腐的问答:1973-01-01T00:00:00Z 的 Unix 纪元时间是多少? 94694400。从 1970-01-01T00:00:00Z 到 1973-01-01T00:00:00Z 经过了多少真实世界的秒数? 94694402. 感谢 Edward Brey 和 Mormegil 的澄清。我将编辑答案以反映您的见解。【参考方案3】:

基本解决方案:

    获取当前时间 向未来添加偏移量(在您的示例中为 10 分钟) 减去 1970 年 1 月 1 日午夜 获取两者之间的总秒数

在 c# 中(在我脑海中,未经测试):

DateTime myEpoch = DateTime.Now.Add( new TimeSpan(...) );
return myEpoch.Subtract( new DateTime(1970, 1, 1, 0, 0, 0) ).TotalSeconds;

【讨论】:

【参考方案4】:

你用什么函数来获取当前时间?

当然需要一个 .NET DateTime 参数...

当然,这只是将未来的 DateTime 传递给函数的简单问题。

或在当前时间和未来时间之间以秒为单位执行 DateDiff 并将其添加。

var dt = new DateTime(1970, 1, 1, 0, 0, 0).ToUniversalTime();

var now = System.DateTime.Now.ToUniversalTime();
var future = new DateTime(2010, 1, 1).ToUniversalTime();

Console.WriteLine((now - dt).TotalSeconds);
Console.WriteLine((future - dt).TotalSeconds);

【讨论】:

这需要在UTC时间范围内完成,否则是正确的。

以上是关于在 C# 中计算未来纪元时间的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中获取今天上午 9 点的 PST 纪元 [重复]

如何从两个纪元时间戳计算 hh:mm:ss 中 hh:mm:ss 的差异?

计算 Unix 纪元时间是不是出现在今天的 SQLite 查询

在 C# 中计算相对时间

在 C# 中计算相对时间

将人类可读的日期转换为纪元时间戳