我有一个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
将在浏览器中为用户显示类似的内容:
TimerId:1
开始时间:04/03/2013 12:00
停止:04/03/2013 12:25
总计(以分钟计):25
现在我认为当用户更改时区时会出现一些问题。 解决这个问题的最佳方法是什么?将日期存储为UTC,然后使用JavaScript进行转换?
感谢您的帮助: - )。
答案 0 :(得分:0)
来自:Determine a User's Timezone
您必须将偏移量从客户端传递到服务器,如下所示:
new Date().getTimezoneOffset()/60;
getTimezoneOffset()将从GMT中减去你的时间并返回 分钟数。因此,如果你住在GMT-8,它将返回480.放 这几个小时,除以60.另外,请注意标志是 与你需要的相反 - 它正在计算GMT与你的偏差 时区,而不是您的时区偏离GMT。要解决这个问题,请简单 乘以-1。
答案 1 :(得分:0)
由于这些是事件时间,因此您应该严格使用UTC,并从服务器获取该值。
当客户端应用程序使用您用于 start 和 stop 输入命令的任何内容调用您时,请使用DateTime.UtcNow()
来获取时间并将其保存在数据库。
你真的不想使用当地时间录制这些时间。否则,如果开始或结束属于不明确的时期(例如DST / SummerTime“后退”转换),您将无法知道事件在转换之前或之后是否落下。
上下文始终与DateTime问题相关,并且在“事件时间”的上下文中 - 您唯一可靠的选项是UTC DateTime或DateTimeOffset。本地日历时间(客户端或服务器)不适合特定事件时间。但它们在其他情况下很有用。
当您实际向用户显示数据时,如果您只是显示开始和结束之间的持续时间,那么您可以根据您记录的UTC时间进行计算。如果要将特定时间显示给用户,那就是将UTC时间转换为用户想要显示的时间区域。如果选择DateTimeOffset,则优点是您不必转换在这个阶段。