DateTime.ParseExact 到 NodaTime ZonedDateTime 问题
DateTime.ParseExact to NodaTime ZonedDateTime issue
我在将解析的 string
转换为正确的 NodaTime ZonedDateTime
时遇到问题。下面的方法接受一个由代理服务器推送的字符串(据称是 UTC),并且 returns 一个 ZonedDateTime
并且 DateTimeZone
被设置为 UTC。域模型将只接受 ZonedDateTime
个对象,所以这是在系统边界发生的。
例如,作为参数传递的 string
恰好是 '2017060623:20:10' 那么 return 就会像 2017-06-06T13-:20 这样的 ZonedDateTime
: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);
}
DateTime.ParseExact
函数可以将DateTimeStyle作为参数。
试试这个
var parsedDateTime = DateTime.ParseExact(
dateTime,
"yyyyMMddHH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
我建议根本不要使用 DateTime
。您正在使用 Noda Time - 所以全力以赴:)
要将文本解析为 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
吗?您不知道最初观察到该值的时区,所以对我来说更像是一个时间点。
我在将解析的 string
转换为正确的 NodaTime ZonedDateTime
时遇到问题。下面的方法接受一个由代理服务器推送的字符串(据称是 UTC),并且 returns 一个 ZonedDateTime
并且 DateTimeZone
被设置为 UTC。域模型将只接受 ZonedDateTime
个对象,所以这是在系统边界发生的。
例如,作为参数传递的 string
恰好是 '2017060623:20:10' 那么 return 就会像 2017-06-06T13-:20 这样的 ZonedDateTime
: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);
}
DateTime.ParseExact
函数可以将DateTimeStyle作为参数。
试试这个
var parsedDateTime = DateTime.ParseExact(
dateTime,
"yyyyMMddHH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
我建议根本不要使用 DateTime
。您正在使用 Noda Time - 所以全力以赴:)
要将文本解析为 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
吗?您不知道最初观察到该值的时区,所以对我来说更像是一个时间点。