将 c# 中的所有日期时间字段转换为登录用户时区的最佳方法是什么?
What is the best way to convert all date time fields in c# to the time zone of the logged in user?
我正在 MVC
中开展一个项目,其中一些页面根据插入 database
中的时区显示 datetime
值。现在我的要求是根据管理员或用户登录的时区显示它。实现该目标的最佳方法是什么。
我想在前端更新它,因为我无法在后端更新它。
我有一个 userinfo
table,它有一个 time_zone_id
映射列到另一个 table 即 time_zone
,其中为注册用户定义了时区.
除了转到每个控制器并更改日期时间字段(添加或减去时区)之外,还有其他方法可以实现相同的目的吗?
如果问题没有解决,请告诉我。
没有内置方法可以在 .NET 应用程序中全局应用时区更改。如果它是这样一种机制,那将是危险的,因为应用程序的不同部分可能需要使用时区,而不仅仅是分配给特定用户的时区。
但是,您还有更大的问题需要解决。您在评论中声明您的时区存储为数值 time_in_minutes
。这只会代表时区 offset,而不是实际的 time zone.
偏移量和时区之间存在显着差异。任何仅跟踪偏移量的解决方案都无法正确转换世界各地的时间,这主要是由于夏令时。请参阅 the timezone tag wiki and the graphs in the dst tag wiki 中的 "Time Zone != Offset"。
此外,您暗示数据库中存储的时间是时区 ID 引用的时区的本地时间。这也是一个问题,因为您可能会在回退 DST 转换期间存储不明确的值。
您应该改为执行以下操作:
以 UTC 或 datetimeoffset
数据类型存储您的值。 (如果您不确定要使用哪个,请参阅 DateTime vs DateTimeOffset。)
在您的时区 table,您应该存储一个包含时区标识符的字符串。您可以选择 Windows 个时区或 IANA 时区。
对于 Windows 时区,标识符包含类似 "Eastern Standard Time"
的值,即使它们实际上代表完整的美国东部时区,包括 EST 和 EDT(不要陷入命名差异)。如果您使用这些,那么您将在 .NET 代码中使用 TimeZoneInfo
class 进行转换。
对于 IANA 时区,标识符更合理,例如 "America/New_York"
或 "Asia/Tokyo"
。您可以找到 a list of them here. In .NET, they easiest way to work with these is with the Noda Time 库。如果可以选择,这将是我的建议。
您应该通读 timezone and dst wiki。我还会推荐以下视频:
- The Problem with Time & Timezones - Computerphile 制作的一段简短有趣的视频。
- Daylight Saving Time Explained - CGP Grey 制作的简短而内容丰富的视频
- Date and Time Fundamentals - 综合 Pluralsight 培训课程,由我编写。
我正在 MVC
中开展一个项目,其中一些页面根据插入 database
中的时区显示 datetime
值。现在我的要求是根据管理员或用户登录的时区显示它。实现该目标的最佳方法是什么。
我想在前端更新它,因为我无法在后端更新它。
我有一个 userinfo
table,它有一个 time_zone_id
映射列到另一个 table 即 time_zone
,其中为注册用户定义了时区.
除了转到每个控制器并更改日期时间字段(添加或减去时区)之外,还有其他方法可以实现相同的目的吗?
如果问题没有解决,请告诉我。
没有内置方法可以在 .NET 应用程序中全局应用时区更改。如果它是这样一种机制,那将是危险的,因为应用程序的不同部分可能需要使用时区,而不仅仅是分配给特定用户的时区。
但是,您还有更大的问题需要解决。您在评论中声明您的时区存储为数值 time_in_minutes
。这只会代表时区 offset,而不是实际的 time zone.
偏移量和时区之间存在显着差异。任何仅跟踪偏移量的解决方案都无法正确转换世界各地的时间,这主要是由于夏令时。请参阅 the timezone tag wiki and the graphs in the dst tag wiki 中的 "Time Zone != Offset"。
此外,您暗示数据库中存储的时间是时区 ID 引用的时区的本地时间。这也是一个问题,因为您可能会在回退 DST 转换期间存储不明确的值。
您应该改为执行以下操作:
以 UTC 或
datetimeoffset
数据类型存储您的值。 (如果您不确定要使用哪个,请参阅 DateTime vs DateTimeOffset。)在您的时区 table,您应该存储一个包含时区标识符的字符串。您可以选择 Windows 个时区或 IANA 时区。
对于 Windows 时区,标识符包含类似
"Eastern Standard Time"
的值,即使它们实际上代表完整的美国东部时区,包括 EST 和 EDT(不要陷入命名差异)。如果您使用这些,那么您将在 .NET 代码中使用TimeZoneInfo
class 进行转换。对于 IANA 时区,标识符更合理,例如
"America/New_York"
或"Asia/Tokyo"
。您可以找到 a list of them here. In .NET, they easiest way to work with these is with the Noda Time 库。如果可以选择,这将是我的建议。
您应该通读 timezone and dst wiki。我还会推荐以下视频:
- The Problem with Time & Timezones - Computerphile 制作的一段简短有趣的视频。
- Daylight Saving Time Explained - CGP Grey 制作的简短而内容丰富的视频
- Date and Time Fundamentals - 综合 Pluralsight 培训课程,由我编写。