关于c#:正确转换日期时区以进行显示的方法

Correct way to convert datetime timezone for display

我们正在开发一个网站,目前,该网站和数据库的时区是德国时区(欧洲标准时区)。 但该应用程序也正在从美国访问。 应用程序中有一个屏幕,其中包含一个名为ValidFrom的DateTime字段,我们存储的时间是UTC时间。 目前,用户没有选择时间,因此我们使用.NET内置的DateTime.UTCNow将DateTime值存储在数据库中。 但问题是在显示时,我们需要根据用户时区显示它。 因此,经过谷歌搜索几个小时后,我们找到了一个使用时刻的解决方案,另一种方法是使用DateTime.SpecifyKind。 我们尝试使用moment.js,但它再次将日期时间转换为本地时间。 所以我们最终使用DateTime.SpecifyKind,如下所示。

1
2
3
4
5
6
7
[DataMember]
private DateTime _validFrom;
public DateTime ValidFrom
{
    get { return _validFrom; }
    set { _validFrom = DateTime.SpecifyKind(value, DateTimeKind.Utc); }
}

现在,值根据时区显示。 但我怀疑的是,它是处理时区显示的正确方法还是存在任何其他更好的解决方案?


我会使用DateTimeOffset,例如:

1
2
3
var utc = DateTimeOffset.UtcNow;
var tz = TimeZoneInfo.FindSystemTimeZoneById("Your Specific Time Zone Id");
var zonedDateTime = TimeZoneInfo.ConvertTime(utc, tz);

将UTC和用户的时区保存在数据库中,并在您希望向用户显示时将UTC转换为特定时区。 我还建议你看看NodaTime,如果你想做任何严肃的日期和时间。 .Net中的内置DateTime具有误导性。


我为此写了一个扩展方法:

1
2
3
4
5
public static DateTime ConvertFromUTC(this DateTime date, TimeZoneInfo destZone)
{
    var utcZone = TimeZoneInfo.FindSystemTimeZoneById("UTC");
    return TimeZoneInfo.ConvertTime(date, utcZone, destZone);
}

但是,如果您打算使用这样的东西,您需要注意夏令时。 如果转换跨越任一时区中的DST更改,则结果可能会关闭。 因此,如果您需要绝对精确度,这取决于网站,例如:它是博客还是股票交易应用程序?