在 django 和 javascript 之间传递日期时间时保持微秒精度

joz*_*yqk 5 javascript django precision time

似乎 django 或 sqlite 数据库正在以微秒精度存储日期时间。但是,当将时间传递给 javascript 时,Date对象仅支持毫秒:

var stringFromDjango = "2015-08-01 01:24:58.520124+10:00";
var time = new Date(stringFromDjango);
$('#time_field').val(time.toISOString()); //"2015-07-31T15:24:58.520Z"
Run Code Online (Sandbox Code Playgroud)

注意58.520124是现在58.520

例如,当我想为日期时间小于或等于现有对象(即MyModel.objects.filter(time__lte=javascript_datetime))的所有对象创建查询集时,这就会成为一个问题。通过截断微秒,对象不再出现在列表中,因为时间不相等。

我该如何解决这个问题?是否有支持微秒精度的日期时间 javascript 对象?我是否可以将数据库中的时间截断为毫秒(我几乎auto_now_add到处都在使用)或要求以降低的精度执行查询?

Mol*_*mby 1

我该如何解决这个问题?

TL;DR:通过以下方式存储较低的精度:

  • 哄骗你的数据库平台只存储毫秒并放弃任何额外的精度(我认为在 SQLite 上很难)
  • 仅以您想要的精度插入值(很难确保您涵盖了所有情况)

是否有支持微秒精度的日期时间 JavaScript 对象?

如果您将日期编码为字符串或数字,您可以添加所需的精确度。还有其他选项(本线程中讨论了一些选项)。除非您确实想要这种准确性,否则这可能不是最好的方法。

我可以将数据库中的时间截断为毫秒吗?

是的,但是因为你使用的是 SQLite,所以有点奇怪。SQLite 并没有真正的日期;您实际上将值存储在text,realinteger字段中。这些底层存储类别决定了您可以存储的值的精度和范围。这里有一个不错的差异写法

例如,您可以将基础存储类别更改为integer. 这会将存储在该字段中的日期截断为 1 秒的精度。当从 JS 执行查询时,您同样可以使用Date.prototype.setMilliseconds()函数截断日期。例如..

MyModel.objects.filter(time__lte = javascript_datetime.setMilliseconds(0))
Run Code Online (Sandbox Code Playgroud)

功能更齐全的数据库平台会更好地处理它。例如,在 PostgreSQL 中,您可以更准确地指定存储的精度。这将添加一个精确到毫秒的时间戳列(与 Javascript 的精度相匹配)。

alter table "my_table" add "my_timestamp" timestamp (3) with time zone
Run Code Online (Sandbox Code Playgroud)

MySQL 会让你做同样的事情

..或者要求以降低的精度执行查询?

是的,但这通常是错误的方法。

如果您的过滤标准非常精确,那么就可以了;您可以截断值然后进行过滤(如..setMilliseconds()上面的示例所示)。但是,如果您要检查的数据库中的值太精确,您就会遇到麻烦。

可以编写一个查询,对存储的值进行格式化或截断,以降低其精度,然后再与您的条件进行比较,但需要对每个存储的值执行该操作。这可能是数百万个值。更重要的是,因为您是动态生成值,所以您刚刚绕过了针对存储值创建的任何索引。