【问题标题】:What is the appropriate date formatting so the lexicographic ordering is the same as time ordering?什么是适当的日期格式,以便字典顺序与时间顺序相同?
【发布时间】:2016-08-23 16:10:38
【问题描述】:

在我的 SQLite 数据库中,没有 Date 数据类型,所以我必须以文本格式存储时间戳。

yyyy-MM-dd HH:mm 格式是否会产生正确的排序,这样当您按字典顺序对其进行排序时(通过执行正常的 ASC 或 DESC 排序),它本身也会按时间值排序?

【问题讨论】:

  • 添加标签到帖子
  • 您可以将它们存储为 INTEGER 类型,以毫秒为单位。
  • @cricket_007 我也考虑过,但不知道如何轻松地在人类可读的日期和 SQL 友好的毫秒计数之间来回转换。我也不知道一个是否比另一个占用更多空间,或者一个是否比另一个更有效
  • 称为纪元时间戳。请使用 SampleDateFormat 查看how to convert
  • 我也不知道如何正确获取当前时间(以毫秒为单位)

标签: java android sqlite date simpledateformat


【解决方案1】:

是的。只是你不应该错过中间的任何 0。 (四月的“04”)。

必须将 April 表示为“04”,而不仅仅是“4”。

【讨论】:

  • 对不起,我不明白你在“是”之后的意思。缺少 0 是什么意思?
【解决方案2】:

您的格式是正确的想法;当按字母顺序排序时,它也是按时间顺序排列的。

您可以更进一步,获得该格式的更好版本,即标准格式,让您的工作更简单、更轻松。

ISO 8601

ISO 8601 标准为表示日期时间相关值的文本定义了多种实用的合理格式。

对于日期和时间的组合格式为:

YYYY-MM-DDTHH:MM:SS.SZ

例如:

2016-04-28T18:22:20.123Z

这种字符串格式会根据您的需要按时间顺序排序。

中间的T 将日期部分与时间部分分开。末尾的ZZulu 的缩写,表示UTC。

通常,最佳做法是将日期时间值转换为 UTC 以用于存储和数据库。您的 JDBC 驱动程序可能会为您执行此操作,但我不了解 SQLite。

java.time

java.time 框架内置于 Java 8 及更高版本中。大部分功能在ThreeTen-Backport 项目中向后移植到Java 6 和7,并在ThreeTenABP 项目中进一步适应Android。

这些新类取代了旧的java.util.Date/.Calendar 和相关类,这些类已被证明设计不佳且很麻烦。

在解析/生成日期时间值的文本表示时,这些类默认使用 ISO 8601 格式。在 Stack Overflow 上搜索许多示例。

InstantUTC 时间线上的一个时刻,分辨率为nanoseconds

Instant instant = Instant.now();

只需调用toString 即可生成该值的字符串表示。

String stringForDatabase = instant.toString();

在 Java 8 中,由于Clock 接口的传统实现,当前时刻仅被捕获到毫秒分辨率,为小数点后 3 位。例如,2016-04-29T00:12:57.123Z。在 Java 9 及更高版本中,Clock 的现代实现能够在计算机硬件时钟支持的范围内以最多 9 位小数(纳秒)捕获当前时刻。

Instant:toString 使用的默认格式化程序使用 0、3、6 或 9 位打印秒的小数部分,根据需要表示秒小数部分的非零部分。所有这些都按要求按字母顺序和时间顺序排序,因此您可以将其中任何一个存储在您的数据库中。

  • 2016-04-29T00:12:57Z
  • 2016-04-29T00:12:57.123Z
  • 2016-04-29T00:12:57.123456Z
  • 2016-04-29T00:12:57.123456789Z

这些都直接解析回Instant 实例。因此,无需像在问题中那样定义自己的格式模式。

Instant instant = Instant.parse( "2016-04-29T00:12:57.123456789Z" );

要查看特定地点的挂钟时间,请应用时区 (ZoneId) 以获取 ZonedDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

提取Instant 以存储回数据库。

Instant instant = zdt.toInstant();
String forDatabase = instant.toString();

【讨论】:

  • 投反对票的人,请在投反对票的同时留下批评意见。
  • Instant 的默认格式化程序有一个致命缺陷:当小数部分为零时,它会忽略小数部分。因为 Z 在数字之后排序,所以恰好有零毫秒的时间将在具有相同秒数和非零毫秒的时间之后排序,对于微秒也是如此。作为一个具体的例子,考虑 2020-11-19T06:10:07.198Z 和 2020-11-19T06:10:07.198466Z - 前者更早,但排序在之后。
猜你喜欢
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 2022-01-12
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
相关资源
最近更新 更多