即使已经设置了应用程序的默认时区,iOS日期的SQLite也可以使用系统时区

时间:2016-06-24 18:54:40

标签: ios swift sqlite fmdb nstimezone

我正在开发一个应用,用户可以在该应用中登录并选择可能位于不同时区的网站。由于应用程序显示的数据与该网站相关,因此我决定通过NSTimeZone.setDefaultTimeZone将应用的默认时区设置为网站时区。这很好用,除非我通过FMDB从我们的sqlite数据库中选择数据(我不认为FMDB与它有任何关系),并使用strftime与本地时间'。虽然我们的数据使用时期按UTC分钟存储,但我们通常需要在当地时区按天,工作日或月份显示汇总。例如,按工作日获得平均值:

select strftime('%w',datetime(epoch,'localtime')),avg(value) 
    from values 
    where siteId = 'x'  
    group by 1 
    order by 2 desc

'当地时间'它使用的是系统本地时间,而不是应用程序的默认时区,其中所有NSDate调用都遵循默认时区。除了localtime和UTC之外,strftime没有任何其他时区选项,并且当前的解决方案非常缓慢,需要多次SQL往返,如上所述,这应该可以在1个查询中轻松处理。

有谁能告诉我iOS上的sqlite如何确定' localtime'?有没有办法强制它使用不同的ieTimeTimeZone?

1 个答案:

答案 0 :(得分:0)

如您所见,SQLite不使用NSDate或应用程序的本地时区。 datetime函数使用修饰符进行转换。假设您有一个存储为GMT的数据库(我认为您的应用就是这种情况):

sqlite> create table mytable (id int, time datetime);
sqlite> insert into mytable values (1, CURRENT_TIMESTAMP);
sqlite> select time from mytable;
2016-06-24 19:05:36  <-  THIS IS GMT
sqlite> select datetime(time, 'localtime') from mytable;
2016-06-24 15:05:36  <- THIS IS LOCAL TIME

在这个例子中(和你的)&#39; localtime&#39;是修饰符。来自sqlite docs:

  

<强>调节剂

     

时间字符串后面可以跟零个或多个改变的修饰符   日期和/或时间。每个修饰符都是应用于的变换   左边的时间值。修改器从左到右应用;   订单很重要。可用的修饰符如下。

     
      
  1. NNN天
  2.   
  3. NNN小时
  4.   
  5. NNN分钟
  6.   
  7. NNN.NNNN秒
  8.   
  9. NNN个月
  10.   
  11. NNN年
  12.   
  13. 月初
  14.   
  15. 年初
  16.   
  17. 一天的开始
  18.   
  19. 工作日N
  20.   
  21. unixepoch
  22.   
  23. 本地时间
  24.   
  25. UTC
  26.   

因此您无法直接转换为本地值。但是,因为您可以使用这些修改器,您的应用可以从NSDate获取您的本地GMT偏移量:

if let myZone = NSTimeZone(abbreviation: "EST")
{
    NSTimeZone.setDefaultTimeZone(myZone)
    var offset = (myZone.secondsFromGMT)/3600 as Int
    var offsetModifer = "\(offset) hours"
}

然后你可以这样执行你的sqlite查询(使用offsetModifer构建查询,在这里的示例中转换为-4 hours

sqlite> select datetime(time, '-4 hours') from mytable;
2016-06-24 15:05:36