SQLite Forum

Convert datetime string to second since Epoch with millisecond precision
Login
Fascinating, because I get the "correct" results with MSVC x64 as well as my GCC 9.1.0 MinGW64, but the results of the downloaded executable (apparently compiled with GCC-5.2.0 of some description) the julianday result is out by 25 ULP which results in the computed unixtime being out by 4219 ULP ...

```
SQLite version 3.33.0 2020-08-14 13:23:32
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .version
SQLite 3.33.0 2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f
zlib version 1.2.11
gcc-5.2.0
sqlite> create table t(s text, f real);
sqlite> insert into t(s) values ('2016-06-13T09:36:34Z');
sqlite> insert into t(s) values ('2016-06-13T09:36:34.123Z');
sqlite> insert into t(s) values ('2016-06-13T09:36:34.123456Z');
sqlite> update t set f = (julianday(s) - 2440587.5) * 86400.0;
sqlite> select * from t;
┌─────────────────────────────┬──────────────────┐
│              s              │        f         │
├─────────────────────────────┼──────────────────┤
│ 2016-06-13T09:36:34Z        │ 1465810594.00001 │
│ 2016-06-13T09:36:34.123Z    │ 1465810594.122   │
│ 2016-06-13T09:36:34.123456Z │ 1465810594.123   │
└─────────────────────────────┴──────────────────┘
sqlite> select s, printf('%!.16f', f) from t;
┌─────────────────────────────┬─────────────────────────────┐
│              s              │     printf('%!.16f', f)     │
├─────────────────────────────┼─────────────────────────────┤
│ 2016-06-13T09:36:34Z        │ 1465810594.0000085831015352 │
│ 2016-06-13T09:36:34.123Z    │ 1465810594.1219954490226107 │
│ 2016-06-13T09:36:34.123456Z │ 1465810594.1230013371037732 │
└─────────────────────────────┴─────────────────────────────┘
sqlite>

SQLite version 3.34.0 2020-11-05 19:31:02
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .version
SQLite 3.34.0 2020-11-05 19:31:02 91cd3839204a000f79887243fbbb1678f185b14e479b5b6781b057e7ec5cec7c
zlib version 1.2.11
gcc-9.1.0
sqlite> create table t(s text, f real);
sqlite> insert into t(s) values ('2016-06-13T09:36:34Z');
sqlite> insert into t(s) values ('2016-06-13T09:36:34.123Z');
sqlite> insert into t(s) values ('2016-06-13T09:36:34.123456Z');
sqlite> update t set f = (julianday(s) - 2440587.5) * 86400.0;
sqlite> select * from t;
┌─────────────────────────────┬──────────────────┐
│              s              │        f         │
├─────────────────────────────┼──────────────────┤
│ 2016-06-13T09:36:34Z        │ 1465810594.00001 │
│ 2016-06-13T09:36:34.123Z    │ 1465810594.123   │
│ 2016-06-13T09:36:34.123456Z │ 1465810594.123   │
└─────────────────────────────┴──────────────────┘
sqlite> select s, printf('%!.16f', f) from t;
┌─────────────────────────────┬─────────────────────────────┐
│              s              │     printf('%!.16f', f)     │
├─────────────────────────────┼─────────────────────────────┤
│ 2016-06-13T09:36:34Z        │ 1465810594.0000085830688477 │
│ 2016-06-13T09:36:34.123Z    │ 1465810594.1230013370513916 │
│ 2016-06-13T09:36:34.123456Z │ 1465810594.1230013370513916 │
└─────────────────────────────┴─────────────────────────────┘
sqlite> select ulps((julianday('2016-06-13T09:36:34.123Z') - 2440587.5) * 86400.0, 1465810594.1219954490226107);
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ulps((julianday('2016-06-13T09:36:34.123Z') - 2440587.5) * 86400.0, 1465810594.1219954490226107) │
├──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 4219.0                                                                                           │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
sqlite>

SQLite version 3.34.0 2020-11-05 19:31:02
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .version
SQLite 3.34.0 2020-11-05 19:31:02 91cd3839204a000f79887243fbbb1678f185b14e479b5b6781b057e7ec5cec7c
zlib version 1.2.11
msvc-1927
sqlite> create table t(s text, f real);
sqlite> insert into t(s) values ('2016-06-13T09:36:34Z');
sqlite> insert into t(s) values ('2016-06-13T09:36:34.123Z');
sqlite> insert into t(s) values ('2016-06-13T09:36:34.123456Z');
sqlite> update t set f = (julianday(s) - 2440587.5) * 86400.0;
sqlite> select * from t;
┌─────────────────────────────┬──────────────────┐
│              s              │        f         │
├─────────────────────────────┼──────────────────┤
│ 2016-06-13T09:36:34Z        │ 1465810594.00001 │
│ 2016-06-13T09:36:34.123Z    │ 1465810594.123   │
│ 2016-06-13T09:36:34.123456Z │ 1465810594.123   │
└─────────────────────────────┴──────────────────┘
sqlite> select s, printf('%!.16f', f) from t;
┌─────────────────────────────┬─────────────────────────────┐
│              s              │     printf('%!.16f', f)     │
├─────────────────────────────┼─────────────────────────────┤
│ 2016-06-13T09:36:34Z        │ 1465810594.0000085709584709 │
│ 2016-06-13T09:36:34.123Z    │ 1465810594.123001298072495  │
│ 2016-06-13T09:36:34.123456Z │ 1465810594.123001298072495  │
└─────────────────────────────┴─────────────────────────────┘
sqlite> select ulps((julianday('2016-06-13T09:36:34.123Z') - 2440587.5) * 86400.0, 1465810594.1219954490226107);
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ulps((julianday('2016-06-13T09:36:34.123Z') - 2440587.5) * 86400.0, 1465810594.1219954490226107) │
├──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 4219.0                                                                                           │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
```

I have made no changes to date.c which would account for this.