UNIX TIMESTAMP GMT stored in sqlite in Integer, convert to local time zone
在我的sqlite表中,我已经在gmt时区的时间戳中存储了一个日期,这样:
1 2 3 4 5
| CREATE TABLE task (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
date INTEGER,
name TEXT
); |
当我查询数据库时,我想用当地时间检索日期,所以:
1
| NSTimeInterval now = [[NSDate date] timeIntervalSince1970]; |
现在的时间戳是我当地的时区,例如,如果有可能,我想这样做:
1
| SELECT id,date,name FROM task WHERE converttolocal(date) = now; |
我想知道如果在sqlite中存在一个函数,例如converttolocal自动转换时间戳...
编辑
我找到了这个:
1
| strftime('%s',date , 'unixepoch', 'localtime') |
但是,例如,如果数据库中的日期gmt是:1375660800,那就是:
1
| GMT: Mon, 05 Aug 2013 00:00:00 GMT |
在函数strftime之后,结果是:1375668000,在我当地时间对应:
1
| (CEST ) Mine time zone : 05 agosto 2013 04:00:00 |
但我希望strftime函数的结果给我这个:1375653600即:
1
| Mine time zone : 05 agosto 2013 00:00:00 CEST |
为什么不给我这个结果?
要从Unix时间戳转换为SQLite的默认日期格式,请使用unixepoch修饰符。
要将时间从UTC转换为本地时间,请使用localtime修饰符。
要从SQLite的默认日期格式转换为Unix时间戳,请使用带%s格式的strftime:
1
| SELECT id ,date ,name FROM task WHERE strftime('%s', date , 'unixepoch', 'localtime') = ? |
使用SQLite的内置方法获取当前时间可能更容易,该时间已经是UTC:
1
| SELECT id,date,name FROM task WHERE datetime('%s', date, 'unixepoch') = datetime('now') |
但是,如果您只有日期,则要忽略时间部分。
在这种情况下,使用date而不是datetime:
1
| SELECT id,date,name FROM task WHERE date('%s', date, 'unixepoch') = date('now') |
-
看看我的问题,我在你回答之前编辑了我的问题......这等于你的答案,但我觉得不行......看看编辑......
-
适合我。请注意,文本日期/时间格式和Unix时间戳都是相对于某个时区的;无论时区如何,数字1375660800始终对应于2013-08-05 00:00:00。
-
如果您将此1375660800放入此strftime('%s',日期,'unixepoch','localtime'),结果会给您带来什么?
-
我的时区是UTC + 2,所以我得到了1375668000.你必须小心,既不要太少也不要太多的时区转换。
-
所以这是错的,我住在意大利,你用德语(我看到你的个人资料)所以我们有相同的时区,如果日期是1375660800并且对应于2013-08-05 00:00:00,我们的2013-08-05 00:00:00是1375653600而不是1375668000
-
如果没有为每个时间值指定时区,则您的评论毫无意义。
-
好吧,我试图更好地解释它,如果在sqlite db date是1375660800对应于:Mon, 05 Aug 2013 00:00:00 GMT我希望该函数给我相应的我的时区(CEST)的开始日那个是1375653600对应05 agosto 2013 00:00:00 CEST,但函数给我和你这个1375668000的值05 agosto 2013 04:00:00 CEST,并且从一天开始就有4小时的差异,我希望我能解释更好。
-
你错了。每个时区的一天开始时间1375660800,与时间00:00:00是每个时区的一天开始时间相同。
-
好的,所以如果我在数据库中有1375660800,我会更好地提出问题,如果我这样做:NSTimeInterval todayTimeInterval = [[[NSDate date] dateAtStartOfDay] timeIntervalSince1970];即1375653600,我想这样做:SELECT id,name,date FROM task WHERE date <= ?其中?是todayTimeInterval,你现在明白我的问题是什么?是为了我想在sqlite查询中转换该值...
-
对于GMT中的Unix时间戳,dateAtStartOfDay无法正常工作。只需计算X - (X % 86400)即可获得当天的正确开始,然后您可以直接与数据库值进行比较。
-
我现在dateAtStartOfDay是我的timezone的startOfdate,因为是我想要的,我不知道如何更好地解释我,我再试一次:如果我想在午夜(一天开始)重新加载所有新任务对于该日期,如果我在GMT使用具有此时间戳1375660800的startOfDate并且对应于此GMT:Mon, 05 Aug 2013 00:00:00 GMT,但在我的时区对应于此:05 agosto 2013 02:00:00 CEST所以我没有刷新新的当天开始时的任务,但是在02:00:00,我希望在我当天的开始时刷新1375653600
-
所以,当你说"当天开始"时,你的意思是"当前时区的一天开始"?在这种情况下,只需将值1375653600直接与数据库中的值进行比较;这两个价值都不需要转换。
-
不,我不能这样做,因为1375653600 != 1375660800,所以我从来没有找到任何东西,我可能找到了一种方法:strftime('%s',1375653600, 'unixepoch', 'localtime')给我1375660800,所以我可以反过来做...
-
但是数据库中的值(格林威治标准时间为1375660800)并不是您所在时区的开始时间,因此不应该匹配。
-
我这样做:SELECT id,name,date FROM task WHERE date = strftime('%s',?,'unixepoch','localtime');哪里?是我的开始,似乎工作
1
| SELECT id,date,name FROM task WHERE datetime('date', 'unixepoch', 'localtime') = datetime('now','unixepoch'); |
这会奏效。 但左侧值永远不会与右侧匹配,您将永远不会检索值,因为您正在捕获时间戳,在您比较时,时间戳值将发生变化。
所以,SELECT id,date,name FROM task WHERE converttolocal(date) = now;永远不会成真。
-
datetime(...) = date(...)永远不会匹配,并且您在错误的时区使用不同的now。
-
不起作用,任何其他解决方案? :(