如何使用 C#/.NET 将日期时间转换为时间戳(忽略当前时区)

Posted

技术标签:

【中文标题】如何使用 C#/.NET 将日期时间转换为时间戳(忽略当前时区)【英文标题】:How to convert datetime to timestamp using C#/.NET (ignoring current timezone) 【发布时间】:2012-04-06 12:41:54 【问题描述】:

如何使用 C# .NET 将日期时间转换为时间戳(忽略当前时区)?

我正在使用以下代码:

private long ConvertToTimestamp(DateTime value)

    long epoch = (value.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
    return epoch;

但是它根据当前时区返回时间戳值&我需要结果而不使用当前时区。

【问题讨论】:

***.com/questions/892074/… 【参考方案1】:

从 DateTime 中查找时间戳:

private long ConvertToTimestamp(DateTime value)

    TimeZoneInfo NYTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
    DateTime NyTime = TimeZoneInfo.ConvertTime(value, NYTimeZone);
    TimeZone localZone = TimeZone.CurrentTimeZone;
    System.Globalization.DaylightTime dst = localZone.GetDaylightChanges(NyTime.Year);
    NyTime = NyTime.AddHours(-1);
    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
    TimeSpan span = (NyTime - epoch);
    return (long)Convert.ToDouble(span.TotalSeconds);

【讨论】:

你根本没有使用 dst!【参考方案2】:

此时您正在调用ToUniversalTime() - 摆脱它:

private long ConvertToTimestamp(DateTime value)

    long epoch = (value.Ticks - 621355968000000000) / 10000000;
    return epoch;

另外,更易读的 IMO:

private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
...

private static long ConvertToTimestamp(DateTime value)

    TimeSpan elapsedTime = value - Epoch;
    return (long) elapsedTime.TotalSeconds;

编辑:如 cmets 中所述,执行减法时不会考虑传入的 DateTimeKind。你真的应该传入一个带有KindUtc 的值,这样才能正常工作。不幸的是,DateTime 在这方面有点破旧 - 请参阅my blog post(关于DateTime 的咆哮)了解更多详细信息。

您可能想改用我的 Noda Time 日期/时间 API,这会使一切变得更加清晰,IMO。

【讨论】:

也更喜欢第二个。 Op 没有说他想要什么,但是如果将其转换为二进制,则输出是否等同于 SqlServer 在创建时间戳时会生成的内容?还有为什么演员阵容很长,没有启动 VS 来检查,但 TotalSeconds 没有返回很长? @Bronumski:不,它返回一个double。我不知道它是否具有可比性,恐怕 - 我不知道 SQL Server 是做什么的。 SQL Server 有 0 = 1900-01-01 00:00:00.000,根据我对创建日期时间和填充数字的蹩脚测试。加 1 加 1 天。添加 0.5 增加 12 小时。对于 1900 年之前的年份,该值可以小于 0。 @A rash:是的,这样更好——虽然还不够,因为减法时没有考虑到种类。此外,未指定的类型与本地不同 - 这有点疯狂。我的 Noda Time 图书馆更清楚地处理了这个问题,IMO :) @ArashMilani - 您可能可以调整上面的代码以使用 Local kind,但没有办法使它与 Unspecified kind 一起使用,因为它不知道如何它与UTC有关。并且由于Local 仅来自DateTime.Now,您可以在其中使用DateTime.UtcNow,那么使用Utc 之外的其他类型确实没有任何好处。我可以证明 NodaTime 是一个更好的解决方案。另见this blog post我写的。【参考方案3】:

JonSkeet 有一个很好的答案,但作为替代方案,如果您想让结果更便携,您可以将日期转换为 ISO 8601 格式,然后可以将其读取到大多数其他框架中,但这可能超出您的要求。

value.ToUniversalTime().ToString("O");

【讨论】:

【参考方案4】:

我不确定你想要什么。你想要一个时间戳吗?然后你可以做一些简单的事情,比如:

TimeStamp ts = TimeStamp.FromTicks(value.ToUniversalTime().Ticks);

既然你命名了一个变量时期,你想要你的日期的 Unix 时间吗?

DateTime unixStart = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc);
long epoch = (long)Math.Floor((value.ToUniversalTime() - unixStart).TotalSeconds);

【讨论】:

DateTime unixStart = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc); long epoch = (long)Math.Floor((value.ToUniversalTime() - unixStart).TotalSeconds);这也返回与我的代码相同的结果... 那我不明白你的代码有什么问题。我在生产代码中使用它来获取 Unix 时间戳(即 UTC),据我所知它是有效的。不管value在哪个时区,我总是得到正确的对应UTC时间。 如果你只想要纪元时间,对应与原始值相同的时区,那么Jon Skeet发布的代码是正确的。

以上是关于如何使用 C#/.NET 将日期时间转换为时间戳(忽略当前时区)的主要内容,如果未能解决你的问题,请参考以下文章

如何将日期转换为时间戳?

如何将日期时间转换为时间戳 Python

使用 PySpark 将日期和时间字符串转换为时间戳时如何保留毫秒?

Javascript:如何将 exif 日期时间数据转换为时间戳? [复制]

C#将日期转换为时间戳[重复]

将日期和时间转换为时间戳 [重复]