26

我知道这是一个很常见的问题,但我觉得我找到的答案并不能真正解决问题。我将概述我的具体用例,并总结来自其他 SO 答案和网络上的信息。

对于我正在编写的服务,数据库条目是在移动设备和我们的网站上创建和存储的,并且需要双向同步。我们目前的目标是 Android 和 iOS,它们都使用 sqlite 作为关系数据库。服务器端是在 Python 中使用 Django 和 MySQL 实现的,但其他解决方案可能会在未来取代它。

将按照此 SO 答案中概述的想法实施同步:https ://stackoverflow.com/a/5052208/2076094 。对于同步,我们将使用仅由服务器设置并同步到客户端的时间戳、last_synced_date 和用于对象创建和更新的时间戳。由于对象指的是用户在特定时间所做的事情,因此它们也具有时间戳信息。

我的问题只涉及用于这些时间戳的时间的内部表示。UI 中的用户表示是内部表示的本地化和格式化版本。在实现语言和用于表示时间戳的不同数据库中都有很多不同的方式。经过相当多的研究,似乎只剩下有效的解决方案:

  • Unix 时间
  • ISO8601

Hacker News 上的这篇文章(两次)建议使用 UNIX 时间,并提出了一个很好的论点。正如预期的那样,关于 HN 的讨论围绕上述两点存在相当大的分歧,然后是一些分歧。

到目前为止,我的结论是,Unix 时间时间戳更容易处理,但似乎不是 Django 中的常用方法。我发现的几乎每个代码示例,从 Django 教程到许多其他站点,都在 models.py 中使用 DateTimeField,它被映射到 SQL 中的某种日期字段,确切的术语取决于所使用的数据库。

使用 ISO8601 日期进行传输和存储的缺点是需要对其进行解析以创建相应的实现语言的 Date 类型。这并不难,但有点烦人。对于我们使用的每一种语言,您要么需要一个(小型)库,要么至少需要比您希望的更多的代码。它不是很漂亮,会创建依赖关系并且可能会稍微慢一些。Unix 时间时间戳在我所知道的任何语言中都没有这个问题。

另一件事是,使用数据库中的“智能”日期或时间戳字段(以及在解析期间)很容易遇到麻烦。SO上有很多关于时间魔法的问题,这些问题会把事情搞砸。我的链接已达到限制,所以我不能发布任何内容,但你会很容易找到一些;)

我们可以使用不包含时区信息的简化格式,并且始终使用 UTC。无论如何,我们只会使用 UTC,但如果您使用 ISO8601,您还不如使用普遍理解且明确的格式。Unix 时间始终采用 UTC,因此您永远不必担心这一点。

当然,当您查看原始数据库时,ISO8601 具有人类可读的优点,而且我不必在 2038 年之前不久重写几行代码,但这似乎并不能弥补缺点。

似乎通过写东西,我实际上已经有了答案;)无论如何,我很想知道其他人的想法以及您在自己的项目中做了什么。请简要概述您的用例,以便其他人可以更好地对您的输入进行分类。

谢谢!

4

1 回答 1

2

真的很难找到任何关于时间数据类型或时间标准格式的信息,不管它是什么已知的。在过去的几天里,我自己一直在努力选择正确的时间格式。和你一样,我也在移动设备和网络服务器中编码(更不用说还有一个桌面应用程序)。

我问自己的主要问题是“我怎样才能在移动设备、Web 服务器(API,或者你想调用的任何东西)和桌面应用程序之间获得无缝体验?如何在事件发生时保持一致?如何确保这个瞬间的表示在这个软件星座的不同层次中是相同的?

您可能知道使用移动设备进行编码意味着您正在使用 SQLite 数据库,而 Web 应用程序主要意味着 MySQL。我深感失望的是,我能想象到的最令人头疼的事情之一就是使用时间数据从一个数据库转到另一个数据库。选择什么?约会时间?时间戳?哦,天哪,SQLite 没有内置的时间数据类型……Unix 时间?好吧,没问题,当然MySQL不以UNIX时间为标准……太简单了……</p>

我学到的是……如果您想将数据放在时间线上并说这是时间线上发生此事件的时间点,最好使用时间戳(无论是 UNIX 还是 MySQL 风格,又名 ISO8601)

人类可读对我来说只是一个细节。没有人应该阅读数据库表,计算机会这样做,并且您确实告诉计算机以人类可以理解的顺序处理数据。

但是接下来的问题是“时区是什么?” 突然出现……嗯……很糟糕……但是,嘿,会在网上寻找答案。

我自己很惊讶 MySQL 不使用 UNIX time,我认为这是人们可以拥有的最标准和最一致的时间格式。

我真的认为围绕这​​些选择的文档和标准是有限的……我现在正在考虑写一些关于如何使用 MySQL 和 SQLite 处理时间的东西。我确实在这件事上浪费了半周的时间,试图了解如何让它变得干净和简单,结论是,有了可用的文档,你就无法……

我可能错了……

不管怎样,看看这段视频,展示了在 MySQL 中处理时间戳数据的过程:

http://www.youtube.com/watch?v=fp-etlirjbo

于 2013-09-29T12:13:44.753 回答