首页 文章

Sqlite:CURRENT_TIMESTAMP是GMT,而不是机器的时区

提问于
浏览
106

我有一个带有此列定义的sqlite(v3)表:

"timestamp" DATETIME DEFAULT CURRENT_TIMESTAMP

此数据库所在的服务器位于CST时区 . 当我在不包含timestamp列的情况下插入到我的表中时,sqlite会自动使用GMT中的当前时间戳填充该字段,而不是CST .

有没有办法修改我的insert语句以强制存储的时间戳在CST中?另一方面,最好将它存储在GMT中(例如,如果数据库被移动到不同的时区),那么我是否可以修改我的选择SQL以将存储的时间戳转换为CST从表中提取它?

11 回答

  • 3

    我在sqlite文档(https://www.sqlite.org/lang_datefunc.html)上找到了这个文本:

    计算给定unix时间戳1092941466的日期和时间,并补偿您当地的时区 .

    SELECT datetime(1092941466, 'unixepoch', 'localtime');
    

    这看起来不符合我的需要,所以我试着改变一下“datetime”函数,并结束了这个:

    select datetime(timestamp, 'localtime')
    

    这似乎有用 - 是转换为您的时区的正确方法,还是有更好的方法来做到这一点?

  • 56

    只需使用本地时间作为默认值:

    CREATE TABLE whatever(
         ....
         timestamp DATE DEFAULT (datetime('now','localtime')),
         ...
    );
    
  • 3

    作为一项规则,您应该在GMT中将时间戳保留在数据库中,并且只能在输入/输出上将它们转换为本地时间/从本地时间转换它们,此时您可以将它们转换为用户(而不是服务器)的本地时间戳 .

    如果你能做到以下几点会很好:

    SELECT DATETIME(col, 'PDT')
    

    ...在Pacific Daylight Time输出用户的时间戳 . 不幸的是,这不起作用 . 但是,根据this SQLite tutorial(向下滚动到"Other Date and Time Commands"),您可以询问时间,然后同时应用偏移量(以小时为单位) . 所以,如果你确实知道用户's timezone offset, you'好 .

    不涉及夏令时规则,但......

  • 7

    在(很少见的)需要本地数据时间的情况下(例如,我将当地时间存储在我的一个数据库中,因为我关心的是当天的时间,我不记得我在哪里在时区方面......),您可以将列定义为

    "timestamp" TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M','now', 'localtime'))
    

    %Y-%m-%dT%H:%M部分当然是可选的;这就是我喜欢存储时间的方式 . [另外,如果我的印象是正确的,sqlite中没有“DATETIME”数据类型,因此TEXT或DATETIME是否用作列声明中的数据类型并不重要 . ]

  • 8

    当使用“ NOT NULL DEFAULT CURRENT_TIMESTAMP ”定义列时,插入的记录将始终使用UTC / GMT时间设置 .

    这是我为避免在INSERT / UPDATE语句中包含时间所做的工作:

    --Create a table having a CURRENT_TIMESTAMP:
    CREATE TABLE FOOBAR (
        RECORD_NO INTEGER NOT NULL,
        TO_STORE INTEGER,
        UPC CHAR(30),
        QTY DECIMAL(15,4),
        EID CHAR(16),
        RECORD_TIME NOT NULL DEFAULT CURRENT_TIMESTAMP)
    
    --Create before update and after insert triggers:
    CREATE TRIGGER UPDATE_FOOBAR BEFORE UPDATE ON FOOBAR
        BEGIN
           UPDATE FOOBAR SET record_time = datetime('now', 'localtime')
           WHERE rowid = new.rowid;
        END
    
    CREATE TRIGGER INSERT_FOOBAR AFTER INSERT ON FOOBAR
        BEGIN
           UPDATE FOOBAR SET record_time = datetime('now', 'localtime')
           WHERE rowid = new.rowid;
        END
    

    测试看它是否有效......

    --INSERT a couple records into the table:
    INSERT INTO foobar (RECORD_NO, TO_STORE, UPC, PRICE, EID)
        VALUES (0, 1, 'xyz1', 31, '777')
    
    INSERT INTO foobar (RECORD_NO, TO_STORE, UPC, PRICE, EID)
        VALUES (1, 1, 'xyz2', 32, '777')
    
    --UPDATE one of the records:
    UPDATE foobar SET price = 29 WHERE upc = 'xyz2'
    
    --Check the results:
    SELECT * FROM foobar
    

    希望有所帮助 .

  • 124
    SELECT datetime('now', 'localtime');
    
  • 1

    您还可以使用strftime()将时间列转换为时间戳:

    SELECT strftime('%s', timestamp) as timestamp FROM ... ;
    

    给你:

    1454521888

    'timestamp'表列甚至可以是文本字段,使用 current_timestamp 作为DEFAULT .

    没有strftime:

    SELECT timestamp FROM ... ;
    

    给你:

    2016-02-03 17:51:28

  • 12

    我认为这可能有所帮助 .

    SELECT datetime(strftime('%s','now'), 'unixepoch', 'localtime');
    
  • 2

    SELECT datetime(CURRENT_TIMESTAMP, 'localtime')

  • 4

    当前时间,在您机器的时区:

    select time(time(), 'localtime');
    

    根据http://www.sqlite.org/lang_datefunc.html

  • 13

    Time ( 'now', 'localtime' ) 和日期 ( 'now', 'localtime' ) 有效 .

相关问题