DateTime.ParseExact到NodaTime ZonedDateTime问题

时间:2017-06-07 00:12:58

标签: c# nodatime

我在将已解析的string转换为正确的NodaTime ZonedDateTime时遇到问题。以下方法采用经纪服务器推送的字符串(据称为UTC),并返回ZonedDateTimeDateTimeZone设置为UTC。域模型只接受ZonedDateTime个对象,因此这发生在系统边界。

例如,作为参数传递的string正好是'2017060623:20:10'然后将返回ZonedDateTime,如2017-06-06T13-:20:10(好奇地是十点)小时差异,我在悉尼的当地时区是+10 UTC)。

public static ZonedDateTime GetZonedDateTimeUtcFromMarketDataString(string dateTime)
{
    var dotNetDateTime = DateTime.ParseExact(
        dateTime,
        "yyyyMMddHH:mm:ss,                
        CultureInfo.InvariantCulture)
        .ToUniversalTime();

    return new ZonedDateTime(Instant.FromDateTimeUtc(dotNetDateTime), DateTimeZone.Utc);
}

所以我将方法更改为下面的方法,但是我确信有更好的方法。我确定我的错误是我以某种方式涉及我当地的时区,而不是将所有内容保留在UTC中。

public static ZonedDateTime GetZonedDateTimeUtcFromMarketDataString(string dateTime)
{
    var parsedDateTime = DateTime.ParseExact(
        dateTime,
        "yyyyMMddHH:mm:ss",
        CultureInfo.InvariantCulture);

    var dotNetDateTime = new DateTime(
        parsedDateTime.Year,
        parsedDateTime.Month,
        parsedDateTime.Day,
        parsedDateTime.Hour,
        parsedDateTime.Minute,
        parsedDateTime.Second,
        DateTimeKind.Utc);

    return new ZonedDateTime(Instant.FromDateTimeUtc(dotNetDateTime), DateTimeZone.Utc);
}

2 个答案:

答案 0 :(得分:1)

DateTime.ParseExact函数可以将DateTimeStyle作为参数。

试试这个

var parsedDateTime = DateTime.ParseExact(
    dateTime,
    "yyyyMMddHH:mm:ss",
    CultureInfo.InvariantCulture, 
    DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);

答案 1 :(得分:1)

我建议不要使用DateTime。你正在使用野田时间 - 所以全力以赴:)

要将文字解析为ZonedDateTime,请使用ZonedDateTimePattern。这是一个例子:

using System;
using NodaTime;
using NodaTime.Text;

class Program
{
    static void Main(string[] args)
    {
        string text = "2017060623:20:10";
        Console.WriteLine(GetZonedDateTimeUtcFromMarketDataString(text));

    }

    static readonly ZonedDateTimePattern ParsePattern =
        ZonedDateTimePattern.CreateWithInvariantCulture(
           "yyyyMMddHH:mm:ss",
           DateTimeZoneProviders.Tzdb); // Won't actually be used...

    static ZonedDateTime GetZonedDateTimeUtcFromMarketDataString(string dateTime)
        => ParsePattern.Parse(dateTime).Value;
}

默认模板值已使用UTC作为时区,因此您不必担心这一点。

或者,您可以使用LocalDateTimePattern,因为您使用的文字没有指定时区 - 解析为LocalDateTime,然后拨打LocalDateTime.InUtc()

所有这些都提出了另一个问题,这就是为什么你要将值解析为ZonedDateTime的原因。如果您总是获得了UTC值,那么您真的需要它是ZonedDateTime而不是Instant吗?你不知道最初观察到的时区,所以感觉更像是我的一个时间点。