Sqlite: текущая метка времени находится в GMT, а не часовой пояс машины
У меня есть таблица sqlite (v3) с этим определением столбца:
"timestamp" DATETIME DEFAULT CURRENT_TIMESTAMP
сервер, на котором живет эта база данных, находится в часовом поясе CST. Когда я вставляю в свою таблицу без включения столбца timestamp, sqlite автоматически заполняет это поле текущей меткой времени в GMT, а не CST.
есть ли способ изменить мой оператор insert, чтобы заставить сохраненную метку времени быть в CST? С другой стороны, вероятно, лучше хранить его в GMT (в случае, если например, база данных перемещается в другой часовой пояс), поэтому есть ли способ изменить мой select SQL, чтобы преобразовать сохраненную метку времени в CST при ее извлечении из таблицы?
11 ответов
Я нашел в документации sqlite (https://www.sqlite.org/lang_datefunc.html) этот текст:
вычислить дату и время, заданные unix метки 1092941466 и компенсации для вашего местного часового пояса.
SELECT datetime(1092941466, 'unixepoch', 'localtime');
это не похоже на то, что это соответствует моим потребностям, поэтому я попытался немного изменить функцию "datetime" и закончил с этим:
select datetime(timestamp, 'localtime')
это, кажется, работает - это правильный способ преобразования для вашего часовой пояс, или есть лучший способ сделать это?
просто используйте местное время по умолчанию:
CREATE TABLE whatever(
....
timestamp DATE DEFAULT (datetime('now','localtime')),
...
);
вы должны, как правило, оставлять метки времени в базе данных в GMT и преобразовывать их только в/из локального времени на входе/выходе, когда вы можете преобразовать их в локальную метку времени пользователя (не сервера).
было бы неплохо, если бы вы могли сделать следующее:
SELECT DATETIME(col, 'PDT')
...для вывода метки времени для пользователя в Тихоокеанское летнее время. К сожалению, это не работает. Согласно этот учебник SQLite, однако (прокрутите вниз до " другая дата и время Команды"), вы можете запросить время, а затем применить смещение (в часах) одновременно. Итак, если вы знаете смещение часового пояса пользователя, вы в порядке.
не имеет дело с правилами летнего времени, хотя...
в (признанном редком) случае, когда требуется локальный datatime (я, например, храню локальное время в одной из моих баз данных, так как все, что меня волнует, - это время в день, и я не отслеживаю, где я был в терминах часовых поясов...), вы можете определить столбец как
"timestamp" TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M','now', 'localtime'))
%Y - %m - %dT%H:%M часть, конечно, необязательна; это именно то, как мне нравится, чтобы мое время хранилось. [Кроме того, если мое впечатление верно, в sqlite нет типа данных "DATETIME", поэтому это не имеет значения используется ли текст или DATETIME в качестве типа данных в объявлении столбца.]
при наличии столбца, определенного с помощью "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
надеюсь, что это поможет.
вы также можете просто преобразовать столбец времени в метку времени с помощью strftime ():
SELECT strftime('%s', timestamp) as timestamp FROM ... ;
дает вам:
1454521888
столбец таблицы "отметка времени" может быть текстовым полем даже, используя current_timestamp
по умолчанию.
без strftime:
SELECT timestamp FROM ... ;
дает вам:
2016-02-03 17:51:28