SQLite datetime () принимает дробные значения модификатора? - PullRequest
2 голосов
/ 10 марта 2020

Как указано в заголовке, принимает ли функция SQLite datetime () дробные (REAL / float / et c) значения для своих предложений модификатора? Официальная документация явно не так или иначе прямо указывает на целое и действительное число. Тот факт, что в нем указаны NNN для минут, часов, дней, месяцев и лет, но NNN.NNNN для секунд, предполагает, что только секунды будут принимать дробное значение. Однако простое тестирование показывает, что дробные значения приемлемы для любого из этих модификаторов.

CREATE TABLE a (rel TEXT);
INSERT INTO a VALUES('0.25 days');
INSERT INTO a VALUES('0.5 days');
INSERT INTO a VALUES('1 days');
INSERT INTO a VALUES('1.5 days');
INSERT INTO a VALUES('2 days');
INSERT INTO a VALUES('7 days');
INSERT INTO a VALUES('14 days');
INSERT INTO a VALUES('0.25 months');
INSERT INTO a VALUES('0.5 months');
INSERT INTO a VALUES('1 months');
INSERT INTO a VALUES('1.5 months');
INSERT INTO a VALUES('6 months');
INSERT INTO a VALUES('0.5 years');
INSERT INTO a VALUES('1 years');
INSERT INTO a VALUES('1.5 years');

SELECT rel, datetime('now', 'localtime', rel) FROM a;

rel         datetime('now', 'localtime', rel)
----------  ---------------------------------
0.25 days   2020-03-10 05:21:35              
0.5 days    2020-03-10 11:21:35              
1 days      2020-03-10 23:21:35              
1.5 days    2020-03-11 11:21:35              
2 days      2020-03-11 23:21:35              
7 days      2020-03-16 23:21:35              
14 days     2020-03-23 23:21:35              
0.25 month  2020-03-17 11:21:35              
0.5 months  2020-03-24 23:21:35              
1 months    2020-04-09 23:21:35              
1.5 months  2020-04-24 23:21:35              
6 months    2020-09-09 23:21:35              
0.5 years   2020-09-08 11:21:35              
1 years     2021-03-09 23:21:35              
1.5 years   2021-09-08 11:21:35

Мне просто интересно, есть ли у кого-нибудь окончательный ответ какие-то другие доказательства или опыт если на это поведение - правильное вычисление даты и времени из дробных модификаторов - можно положиться, или если это просто извращение.

1 Ответ

1 голос
/ 11 марта 2020

Это не странность. Как бы неудобно ни было, когда вы полагаетесь на поведение, которое, по-видимому, выходит за пределы ограниченного вывода документов, может быть пора обновить документы.

Реализация datetime SQLite в src/date.c понимает NNN для обозначения дробных чисел:

/*
** The following table defines various date transformations of the form
**
**            'NNN days'
**
** Where NNN is an arbitrary floating-point number and "days" can be one
** of several units of time.
*/

Более того, тестовые примеры в test/date.test охватывают некоторые дробные арифметические даты и времени c в единицах, больших, чем секунды:

$ perl -lnE 'say if /\d\.\d+\s+(days|hours|minutes|months|years)/' date.test 
datetest 2.24 {datetime('2003-10-22 12:34','1.5 months')} {2003-12-07 12:34:00}
datetest 2.26 {datetime('2003-10-22 12:34','+10.5 minutes')} \
datetest 2.27 {datetime('2003-10-22 12:34','-1.25 hours')} \
datetest 8.15 {datetime('now','1.5 months')} {2003-12-07 12:34:00}
datetest 8.17 {datetime('now','+10.5 minutes')} {2003-10-22 12:44:30}
datetest 8.18 {datetime('now','-1.25 hours')} {2003-10-22 11:19:00}
datetest 13.21 {julianday(2454832.5,'-1.5 months')} {2454786.5}
datetest 13.22 {julianday(2454832.5,'+1.5 months')} {2454878.5}
datetest 13.23 {julianday(2454832.5,'-1.5 years')} {2454284.0}
datetest 13.24 {julianday(2454832.5,'+1.5 years')} {2455380.0}
datetest 13.30 {date('2000-01-01','+1.5 years')} {2001-07-02}
datetest 13.31 {date('2001-01-01','+1.5 years')} {2002-07-02}
datetest 13.32 {date('2002-01-01','+1.5 years')} {2003-07-02}
datetest 13.33 {date('2002-01-01','-1.5 years')} {2000-07-02}
datetest 13.34 {date('2001-01-01','-1.5 years')} {1999-07-02}

В качестве предостережения отметим, что для этого вида арифметики даты и времени c SQLite использует нормализованные интервалы времени, которые не всегда соответствуют нашему гражданскому расчету: 60 секунд (но больше секунд), 24 часа дней (но с учетом летнего времени!), 30 дневных месяцев (привет, сентябрь, апрель, июнь и ноябрь - где твои друзья?) и 365 дневных лет (но високосные годы!).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...