如何知道给定的字符串是否是有效的UTC DateTime格式?

The*_*ght 3 c# asp.net datetime parsing

我需要允许接受UTC日期时间:http://www.w3.org/TR/NOTE-datetime

如:

 - Year:
         YYYY (eg 1997)    Year and month:
         YYYY-MM (eg 1997-07)    Complete date:
         YYYY-MM-DD (eg 1997-07-16)    Complete date plus hours and minutes:
         YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)    Complete date plus hours, minutes and seconds:
         YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)    Complete date plus hours, minutes, seconds and a decimal fraction of
   a second
         YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00) where:

        YYYY = four-digit year
        MM   = two-digit month (01=January, etc.)
        DD   = two-digit day of month (01 through 31)
        hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
        mm   = two digits of minute (00 through 59)
        ss   = two digits of second (00 through 59)
        s    = one or more digits representing a decimal fraction of a second
        TZD  = time zone designator (Z or +hh:mm or -hh:mm)
Run Code Online (Sandbox Code Playgroud)

如何将字符串转换为具有特定格式的DateTime?

我写了下面的代码:

 private const string Format = "YYYY-MM-DDThh:mm:ssZ";

        public DateTime? Parse(string modifiedSince)
        {
            // how to know whether it's a valid DateTime in UTC format?
        }
Run Code Online (Sandbox Code Playgroud)

但它总是返回null,这意味着它无法解析为DateTime.

它应该成功验证以下UTC值,但它不会:

2013-05-10
2013-05-10T05:04:10
2013-05-10T05:04:10.40
013-05-10T05:04:10.4Z
Run Code Online (Sandbox Code Playgroud)

(Z通常是可选的)

如何使用DateTime.Parse或.Parsexact以便它成功返回上述格式的日期?

所有其他日期格式应该失败,例如20130510

我可以写一个正则表达式吗?

Mat*_*int 9

你遗漏了一些重要的东西. UTC不是格式.

UTC指的是"协调世界时"(是的,缩写是故意不按顺序).这是本初子午线的固定时钟,相当于GMT用于所有实际目的.它不会因"夏令时"或"夏令时"而改变,而是在谈论其他时区的偏移时我们将零置于零.

您描述的格式称为ISO8601.从技术上讲,ISO8601标准定义了几种格式,但最常用的格式也在RFC3339中定义,并且仅涵盖您列出的最后两种格式.换句话说,ISO8601允许在不同精度下多次表示时间,但RFC3339要求值高达第二.

现在说到.Net,你错过了另外几个重要的概念.具体来说,你需要注意DateTime.KindDateTimeOffset.

当你有一个字符串值包含一个Z+00:00在结尾时,你知道它代表UTC的时间,并且可以存储在DateTime具有的时间DateTime.Kind == DateTimeKind.Utc.

如果您有其他偏移量,例如+01:00-04:00,那么您应该将它们存储在DateTimeOffset对象中.如果您尝试将其存储在a中DateTime,则必须选择是否要忽略偏移量,还是应用它并将时间存储为UTC.

如果你最后没有任何东西,那么你就会有歧义.你可以将它存放在一个DateTime地方,Datetime.Kind == DateTimeKind.Unspecified但你必须非常小心你用它做什么.它没有任何关于该值来自哪个时区或偏移的信息 - 因此任何数学运算都可能不正确.例如,你永远不应该通过DateTime用未指定(或局部)种类减去两个valule来获得持续时间.有关其他详细信息,请参阅此博客文章.

最后一点,要明白.Net没有内置类来代表没有时间的日期.为此,我们通常DateTime在午夜时使用- 但您无法将其与实际给出午夜时间的值区分开来.在其他更糟糕,解析后2013-05-102013-05-10T00:00:00-它们是等价的.

这里有一些代码可以帮助您入门.

public DateTime? Parse(string s)
{
    // you may want to add a few more formats here
    var formats = new[] { "yyyy-MM-dd",
                          "yyyy-MM-ddThh:mm:ss",
                          "yyyy-MM-ddThh:mm:ssZ" };

    DateTime dt;
    if (DateTime.TryParseExact(s, formats,
                               CultureInfo.InvariantCulture, // ISO is invariant
                               DateTimeStyles.RoundtripKind, // this is important
                               out dt))
        return dt;

    return null;
}
Run Code Online (Sandbox Code Playgroud)

您还应该研究一下DateTimeOffset.TryParseExact您是否打算沿着这条路走下去.