存储和显示来自不同时区的多个服务器的日期时间

本文关键字:服务器 时间 日期 时区 显示 存储 | 更新日期: 2023-09-27 18:32:04

我有一个朋友,他很难弄清楚如何向来自多个时区的用户显示日期时间,但没有根据他们的时区调整日期。例如,假设他在亚利桑那州、加利福尼亚州内华达州都有一台服务器,每个服务器都有适当的州时区。如果用户将记录保存为亚利桑那州时间上午 9:00,他希望该记录在向用户显示时在加利福尼亚州内华达州的服务器上显示为上午 9:00。我相信数据库是SQL Server,2008

他怎么能这样做呢?我将假设它与 UTC 日期时间值有关?无论如何,我希望有一个关于他如何实现这一目标的"完整"例子,因为我们似乎无法达成协议,我可以说他很沮丧......

提前感谢!

存储和显示来自不同时区的多个服务器的日期时间

听起来他们真正输入的是当地时间,没有真正参考任何特定的时区。这最接近DateTimeKind.Unspecified的行为(不是本地的,这意味着"在服务器的本地时区",这是另一回事)。

我不相信SQL Server在存储或检索数据时实际上会执行任何时区转换,但是在检索数据后,可能值得您的朋友使用DateTime.SpecifyKind明确地将类型设置为"未指定"。这可以为他以后省去麻烦。

可以在任何地方使用 UTC - 但听起来这不是真正的 UTC 日期/时间......这是一个"无论您身在何处的当地时间",这是完全不同的。

当然,在这一点上不提及我自己的 Noda Time 项目是我的失职 - 因为你的朋友想要的是LocalDateTime - 拥有一组合理的日期/时间类型可以更轻松地在您的代码中保持所有这些直截了当。我建议你的朋友在数据库代码本身以外的任何地方都使用 Noda Time——你可以使用 ToDateTimeUnspecifiedLocalDateTime转换为DateTime,并使用 FromDateTime 以另一种方式进行转换。

您和您的朋友可能希望阅读核心概念和类型选择页面以获得更多思考 - 无论您是否使用Noda Time,它都希望能让您更仔细地思考可用的日期/时间类型。然后,如果你仍然不相信,你可以阅读我对DateTime的咆哮:)

听起来你的朋友可以直接将时间存储在SQL中。例如,如果加利福尼亚州和亚利桑那州的两台服务器在当地时间晚上 9 点运行以下查询,则将插入两个晚上 9 点的值。

SqlCommand cmd = new SqlCommand("INSERT INTO table (Date) VALUES (@value)", conn);
cmd.Parameters.AddWithValue("@value", DateTime.Now.ToString("yyyy-mm-dd hh:mm:ss"));
cmd.ExecuteNonQuery();

如果要插入 UTC 时间,可能需要查看 SQL Server 2008 的等效convert_tz功能。您可以存储 UTC 时间和服务器配置的时区,您将能够执行到服务器时间的转换。

 SELECT convert_tz(table.UtcTime, 'UTC', table.TimeZone) FROM table