c#将字符串(没有时区)解析为DateTime,将DST考虑在内

时间:2013-02-06 18:20:36

标签: c# parsing datetime timezone dst

我读过很多SO文章,但我似乎无法找到问题的好答案。发布的建议包括将日期转换为字符串多次以及从字符串转换为一次的函数,在结尾处连接位并且它们似乎只是......凌乱

所以问题是:

我们在世界各地都有服务器。所有服务器都在其自己的本地时间运行,并使用服务器本地的时间条目保留日志。有些服务器在DST观察区域,有些则不是

假设我从日志中获取这些字符串: 2013-01-01 12:34:56,2013-07-01 12:34:56 我知道这台服务器在纽约,所以当DST运行时它是UTC-5或UTC-4

我在香港服务器的日志中使用相同的字符串,其中DST不适用且时区为+8

我所追求的是一段代码,我可以告诉它:

  • 这是一个代表时间的字符串
  • 这是字符串来自的时区
  • 如果相关,则应适用夏令时

代码会将字符串解析为DateTimeOffset,如果解析的时间与DST相关,则根据DST调整偏移量

例如: NY服务器日志说“ 2013-01-01 ...”DST 在JANUARY中应用此日期,因此解析的日期应为: 纽约时间12:34:56,UTC时间17:34:56(因为它是-5,没有夏令时)

NY服务器日志说“ 2013-07-01 ...”DST DOES 在6月份应用于此日期,因此解析的日期应为: 纽约时间12:34:56,UTC时间16:34:56(因为它是-4,用DST)

HK服务器,两个日期时间解析为UTC时间04:34:56

谢谢你们

2 个答案:

答案 0 :(得分:6)

首先,我强烈建议您将系统更改为在任何地方登录UTC。它会让你的生活变得更加简单。

如果你真的坚持你所拥有的,你应该使用DateTime.TryParseExactDateTimeStyles只有0(默认值)。这将为您提供DateTimeKind Unspecified的值,这是您想要的。 (它不是UTC,并且它不是进行解析的机器的本地。)

然后,您可以使用TimeZoneInfo.GetUtcOffset(使用该日志的正确时区)计算偏移量,并从两者中创建DateTimeOffset

作为一个完全偏向的,您也可以更改为使用我维护的Noda Time项目,这将使您的代码更容易理解:)

答案 1 :(得分:5)

要获取记录在不同日志文件中的时间的UTC时间,您需要知道本地时区的名称。然后,您可以使用DateTimeOffset-struct TimeZoneInfo-class来计算UTC时间:

public DateTime ParseAsUtc(string logDate, string timezoneName)
{
    var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timezoneName);
    var localDate = DateTime.Parse(logDate);
    var offset = new DateTimeOffset(localDate, timeZone.GetUtcOffset(localDate));
    return offset.ToUniversalTime().DateTime;
}

ParseAsUtc("2013-01-01 12:34:56", "Eastern Standard Time"); //01.01.2013 17:34:56
ParseAsUtc("2013-07-01 12:34:56", "Eastern Standard Time"); //01.07.2013 16:34:56
ParseAsUtc("2013-01-01 12:34:56", "China Standard Time");   //01.01.2013 04:34:56
ParseAsUtc("2013-01-01 12:34:56", "China Standard Time");   //01.07.2013 04:34:56