将时间戳从任何时区转换为 UTC,并且可以选择不使用 DST

Convert timestamp from any timezone to UTC, and optionally without DST

我们有来自 CSV 文件的时间戳,如下所示:

06-02-2018 15:04:21

我们不控制它们的交付,也不控制时区。

到目前为止我们所知道的是我们到目前为止所看到的是:

标准浪漫时间 标准浪漫时间,但没有 DST 补偿。 协调世界时

据此,我们了解到我们需要一个引擎,它可以采用任何时间戳(以 DateTime.ParseExact 理解的模式编写),属于任何时区,可选择忽略 DST,然后将其转换为 UTC(我们内部使用的格式)。

我希望这能做到:

public DateTime ConvertToUtc(string fromTimestamp, DataReaderConfiguration dataReaderConfiguration)
{
  DateTime readTime = DateTime.ParseExact(fromTimestamp, dataReaderConfiguration.TimestampFormat,
    CultureInfo.InvariantCulture, DateTimeStyles.None);
  DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(readTime,
    TimeZoneInfo.FindSystemTimeZoneById(dataReaderConfiguration.TimeZone));
  return utcTime;
}

但 C# 没有定义没有 DST 的时区(UTC 除外)。

因此我们需要扩展该方法以允许在没有 DST 的情况下进行时区转换。

您可以自己创建此函数,方法是利用 TimeZoneInfo.BaseUtcOffset 属性 和 DateTimeOffset

public static DateTime ConvertTimeToUtc(DateTime dt, TimeZoneInfo tz, bool useDST)
{
    if (useDST)
    {
        // the normal way (converts using the time in effect - standard or daylight)
        return TimeZoneInfo.ConvertTimeToUtc(dt, tz);
    }

    // the way to convert with just the standard time (even when DST is in effect)
    var dto = new DateTimeOffset(dt, tz.BaseUtcOffset);
    return dto.UtcDateTime;
}

然后从您的 DataReaderConfiguration 对象中传递任何 属性 来指示您是否要使用 DST(或在必要时取消它)。

另请注意,这给出了基于当前 组规则的标准时间。如果您要处理时区标准时间发生变化的历史日期,事情就会变得有点复杂。您必须弄清楚当时有哪些调整规则等。您甚至可能会发现 Windows 时区数据不足的极端情况。