将用户选择的日期保存为utc并使用utc字段

时间:2016-04-14 06:29:47

标签: c# timezone

我有点困惑什么是正确的方法。

我的应用程序将是一个全球应用程序,意味着具有不同时区的地方(事件所有者)将与它进行交互,我希望保持简单。

我的应用允许地点(事件所有者)在日历上创建事件(通过显然选择日期时间),然后保存到数据库。 (StartDateTime,EndDateTime)

然后,用户(活动参加者)将查看他们附近发生的事件。

到目前为止我所做的是在我的表中创建两个名为StartDateTimeUTC,EndDateTimeUTC的字段,我为每个用户设置了默认的时区设置。

创建新事件时,我会读取他们的时区,将他们选择的日期时间转换为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并保存到数据库。

现在我想查询db以了解今天发生的所有事件,但我需要获取当前用户的LOCAL TIME(基于他们的时区)

 var currentTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tz); //tz being read from db for particular user

然后我可以使用currentTime查找和查询我的数据库,查找今天发生的所有事件。

仅限应用 Place使用后端为其用户创建活动(位于世界上的任何地方),在移动设备上使用应用的用户将查看他们周围不同地方发生的事件(相同时区)

问题 这是处理时区的正确方法,而不必担心夏令时吗?或者我是否需要为根据当地时间向用户显示事件的应用做更多事情,并保持所有内容同步。

或者我应该将所有内容存储为无UTC,并确定用户从浏览器获取的当前日期时间(事件所有者)以查询db,以及编辑/添加事件。并从移动设备确定用户(与会者)的时间。

如果我使用UTC,我会跟踪地点和与会者的时区,并确保所有比较都通过UTC完成。

如果我只输入NONE utc,我不必担心任何转换,除了我需要从浏览器/移动设备读取用户CURRENT DATETIME这一事实。

我错过了什么吗?

1 个答案:

答案 0 :(得分:-1)

当我使用Azure表存储(NOSQL)时,我遇到了同样的障碍,因为ATS始终将所有日期时间字段存储为UTC。

在数据库表上,我有3个字段:

TerminalUtcTime DATETIME TerminalTimezone CHAR(6) TerminalLocalTime 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时间的数据库上的方法,但如果您使用的是允许保存非UTC时间的MySql,MSSQL等,那么这也可能对您有用并节省所有麻烦。