写代码真的头疼,还是sqlite的问题

sqlite,查询指定日期,就很奇怪
date('时间戳', 'unixepoch')='2022-07-29'
有一些正常,有一些不正常
昨天0点后插入了一些数据,但是指定日期查询数据没有结果
然后我注意到https://www.runoob.com/sqlite/sqlite-date-time.html

下面是计算给定 UNIX 时间戳 1092941466 相对本地时区的日期和时间
sqlite> SELECT datetime(1092941466, 'unixepoch', 'localtime');
2004-08-19 11:51:06

多加一个localtime参数,正常
这个数据库时区是个什么情况,不加localtime的话,0点不算第二天还是咋地,但是不算的话,查询大多数情况下又是比较正常的

回复列表(13)
  • @Ta / 07-29 14:31 / /

    @echo醉老仙,你不知道时区吗,北京时间8点是协调世界时0点。所以一天有16小时结果正确,8小时结果不正确。在北京时间0点到8点,协调世界时还没有到第二天。

    时间戳转日期必须指定时区,否则结果很可能不正确,因为unix时间戳自身的时区是协调世界时。

  • @Ta / 07-29 14:35 / /

    @老虎会游泳,我知道是这样,但是数据库还要按时区查我是第一次遇到,搞的头大呀,数据都要重新处理,我不明白的是date转换为日期,只比较日期,又不管它是几点的,这样也不给我正确结果,闹心

  • @Ta / 07-29 14:51 / /

    @echo醉老仙,如果原始数据就是日期(直接就是年月日),那是没有关系。但是原始数据是精确到秒的时间(unix时间戳的本质),那时区自然有关系。

  • @Ta / 07-29 15:01 / /

    @老虎会游泳,原来如此,没有老师教,天天走弯路

  • @Ta / 07-29 18:11 / /

    @echo醉老仙@老虎会游泳SQLite笨笨的,就直接转换时间而已,不考虑啥时区:

    select datetime(0, 'unixepoch'), unixepoch('1970-01-01 00:00:00');
    
    datetime(0, 'unixepoch') unixepoch('1970-01-01 00:00:00')
    1970-01-01 00:00:00 0

    至于 localtimeutc修饰符干啥用的:

    The "localtime" modifier (14) assumes the time value to its left is in Universal Coordinated Time (UTC) and adjusts that time value so that it is in localtime. If "localtime" follows a time that is not UTC, then the behavior is undefined. The "utc" modifier is the opposite of "localtime". "utc" assumes that the time value to its left is in the local timezone and adjusts that time value to be in UTC. If the time to the left is not in localtime, then the result of "utc" is undefined.

    大意:localtime假设它左边的时间值是UTC(世界协调时),然后转换成本地时间。utc则相反操作。

  • @Ta / 07-29 21:54 / /
    基佬牌手机每天艳遇不断,激情不断。基佬至尊纪念版
  • @Ta / 07-30 03:40 / /

    @无名啊,“本地时间”这个词本身就隐含着系统所在的时区。如果将系统时区设为UTC,或者你本身就在0时区并且没有夏令时,则localtime操作符和utc将没有差别。我估计SQLite只是懒得处理时区名称,所以选择从系统获取时区偏移数据。这样其实有隐患,如果新购的服务器时区和以前不同,程序运行结果也将发生改变。

  • @Ta / 07-30 09:44 / /

    数据库字段默认值:

    时间戳:(strftime('%s','now')) ->1659144921 ->2022-07-30 09:35:21

    时间:(datetime('now','localtime')) -> 2022-07-30 09:35:21

    日期比较(查询时间戳):

    date(column, 'unixepoch', 'localtime')='2022-07-30'

    日期比较(查询时间)
    date(column)='2022-07-30'
    时间比较同上
    datetime
    time

  • @Ta / 07-30 12:01 / /

    @老虎会游泳,嗯,不用localtimeutc修饰符的话,不会有时区转换

    假如数据库中存的是时间戳(UTC),下面情况会出问题:

    1. 用户不以 UTC 角度去查询

      date('时间戳', 'unixepoch') = '2022-07-29'  -- 如 @echo醉老仙 的 SQL
      
    2. 用户意识到了时区问题,加了个localtime修饰符。但若服务器时区和用户设想的不一样(如 日本东京GMT+9:00,也会出问题。只能手动加个偏移了:

      select datetime(10, 'unixepoch', '+8 hours');  -- 1970-01-01 08:00:10
      date('时间戳', 'unixepoch', '+8 hours') = '2022-07-29'  -- @echo醉老仙 的 SQL
      

    @老虎会游泳,你是想说这个问题,是嘛

  • @Ta / 07-30 15:28 / /
    我一般 使用时间戳,
  • @Ta / 07-30 15:47 / /

    @无名啊,嗯,是的。

  • @Ta / 07-30 22:24 / /
    我碰过一个项目,时间存yyyy-mm-dd,其他字段习惯性varchar!可能是项目赶时间吧!
  • @Ta / 07-30 22:32 / /

    @TabKey9,还不如直接text或者varchar(255)
    一加8Pro

添加新回复
回复需要登录