【问题标题】:Unix Timestamp has a UTC differenceUnix Timestamp 有 UTC 差异
【发布时间】:2021-05-11 16:25:46
【问题描述】:

我需要将日期和时间字符串转换为纪元时间戳。我得到了 11 小时的时差,(我认为这是 UTC 与本地时差)。

using System;
                    
public class Program
{
    public static void Main()
    {
        var output = StringDateToUnixString("08-02-2021 23:59:59", "dd-MM-yyyy HH:mm:ss");
        Console.WriteLine($"Result : {output}");
        Console.WriteLine("Expected: 1612789199000");
        if(output == 1612789199000)
        {
            Console.WriteLine("Match");
        }
        else
        {
            Console.WriteLine("Not a match");
        }
    }
    
    public static double StringDateToUnixString(string dateString, string currentFormat)
    {
        var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        DateTime date = DateTime.ParseExact(dateString, currentFormat, System.Globalization.CultureInfo.InvariantCulture);
        return Convert.ToInt64((date - epoch).TotalMilliseconds);
    }
}

当我检查时,纪元和本地时间是 UTC,但是 (UTC-UTC).TotalMilliseconds,当转换回来时是本地时间。 我非常感谢我可以更新 StringDateToUnixString 函数,以便 Main 可以按预期工作。

【问题讨论】:

标签: c# datetime asp.net-core .net-core epoch


【解决方案1】:

你试过这个吗?获取unix时间戳:

DateTimeOffset.Now.ToUnixTimeMilliseconds();

以及将时间戳转换为日期时间:

return new DateTimeOffset(1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero).AddMilliseconds(1612789199000).UtcDateTime;

【讨论】:

  • 没用,除非你想给我提供完整的代码。我可能做错了什么。
【解决方案2】:

问题是因为您减去两个具有不同含义的DateTime 值。您的 epoch 变量是基于 UTC 的,其 Kind 属性设置为 DateTimeKind.Utc,而您的 date 变量是基于本地时间的,其 Kind 属性设置为 DateTimeKind.Unspecified

但是,在减去或比较 DateTime 值时 - 不考虑 Kind 属性。该操作仅基于Ticks 属性。

将此与DateTimeOffset 值进行对比,其中偏移量被考虑到此类操作中。

您可以通过几种不同的方式在代码中解决此问题,并且仍然可以从基于本地时间的日期/时间字符串调整为 Unix 时间戳(本质上是基于 UTC):

  • 您可以在解析后将 date 值转换为 UTC,然后再减去:

    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    DateTime dateTime = DateTime.ParseExact(dateString, currentFormat, CultureInfo.InvariantCulture);
    return (dateTime.ToUniversalTime() - epoch).TotalMilliseconds;
    
  • 您可以告诉DateTime.ParseExact,您希望输入字符串被假定为本地时间并且输出值应调整为UTC 的行为。这是通过组合 AssumeLocalAdjustToUniversal DateTimeStyles 标志来完成的,如下所示:

    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    DateTime dateTime = DateTime.ParseExact(dateString, currentFormat, CultureInfo.InvariantCulture,
        DateTimeStyles.AssumeLocal | DateTimeStyles.AdjustToUniversal);
    return (dateTime - epoch).TotalMilliseconds;
    
  • 您可以将值解析为DateTimeOffset 而不是DateTime。这样做时,如果输入字符串中没有偏移量,则使用本地时区。这种方法还有一个优点是可以使用内置的ToUnixTimeMilliseconds方法:

    DateTimeOffset dateTimeOffset = DateTimeOffset.ParseExact(dateString, currentFormat, CultureInfo.InvariantCulture);
    return dateTimeOffset.ToUnixTimeMilliseconds();
    

请注意,在所有三种情况下,我都假设 using System.Globalization; 包含在程序的顶部,并且我从结果中删除了 Convert.ToInt64,因为它是无关的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    • 2014-03-23
    相关资源
    最近更新 更多