我有点困惑什么是正确的方法。
我的应用程序将是一个全球性的应用程序,这意味着不同时区的地方(活动所有者)将与它交互,我想让事情变得简单。
我的应用程序允许场所(事件所有者)在日历上创建事件(显然是通过选择日期时间),然后保存到数据库。(开始日期时间,结束日期时间)
然后,用户(活动参与者)将查看他们附近发生的事件。
到目前为止,我所做的是在我的表中创建两个名为StartDateTimeUTC和EndDateTimeUTC的字段,我为每个用户都允许他们设置一个默认时区ID。
创建新事件时,我读取他们的时区,将他们选择的日期时间转换为UTC
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); //gotten from db
DateTime startDateTimeUserSelected = new DateTime(2016, 4, 14, 2, 15, 0); //user picked from a datetimepicker
DateTime endDateTimeUserSelected = new DateTime(2016, 4, 14, 4, 15, 0); //user picked from a datetimepicker
var starDateTimeUTC = TimeZoneInfo.ConvertTimeToUtc(startDateTimeUserSelected, tz);
var endDateTimeUTC = TimeZoneInfo.ConvertTimeToUtc(endDateTimeUserSelected, tz);
然后我把这些保存到我的数据库字段中,现在我把用户选择的日期保存为utc并保存到数据库中。
现在我想查询数据库中今天发生的所有事件,但我需要获得当前用户的本地时间(基于他们的时区)
var currentTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tz); //tz being read from db for particular user
然后我可以使用currentTime来查找和查询我的数据库中今天发生的所有事件。
仅限于应用程序Place使用后端为用户创建事件(地点可以在世界任何地方),用户在手机上使用应用程序将查看周围不同地方(同一时区)发生的事件
问题这是处理时区而不必担心夏令时的正确方法吗?还是我必须为一个应用程序做更多的工作,该应用程序根据用户的本地时间向用户显示事件,并保持一切同步。
或者我应该将所有内容都存储为none UTC,并从浏览器中确定用户的当前日期时间,以便查询数据库(事件所有者),并编辑/添加事件。并通过移动设备确定用户(与会者)的时间。
如果我使用UTC,我会跟踪地点和与会者的时区,并确保所有比较都是通过UTC进行的。
如果我只是将所有内容都输入为NONE utc,那么除了需要从浏览器/移动设备读取用户CURRENT DATETIME之外,我不必担心任何转换。
我错过什么了吗?
当我使用Azure表存储(NOSQL)时,我遇到了同样的障碍,因为ATS总是将所有日期-时间字段存储为UTC。
在数据库表上,我有3个字段:
TerminalUtcTime DATETIME终点站时区CHAR(6)终端本地时间CHAR(12)
目标是永远不要使用UTC和时区来计算终端的本地时间。因为日光的影响节省时间(夏时制)等是而不是反映在时区上以及UTC时间。
根据我的经验,我们不得不将终端的本地时间原样转发给一些非常严格的银行网络服务。我们必须发送尽可能准确的数据。
在客户端:
DateTime terminalUtcTime = DateTime.Now.ToUniversalTime();
string terminalTimeZone = // Get from TimeZoneInfo.Local and format to ±hh:mm like +08:45 or -10:00 (format varies on how you may want it to be)
// Getting the timezone can be tricky because the hh and mm separator can be changed in the control panel so I had to use substrings instead
DateTime terminalLocalTime = DateTime.Now.ToLocalTime();
在服务器上:
您只需要将terminalUtcTime保存为terminalUtcTime,terminalTimezone作为terminalTimezone,terminalLocalTime作为字符串。
terminalLocalTime.ToString("yyyyMMddHHmmssfff"); // Saves up to the milliseconds
现在,如果需要,您可以检索终端本地时间的DateTime实例。无需计算等。我使用DateTime.ParseExact(var,"yyyyMMddHHmmssfff");
是的,你必须在表上添加一个新字段,但这可以省去你所有的烦恼。这是一种只允许UTC时间的数据库方法,但如果您使用MySql、MSSQL等允许保存非UTC时间,那么这可能也适用于您,并省去所有麻烦。