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

时间:2012-04-24 18:00:59

标签: c# .net sql-server

我有一位朋友,他很难找出如何向多个时区的用户显示日期时间,但没有根据时区调整日期。例如,假设他在 Arizona California Nevada 中都有一个服务器,每个服务器都有相应的州时区。如果用户将记录保存为上午9:00 亚利桑那州时间,他希望它在 California Nevada上显示为上午9:00 服务器,当它们显示给用户时。数据库是SQL Server,2008我相信。

他怎么能这样做?我将假设它与UTC DateTime值有关?无论如何,我很欣赏一个关于如何实现这个目标的“完整”例子,因为我们似乎无法达成协议,我可以说他会感到沮丧......

提前致谢!

2 个答案:

答案 0 :(得分:3)

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

我不知道的认为的SQL Server将实际存储或检索数据时执行任何时区转换,但它可能是值得你的朋友明确地做出那种“未指定”使用DateTime.SpecifyKind后检索它。这可以在以后拯救他。

可以在任何地方使用UTC - 但听起来它不是真的一个UTC日期/时间......这是一个“当地时间无论你在哪里”这完全是不同。

当然,如果不提我自己的Noda Time项目,那将是我的疏忽 - 正如你的朋友想要的是LocalDateTime - 拥有一套合理的日期/时间类型它很多更容易在代码中保持这一切。我建议您的朋友在数据库代码本身以外的任何地方使用Noda Time - 您可以使用LocalDateTimeDateTime转换为ToDateTimeUnspecified,并使用FromDateTime进行另一种转换。

您和您的朋友可能希望阅读core conceptstype choices页面以获取更多值得思考的东西 - 无论您是否使用Noda Time,它都会让您想到日期的类型/时间可以更仔细。如果你仍然不相信,那么你可以阅读我的rant against DateTime。)

答案 1 :(得分:0)

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

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