【问题标题】:Inconsistent DateTime to Unix Time conversion and error on 24 hour inputDateTime 到 Unix 时间转换和 24 小时输入错误
【发布时间】:2014-03-24 14:23:10
【问题描述】:

附件是我目前使用的一种方法,它接收DateTime 字符串列表、它们的输入格式(即yyyy-MM-dd HH:mm:ss)以及它们以小时为单位的偏移量。

至于文化和“标准”,我使用InvariantCulture,并将时间转换为UTC

    public int unixFormat3(string dateTimeInput, string inputFormat, int hours)
    {
        DateTime result;
        CultureInfo provider = CultureInfo.InvariantCulture;
        result = DateTime.ParseExact(dateTimeInput, inputFormat, provider);

        int unixTime = (Int32)(result.ToUniversalTime().AddHours(hours).Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc))).TotalSeconds;
        return unixTime;
    }

上述方法的两个问题:

  1. 我使用这个网站作为比较。如果我的输入是2014-03-18 21:00:00,根据我的方法,我的输出是1395190800,它转换回2014-03-19 01:00:00。它有四个小时的差异。所需的输出是这样的:

  1. 如果我的输入是2014-03-18 24:00:00,我会收到以下错误:

The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.

值得注意的是,它不允许在HH 部分输入24。这是一个奇怪的错误,因为 NodaTime 处理得很好......虽然这与我使用 DateTime 无关。

有人对这个领域有任何见解吗?

编辑:

经过一些实验,删除 .ToUniversalTime() 会删除我的 4 小时偏移量。为什么会发生这种情况?

public int unixFormat3(string dateTimeInput, string inputFormat, int hours)
{
    DateTime result;
    CultureInfo provider = CultureInfo.InvariantCulture;
    result = DateTime.ParseExact(dateTimeInput, inputFormat, provider);

    int unixTime = (Int32)(result.AddHours(hours).Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc))).TotalSeconds;
    return unixTime;
}

【问题讨论】:

  • 3/19 00:00 不行吗?
  • 它确实有效,尽管24:00 没有。在DateTime 库看来,24:0000:00 似乎不是一回事。
  • 打电话给 Jon Skeet 和 Matt Johnson :)。

标签: c# datetime timezone unix-timestamp dst


【解决方案1】:

此问题How to know whether a given string is a valid UTC DateTime format? 中引用的文档http://www.w3.org/TR/NOTE-datetime 未将24 列为有效小时值。

该问题的答案引用的这份文档http://en.wikipedia.org/wiki/Iso8601 确实将 24:00 列为有效时间。这个http://en.wikipedia.org/wiki/12-hour_clock#Confusion_at_noon_and_midnight也说24:00有效。

【讨论】:

    【解决方案2】:

    System.DateTime 对象将小时表示为 0 到 23 之间的整数值(请参阅http://msdn.microsoft.com/en-us/library/vstudio/system.datetime.hour(v=vs.100).aspx)。据我所知,NodaTime 不使用任何 .NET 提供的 DateTimeDateTimeOffset 类并自行处理所有内容,这就是它正确处理 24 小时的原因。

    至于ToUniversalTime()为什么要添加偏移量,可能是因为ParseExact返回的日期已经调整过了。 (在您调用ToUniversalTime() 之前,result 的值是多少?)

    您可能还想更改您的调用以改用 ParseExact 的重载:

    result = DateTime.ParseExact(dateTimeInput, inputFormat, provider, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
    

    这告诉解析器如果在解析的字符串中没有指定时区,则假定时间为 UTC。

    附带说明一下,您可能应该在某处将您的 Unix 纪元声明为只读全局变量,并使用 TryParseExact 而不是 ParseExact

    public class UnixTime
    {
        public static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
    
        public int unixFormat3(string dateTimeInput, string inputFormat, int hours)
        {
            int unixTime = -1;
            DateTime result = DateTime.MinValue;
            if (DateTime.TryParseExact(dateTimeInput, inputFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out result))
            {
                unixTime = (int)(result.AddHours(hours).Subtract(UnixTime.Epoch)).TotalSeconds;
            }
    
            return unixTime;
        }
    }
    

    【讨论】:

    • 非常感谢您的详细回答。这是非常有用的。你能给我一个关于如何处理 C# 不处理 24 的建议吗?这看起来很奇怪;我可以想象很多情况下会有 24 作为输入。
    • DateTimeStyles.AssumeUniversal puu.sh/7HUMD/2f48f7e43d.png。没有ToUniversalTime()DateTimeStyles.AssumeUniversal: puu.sh/7HUUv/a6cf577df3.png 看来,当您不假设/ UTC 时,代码不会为您偏移。当您假设 UTC 时,它会为您抵消。它究竟是如何假设我的偏移量的?根据我的电脑和我的时区,我的时区是:UTC -05:00,而不是-04:00
    • 哇。我对 DateTimes 和时区了解得越多,我就越困惑。由于输入是2014-03-18 21:00:00,因此它与时区无关。它是什么时区是模棱两可的,因为没有语言环境或时区标签。您认为默认情况下是 UTC 吗?
    • 你应该有DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal。否则,输入将被视为通用输入,但随后会转换为 local.
    • @MattJohnson,我更新了代码以包含“DateTimeStyles.AdjustToUniversal”。谢谢!
    猜你喜欢
    • 2021-12-24
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多