【问题标题】:How can I store the current timestamp in SQLite as ticks?如何将 SQLite 中的当前时间戳存储为刻度?
【发布时间】:2016-10-06 08:21:37
【问题描述】:

我有一个 SQLite 数据库,我将日期存储为刻度。我没有使用默认的 ISO8601 格式。假设我有一个定义如下的表:

CREATE TABLE TestDate (LastModifiedTime DATETIME)

使用 SQL,我希望插入当前日期和时间。如果我执行以下任何语句,我最终会将日期和时间存储为字符串而不是刻度。

INSERT INTO TestDate (LastModifiedTime) VALUES(CURRENT_TIMESTAMP)
INSERT INTO TestDate (LastModifiedTime) VALUES(DateTime('now'))

我查看了SQLite documenation,但似乎没有找到任何获取当前时间戳的选项。

我当然可以在 C# 中定义一个参数并将值存储为 System.DateTime。这确实会导致日期时间以刻度存储到数据库中。

我想做的是能够直接从 SQL 语句中插入和更新当前时间戳。我该怎么做?

编辑:

我希望将数据作为刻度存储在数据库中的原因是,日期的存储格式与 ADO.Net 数据提供程序存储的格式相同,因此当使用 ADO.Net 查询数据时provider 它被正确地检索为 System.DataTime .Net 类型。

【问题讨论】:

  • THX,将当前时间戳插入数据库只需添加 ---> DateTime('now')

标签: sqlite datetime iso8601


【解决方案1】:

SQLite 的这种特殊性让我非常痛苦。

简单的方法 - 以常规时间戳存储和检索

create table TestDate (
        LastModifiedTime datetime
);
insert into TestDate (LastModifiedTime) values (datetime('now'));
select datetime(LastModifiedTime), strftime('%s.%f', LastModifiedTime)  from TestDate;

输出:2011-05-10 21:34:46|1305063286.46.000

痛苦的方式 - 作为 UNIX 时间戳存储和检索

您可以使用 strftime 检索刻度值。此外,要存储 UNIX 时间戳(大致相当于刻度),您可以将秒数括在单引号中。

 insert into TestDate (LastModifiedTime) values ('1305061354');

SQLite 将在内部将其存储为其他一些不是 UNIX 时间戳的值。在检索时,您需要明确告诉 SQLite 将其作为 UNIX 时间戳进行检索。

 select datetime(LastModifiedTime, 'unixepoch') FROM TestDate;

要存储当前日期和时间,请使用 strftime('%s', 'now')。

 insert into TestDate (LastModifiedTime) VALUES (strftime('%s', 'now'));

完整示例:

create table TestDate (
        LastModifiedTime datetime
);      
insert into TestDate (LastModifiedTime) values (strftime('%s', 'now'));
select datetime(LastModifiedTime, 'unixepoch') from TestDate;

当被 sqlite3 执行时,这个脚本带有 print:

2011-05-10 21:02:34 (or your current time)

【讨论】:

  • The Easy Way 的时间戳输出似乎无效,原因有几个 - 它有一个额外的小数点,并且时钟秒数夹在纪元秒和毫秒之间。出于我的目的,我需要将“现在”与已经存储在数据库中的时间戳进行比较,以毫秒为单位,而不是十进制秒。但毫秒精度实际上并不重要,所以我最终改用strftime('%s000','now')
【解决方案2】:

在进一步研究SQLite documentation和其他关于日期数字转换的信息后,我想出了以下公式,它似乎产生了正确的结果:

INSERT INTO TestDate(LastModifiedTime)
    VALUES(CAST((((JulianDay('now', 'localtime') - 2440587.5)*86400.0) + 62135596800) * 10000000 AS BIGINT))

似乎是一种痛苦的方式来生成我希望可以作为内置日期时间格式使用的东西,尤其是数据库支持以刻度存储日期时间值。希望这对其他人也有用。

更新:

上述公式在夏令时方面并不完美。请参阅 SQLite 文档中有关本地时间计算的 Caveats And Bugs 部分。

【讨论】:

  • 您的公式不正确,因为它没有考虑夏令时时间的变化。 NTFS 中的 LastModifiedTime 元数据存储为 UTC,因此您的转换存在错误。
  • 确实如此。我添加了有关本地时间计算的注释。您对改进公式有什么建议吗?
【解决方案3】:

以下将返回自 UNIX 纪元以来的毫秒数:

SELECT (strftime('%s', 'now') - strftime('%S', 'now') + strftime('%f', 'now')) * 1000 AS ticks

它的工作原理是获取自 Unix 纪元 (%s) 以来的秒数,减去当前时间的秒数 (%S),然后添加秒数带小数位 (%f),然后将结果乘以 1000 以将秒数转换为毫秒数。

减法和加法是为了增加值的精度而不会使结果倾斜。如 SQLite 文档中所述,在同一步骤中对 'now' 的所有使用都将返回相同的值。

【讨论】:

  • 请注意,这会返回以毫秒为单位的时间。如果时间是您的主键,它可能不是唯一的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
相关资源
最近更新 更多