在 django 和 javascript 之间传递日期时间时保持微秒精度
Keeping microsecond precision when passing datetime between django and javascript
django 或 sqlite 数据库似乎以微秒精度存储日期时间。但是当 passing a time to 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"
请注意 58.520124
现在是 58.520
。
例如,当我想为日期时间小于或等于现有对象时间(即 MyModel.objects.filter(time__lte=javascript_datetime)
)的所有对象创建一个查询集时,这就会成为一个问题。通过截断微秒,对象不再出现在列表中,因为时间不相等。
我该如何解决这个问题?是否有支持微秒精度的 datetime javascript 对象?我可以将数据库中的时间截断到毫秒吗(我几乎到处都在使用 auto_now_add
)或者要求以较低的准确性执行查询?
How can I work around this?
TL;DR:存储较低的精度,通过:
- 诱使您的数据库平台只存储毫秒并丢弃任何额外的精度(我认为在 SQLite 上很难)
- 仅以您想要的精度插入值(很难确保涵盖所有情况)
Is there a datetime javascript object that supports microsecond accuracy?
如果您将日期编码为字符串或数字,您可以添加任意多的准确性。还有其他选项(一些讨论 in this thread)。除非你真的 想要 这种准确性,否则它可能不是最好的方法。
Can I truncate times in the database to milliseconds..
是的,但是因为您使用的是 SQLite,所以有点奇怪。 SQLite 并没有真正的日期;您实际上是将值存储在 text
、real
或 integer
字段中。这些底层存储 classes 决定了您可以存储的值的精度和范围。有一个不错的 write up of the differences here.
例如,您可以将底层存储 class 更改为 integer
。这会将存储在该字段中的日期截断为 1 秒的精度。从 JS 执行查询时,您同样可以使用 Date.prototype.setMilliseconds()
function 截断日期。例如..
MyModel.objects.filter(time__lte = javascript_datetime.setMilliseconds(0))
功能更完整的数据库平台会更好地处理它。例如在 PostgreSQL 中你可以 specify the precision stored more exactly。这将添加一个精确到毫秒的时间戳列(与 Javascript 匹配)..
alter table "my_table" add "my_timestamp" timestamp (3) with time zone
MySQL 将 let you do the same thing.
.. or ask that the query be performed with reduced accuracy?
是的,但这通常是错误的方法。
如果您通过过滤的标准是精确的,那么您就可以了;您可以截断该值然后进行过滤(如上面的 ..setMilliseconds()
示例)。但是,如果您正在检查 against 的数据库中的值过于精确,您将会遇到麻烦。
您可以编写一个查询,以便在与您的标准进行比较之前格式化或截断存储的值以降低其精度,但需要执行该操作对于存储的每个值。这可能是数百万个值。更重要的是,因为您是动态生成值,所以您刚刚绕过了针对存储值创建的任何索引。
django 或 sqlite 数据库似乎以微秒精度存储日期时间。但是当 passing a time to 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"
请注意 58.520124
现在是 58.520
。
例如,当我想为日期时间小于或等于现有对象时间(即 MyModel.objects.filter(time__lte=javascript_datetime)
)的所有对象创建一个查询集时,这就会成为一个问题。通过截断微秒,对象不再出现在列表中,因为时间不相等。
我该如何解决这个问题?是否有支持微秒精度的 datetime javascript 对象?我可以将数据库中的时间截断到毫秒吗(我几乎到处都在使用 auto_now_add
)或者要求以较低的准确性执行查询?
How can I work around this?
TL;DR:存储较低的精度,通过:
- 诱使您的数据库平台只存储毫秒并丢弃任何额外的精度(我认为在 SQLite 上很难)
- 仅以您想要的精度插入值(很难确保涵盖所有情况)
Is there a datetime javascript object that supports microsecond accuracy?
如果您将日期编码为字符串或数字,您可以添加任意多的准确性。还有其他选项(一些讨论 in this thread)。除非你真的 想要 这种准确性,否则它可能不是最好的方法。
Can I truncate times in the database to milliseconds..
是的,但是因为您使用的是 SQLite,所以有点奇怪。 SQLite 并没有真正的日期;您实际上是将值存储在 text
、real
或 integer
字段中。这些底层存储 classes 决定了您可以存储的值的精度和范围。有一个不错的 write up of the differences here.
例如,您可以将底层存储 class 更改为 integer
。这会将存储在该字段中的日期截断为 1 秒的精度。从 JS 执行查询时,您同样可以使用 Date.prototype.setMilliseconds()
function 截断日期。例如..
MyModel.objects.filter(time__lte = javascript_datetime.setMilliseconds(0))
功能更完整的数据库平台会更好地处理它。例如在 PostgreSQL 中你可以 specify the precision stored more exactly。这将添加一个精确到毫秒的时间戳列(与 Javascript 匹配)..
alter table "my_table" add "my_timestamp" timestamp (3) with time zone
MySQL 将 let you do the same thing.
.. or ask that the query be performed with reduced accuracy?
是的,但这通常是错误的方法。
如果您通过过滤的标准是精确的,那么您就可以了;您可以截断该值然后进行过滤(如上面的 ..setMilliseconds()
示例)。但是,如果您正在检查 against 的数据库中的值过于精确,您将会遇到麻烦。
您可以编写一个查询,以便在与您的标准进行比较之前格式化或截断存储的值以降低其精度,但需要执行该操作对于存储的每个值。这可能是数百万个值。更重要的是,因为您是动态生成值,所以您刚刚绕过了针对存储值创建的任何索引。