.net 如何将字符串+偏移量值转换为DateTimeOffset,而无需先加后减偏移量?

dxxyhpgq  于 2023-11-20  发布在  .NET
关注(0)|答案(1)|浏览(137)

我们的应用程序与一个API交互,该API返回格式为yyyyMMdd HH:mm的本地日期时间字符串,其中第二个数字字段指示UTC偏移量(以小时为单位)。
我们用下面的代码成功地处理了这个问题。

  1. DateTimeOffset ParseWeirdDateTime(string dateTimeString, double utcOffset)
  2. {
  3. DateTimeOffset dateTimeOffset = DateTimeOffset.ParseExact(
  4. dateTimeString,
  5. "yyyyMMdd HH:mm",
  6. CultureInfo.InvariantCulture,
  7. DateTimeStyles.AssumeUniversal
  8. );
  9. return dateTimeOffset.AddHours(-utcOffset).ToOffset(TimeSpan.FromHours(utcOffset));
  10. }
  11. string localDateTimeString = "20231108 14:30";
  12. double utcOffset = -4;
  13. DateTimeOffset dateTimeParsed = ParseWeirdDateTime(localDateTimeString, utcOffset);
  14. // comes out to 11/8/2023 2:30:00 PM -04:00

字符串
我的问题是,有没有更好的方法来处理这个问题?虽然这很有效,但解析为UTC DateTimeOffset感觉很笨拙,只是应用偏移量的倒数,最后转换为偏移量。

x8goxv8g

x8goxv8g1#

  • 你说你的yyyyMMdd HH:mm输入字符串代表一个“本地”(或者更确切地说:非UTC)时刻,但是.
  • 即使输入字符串并不表示Date+Time+Offset元组,您也在使用DateTimeOffset.ParseExact:字符串只表示Date+Time+Undefined-Offset元组。
  • 因此使用DateTime.ParseExact,并确保它有DateTimeKind.Unspecified(因为此时没有指定偏移数据)。
  • (顺便说一句,永远不要使用DateTimeKind.Local:它专门指 * 本地计算机的时间 *,这在商业应用程序中几乎总是无用的,因为它不像真实的UTC那样是不变的:考虑本地时区,政治时区变化,夏令时,机器错误配置等)。
  • 此外,您错误地使用了DateTimeStyles.AssumeUniversal,这在这里不适用,因为您传入的字符串并不表示UTC值。正如the documentation所述“* 如果解析的字符串中没有指定时区,则假定该字符串表示UTC *”。

我会这样做:

  • 由于dateTimeString值仅表示日期+时间值 * 而没有偏移量 *,因此我使用DateTime.ParseExact而不是DateTimeOffset.ParseExact
  • 这里使用DateTimeStyles.None作为AssumeUniversal是不正确的。
  • 然后我通过ctor将DateTime的值 * 调整为 * a DateTimeOffset
  1. /// <summary><see href="https://stackoverflow.com/a/77449580/159145" /></summary>
  2. static DateTimeOffset ParseWeirdDateTime( String dateTimeString, Double utcOffsetInHours /* Always specify units in names when using dimensionless types */ )
  3. {
  4. DateTime instantInTimeWithUndefinedOffset = DateTime.ParseExact(
  5. s : dateTimeString,
  6. format : "yyyyMMdd HH:mm",
  7. provider: CultureInfo.InvariantCulture,
  8. style : DateTimeStyles.None
  9. );
  10. Debug.Assert( instantInTimeWithUndefinedOffset.Kind == DateTimeKind.Unspecified );
  11. return new DateTimeOffset( instantInTimeWithUndefinedOffset, offset: TimeSpan.FromHours( utcOffsetInHours ) );
  12. }

字符串

展开查看全部

相关问题