137

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

"timestamp" DATETIME DEFAULT CURRENT_TIMESTAMP

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

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

4

11 回答 11

162

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

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

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

这看起来不符合我的需要,所以我试着稍微改变一下“datetime”函数,最后得到了这个:

select datetime(timestamp, 'localtime')

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

于 2008-12-19T16:04:28.907 回答
80

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

CREATE TABLE whatever(
     ....
     timestamp DATE DEFAULT (datetime('now','localtime')),
     ...
);
于 2010-05-30T14:42:08.777 回答
22

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

如果您可以执行以下操作,那就太好了:

SELECT DATETIME(col, 'PDT')

...在太平洋夏令时为用户输出时间戳。不幸的是,这不起作用。但是,根据这个 SQLite 教程(向下滚动到“其他日期和时间命令”),您可以询问时间,然后同时应用偏移量(以小时为单位)。因此,如果您确实知道用户的时区偏移量,那就太好了。

不处理夏令时规则,虽然......

于 2008-12-19T16:08:51.223 回答
16

在(公认的罕见)需要本地数据时间的情况下(例如,我将本地时间存储在我的一个数据库中,因为我只关心一天中的时间是什么,并且我不跟踪我在哪里就时区而言...),您可以将列定义为

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

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

于 2009-02-21T03:38:59.617 回答
9

当使用“ 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

希望有帮助。

于 2009-08-11T18:11:17.640 回答
9
SELECT datetime('now', 'localtime');
于 2014-01-16T17:53:23.507 回答
9

SELECT datetime(CURRENT_TIMESTAMP, 'localtime')

于 2015-04-22T14:36:05.160 回答
5

Time ( 'now', 'localtime' )和日期( 'now', 'localtime' )工作。

于 2014-11-07T05:26:41.497 回答
4

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

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

给你:

1454521888

'timestamp' 表列甚至可以是文本字段,使用current_timestampas DEFAULT。

没有 strftime:

SELECT timestamp FROM ... ;

给你:

2016-02-03 17:51:28

于 2016-02-03T18:01:01.483 回答
3

我认为这可能会有所帮助。

SELECT datetime(strftime('%s','now'), 'unixepoch', 'localtime');
于 2009-02-20T23:46:43.310 回答
3

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

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

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

于 2012-11-14T02:22:32.480 回答