在django和javascript

时间:2015-09-21 06:16:45

标签: javascript django time precision

似乎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)或者要求以较低的准确度执行查询吗?

1 个答案:

答案 0 :(得分:1)

  

我该如何解决这个问题?

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

  • 哄骗你的数据库平台只存储几毫秒并丢弃任何额外的精度(我觉得SQLite很难)
  • 只能以您想要的精度插入值(难以确保您已覆盖所有情况)
  

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

如果您将日期编码为字符串或数字,则可以添加更多您想要的准确度。还有其他选择(一些讨论in this thread)。除非你实际上想要这个准确性,否则它可能不是最好的方法。

  

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

是的,但是因为你在SQLite上,这有点奇怪。 SQLite没有真正的日期;您实际上是将值存储在textrealinteger字段中。这些底层存储类决定了您可以存储的值的精度和范围。有一个不错的write up of the differences here

例如,您可以将基础存储类更改为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

  

..或者要求以较低的准确度执行查询?

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

如果您按过滤的标准是精确的,那么您就可以了;您可以截断值然后过滤(如上面的..setMilliseconds()示例)。但是,如果您正在检查的数据库中的值太精确,那么您将会遇到错误的时间。

可以编写一个查询,以便在与标准进行比较之前对存储的值进行格式化或截断以降低其精度,但是需要对每个值执行操作存储即可。这可能是数百万的价值。更重要的是,因为您正在动态生成值,所以您只是绕过了针对存储值创建的任何索引。