我们正在使用Microsoft的Azure移动服务开发IOS应用程序。 Web GUI将日期时间创建为DateTimeOffset字段,这很好。但是当我们将移动设备将日期时间放入数据库时,然后通过实体框架从数据库中读取它们,我们将它们调整为UCT。 (当我们在SSMS中查看记录时,我们会看到同样的事情。)
我一直对SQL的标准日期时间类型缺乏时区支持感到沮丧,我认为DateTimeOffset会更好。但如果我想要我在UTC的时间,我会把它们存储在UTC中。如果用户在CST上午3:00输入时间,我想知道他进入了CST。将它转换为UTC并丢弃偏移量对我来说没有多大意义,因为它假设CST凌晨3点和PDT凌晨3点是相同的。
我是否可以使用某种数据库配置来保持Azure数据库不以UTC格式存储日期?
答案 0 :(得分:2)
问题是,在Azure移动服务中的某个时刻,该属性将转换为JavaScript Date
对象,该对象无法保留偏移量。
有几篇博客文章描述了这个问题,以及可能的解决方法:
基本上,他们都采用相同的方法将偏移分割成单独的字段。然而,仔细观察这些,他们都犯了一个重要的错误:
dto.DateTime.ToUniversalTime()
实际应该是:
dto.UtcDateTime
DateTime
的{{1}}始终为DateTimeOffset
,因此DateTimeKind.Unspecified
会认为来源是本地,而非使用DTO的抵消。
我在这些帖子的代码中看到了一些其他类似的错误,所以要小心彻底测试。然而,一般的方法是合理的。
答案 1 :(得分:0)
我们正在使用Node.js后端,并注意到同样的事情,我们的SQL Server数据库中的DATETIMEOFFSET
读取是以UTC返回的,无论偏移量如何。另一种方法是在查询级别转换DATETIMEOFFSET
,以便将其作为带有时区信息的字符串输出。以下内容将DATETIMEOFFSET(0)
字段转换为ISO8601格式;但是,其他可能的样式可以用作记录here:
SELECT CONVERT(VARCHAR(33), [StartDate], 126) AS [StartDate] FROM [Products];
新输出现在是:"2016-05-26T00:00:00-06:00"
而不是"2016-05-26T06:00:00+00:00"
当然,这意味着客户端必须将字符串序列化为各自的格式。在iOS中,ISO8601
库可用于将输出读取为NSDateComponents
或NSDate
。
此方法的一个好处是,任何数据库级别的检查或触发器都可以使用DATETIMEOFFSET
进行日期比较,而不是尝试考虑具有基本DATETIME
的单独偏移列。