提问人:Jacob Stamm 提问时间:11/9/2023 最后编辑:DaiJacob Stamm 更新时间:11/13/2023 访问量:49
如何在不添加然后减去偏移量的情况下将字符串+偏移值转换为 DateTimeOffset?
How do I convert a string+offset value to a DateTimeOffset without adding-then-subtracting the offset?
问:
我们的应用程序与一个 API 交互,该 API 以以下格式返回本地日期时间字符串,该字符串带有一个辅助数字字段,指示以小时为单位的 UTC 偏移量。yyyyMMdd HH:mm
我们通过以下代码成功处理了此问题。
DateTimeOffset ParseWeirdDateTime(string dateTimeString, double utcOffset)
{
DateTimeOffset dateTimeOffset = DateTimeOffset.ParseExact(
dateTimeString,
"yyyyMMdd HH:mm",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal
);
return dateTimeOffset.AddHours(-utcOffset).ToOffset(TimeSpan.FromHours(utcOffset));
}
string localDateTimeString = "20231108 14:30";
double utcOffset = -4;
DateTimeOffset dateTimeParsed = ParseWeirdDateTime(localDateTimeString, utcOffset);
// comes out to 11/8/2023 2:30:00 PM -04:00
我的问题是,有没有更好的方法来解决这个问题?尽管这可行,但解析为 UTC DateTimeOffset 感觉很笨拙,只是应用偏移量的倒数并最终转换为偏移量。
答:
1赞
Dai
11/9/2023
#1
- 你说你的输入字符串代表一个“本地”(或者更确切地说:非UTC)时刻,但是......
yyyyMMdd HH:mm
- 即使输入字符串不表示元组,您仍在使用:字符串仅表示元组。
DateTimeOffset.ParseExact
Date+Time+Offset
Date+Time+Undefined-Offset
- 因此,请改用,并确保它有(因为此时没有指定偏移数据)。
DateTime.ParseExact
DateTimeKind.Unspecified
- (顺便说一句,从不使用:它特指本地计算机的时间,这在业务应用程序中几乎总是无用的,因为它不像真正的UTC那样是不变的:考虑本地时区,政治时区变化,夏令时,机器配置错误等)。
DateTimeKind.Local
- 因此,请改用,并确保它有(因为此时没有指定偏移数据)。
- 此外,您错误地使用了 ,这在这里不适用,因为您传入的字符串不表示 UTC 值。正如文档所述,“如果在解析的字符串中未指定时区,则假定该字符串表示 UTC。
DateTimeStyles.AssumeUniversal
"
- 即使输入字符串不表示元组,您仍在使用:字符串仅表示元组。
我会这样做:
- 由于该值仅表示没有偏移量的日期+时间值,因此我使用而不是 .
dateTimeString
DateTime.ParseExact
DateTimeOffset.ParseExact
- 此处使用方式不正确。
DateTimeStyles.None
AssumeUniversal
- 然后我通过 ctor 将值调整为 a。
DateTime
DateTimeOffset
/// <summary><see href="https://stackoverflow.com/a/77449580/159145" /></summary>
static DateTimeOffset ParseWeirdDateTime( String dateTimeString, Double utcOffsetInHours /* Always specify units in names when using dimensionless types */ )
{
DateTime instantInTimeWithUndefinedOffset = DateTime.ParseExact(
s : dateTimeString,
format : "yyyyMMdd HH:mm",
provider: CultureInfo.InvariantCulture,
style : DateTimeStyles.None
);
Debug.Assert( instantInTimeWithUndefinedOffset.Kind == DateTimeKind.Unspecified );
return new DateTimeOffset( instantInTimeWithUndefinedOffset, offset: TimeSpan.FromHours( utcOffsetInHours ) );
}
评论
0赞
Jacob Stamm
11/14/2023
我喜欢。这与我的方法类似,但意图要明确得多。
评论