将Apple收据给出的日期转换为.net DateTime对象

本文关键字:转换 net DateTime 对象 日期 Apple | 更新日期: 2023-09-27 18:02:10

虽然这可能是一些简单的东西-我找不到任何地方,给出任何(正确的)解决方案…

Apple收据在RFC 3339中的返回日期它看起来像这样:

2016-08-10 19:47:16 America/los - angeles

2016-08-11 02:42:16 Etc/GMT

我找到的任何解决方案都不能正确处理时区…例如:DateTime对象似乎根本没有此格式的字符串转换器。

我找到了另一个解决方案:

string tTranDatStr = "2016-08-11 02:42:16 Etc/GMT";
trans_date = XmlConvert.ToDateTime(tTranDatStr, XmlDateTimeSerializationMode.Local);

但是会抛出:

字符串'2016-08-11 02:42:16 Etc/GMT'不是有效的AllXsd值。

是否有任何优雅的解决方案,也是正确的(将时间转换为当前地区时区…)?

谢谢! !

将Apple收据给出的日期转换为.net DateTime对象

。. NET对这里使用的zoneinfo/Olson/tz/IANA时区(无论你想叫它们什么…)没有内置支持。幸运的是,我的Noda Time项目做到了。

下面是一些使用Noda Time 1.3.2的代码,它成功地解析了你给出的两个样本值。您所展示的数据的自然类型是ZonedDateTime,它是已知时区中的日期和时间。接下来,您可以将其转换为OffsetDateTime,这有点像。net的DateTimeOffset(您可以将其转换为)。

我个人建议尝试在你的代码中使用Noda Time类型——这个项目的目的是使日期/时间代码不那么繁琐和容易出错。如果您确实需要转换为BCL类型,您当然可以这样做。

using System;
using NodaTime;
using NodaTime.Text;
class Program
{
    private static readonly ZonedDateTimePattern ApplePattern =
        ZonedDateTimePattern.CreateWithInvariantCulture(
            "yyyy-MM-dd HH:mm:ss z", DateTimeZoneProviders.Tzdb);
    static void Main(string[] args)
    {
        ParseApple("2016-08-10 19:47:16 America/Los_Angeles");
        ParseApple("2016-08-11 02:42:16 Etc/GMT");
    }
    static void ParseApple(string text)
    {
        Console.WriteLine($"Parsing {text}");
        ParseResult<ZonedDateTime> result = ApplePattern.Parse(text);
        if (!result.Success)
        {
            Console.WriteLine($"Parse failed! {result.Exception.Message}");
            return;
        }
        ZonedDateTime zonedValue = result.Value;
        Console.WriteLine($"ZonedDateTime: {zonedValue}");
        // OffsetDateTime is a Noda Time type...
        OffsetDateTime offsetValue = zonedValue.ToOffsetDateTime();
        Console.WriteLine($"OffsetDateTime: {offsetValue}");
        // DateTimeOffset is the BCL type...
        DateTimeOffset dto = offsetValue.ToDateTimeOffset();
        Console.WriteLine($"DateTimeOffset: {dto}");
        Console.WriteLine();
    }
}
输出:

Parsing 2016-08-10 19:47:16 America/Los_Angeles
ZonedDateTime: 2016-08-10T19:47:16 America/Los_Angeles (-07)
OffsetDateTime: 2016-08-10T19:47:16-07
DateTimeOffset: 10/08/2016 19:47:16 -07:00
Parsing 2016-08-11 02:42:16 Etc/GMT
ZonedDateTime: 2016-08-11T02:42:16 Etc/GMT (+00)
OffsetDateTime: 2016-08-11T02:42:16Z
DateTimeOffset: 11/08/2016 02:42:16 +00:00