1

我有一个 C# 时间应用程序,用户可以在其中创建一个计时器并启动它,它会在服务器上执行类似的操作:

(日期存储在 CEST 中(问题是夏季和冬季时间))

// insert into db
var entry = new TimeEntry();
entry.Start = DateTime.Now; (04/03/2013 12:00)

_timeEntries.Add(entry);    // => now it's in the db

如果他停止它,那么它会执行以下操作:

// update the entry
var entry = _timeEntries.Get(1)    // 1 is the id from the created entry before
entry.End = DateTime.Now; (04/03/2013 12:37)

_timeEntrires.Update(entry);    // => now it updates it in the db

将在浏览器中为用户显示类似的内容:

定时器 ID:1

开始时间:2013 年 4 月 3 日 12:00

停止:04/03/2013 12:25

总计(分钟):25

现在我认为当用户更改他的时区时会出现一些问题。解决这个问题的最佳方法是什么?将日期存储为 UTC,然后使用 JavaScript 进行转换?

感谢您的帮助:-)。

4

2 回答 2

0

From :确定用户的时区

您必须将偏移量从客户端传递到服务器,如下所示:

new Date().getTimezoneOffset()/60;

getTimezoneOffset() 将从 GMT 中减去您的时间并返回分钟数。因此,如果您居住在 GMT-8 中,它将返回 480。将其转换为小时,除以 60。另外,请注意符号与您需要的相反——它计算的是 GMT 与您的时区的偏移量,而不是您的时区时区与 GMT 的偏移量。要解决此问题,只需乘以 -1。

于 2013-04-03T11:10:16.323 回答
0

由于这些是事件时间,因此您应该严格使用 UTC,并从服务器获取该值。

当客户端应用程序使用您用于启动停止输入命令的任何内容调用您时,请使用它DateTime.UtcNow()来获取时间并将其保存在数据库中。

您真的根本不想使用本地时间来记录这些时间。否则,如果开始或结束位于不明确的时期内(例如 DST/SummerTime “回退”转换),您将无法知道事件是在转换之前还是之后发生的。

上下文对于 DateTime 问题总是很重要,并且在“事件时间”的上下文中 - 您唯一可靠的选项是 UTC DateTime 或DateTimeOffset。本地日历时间(客户端或服务器)不适用于特定事件时间。不过,它们在其他情况下也很有用。

当您实际向用户显示数据时,如果您只是显示开始和结束之间的持续时间,那么您可以简单地根据您记录的 UTC 时间计算它。如果您想将特定时间显示给用户,那么您可以将 UTC 时间转换为用户想要显示的任何时区。如果您选择 DateTimeOffset,优点是您不必转换在这个阶段。

于 2013-04-04T00:31:23.247 回答