我这样做的原因是,在任何数据库中存储为日期对象的日期往往以特定格式编写,这可能与您需要在前端呈现给用户的内容大不相同。我还认为,如果您的应用程序从不同类型的数据存储中提取信息,这将特别有用。一个很好的例子是 MongoDB 和 SQL 日期对象之间的区别。
但是,我不知道这是否是推荐的做法。我应该继续将日期存储为长(以毫秒为单位的时间)还是日期对象?
关于 MongoDB,我不能代表它,但在 SQL 数据库中,不,这不是最佳实践。这并不意味着可能没有偶尔的用例,而是“最佳实践”没有。
将它们存储为日期,将它们检索为日期。您最好的选择是设置您的数据库以将它们存储为 UTC(松散地,“GMT”),以便数据是可移植的,并且您可以根据需要使用不同的本地时间(例如,如果数据库由地理上不同的用户使用) ,并在应用层处理从 UTC 到本地时间的任何转换(例如,通过Calendar
或第三方日期库)。
将日期存储为数字意味着您的数据库难以报告、运行临时查询等。我犯过一次错误,我不会在没有充分理由的情况下重复这个错误。:-)
这在很大程度上取决于:
第三点可能是最重要的。想想你试图存储的值的真正含义。即使您显然没有使用 Noda Time,但希望我的用户指南页面根据您的输入数据选择要使用的 Noda Time 类型可以帮助您清楚地考虑这一点。
如果您只使用过 Java,并且您的数据库对日期/时间类型没有非常好的支持,并且您只是试图表示“即时”(而不是特定时间的瞬间)时区,或带有偏移量的本地日期/时间,或只是一个本地日期/时间,或只是一个日期......),您可以轻松编写诊断工具将您的数据转换为更易于阅读的形式 - 然后存储along
是合理的。但这是一个相当长的“如果”列表。
如果您希望能够在数据库中执行日期操作——例如,询问发生在当月第一天的所有值——那么您可能应该使用日期/时间类型,注意时区。(我的经验是,当涉及到日期/时间类型时,大多数数据库至少有令人震惊的糟糕记录。)
一般来说,您应该使用能够满足您所有要求并且是该特定环境最自然的表示的任何类型。因此,在具有日期/时间类型的数据库中,当您与之交互时不会给您带来问题(例如,以未经请求的方式执行任意时区转换),请使用该类型。它将使各种事情变得更容易。
使用更“原始”的表示(例如 64 位整数)的优点正是数据库不会乱用它。您有效地从数据库中隐藏了数据的含义,具有该方法的所有正常优点和缺点(主要是缺点)。
这取决于各个方面。当使用标准的“自纪元以来的秒数”时,有人只使用整数精度,他们的日期被限制在 1970-2038 年的范围内。
但也存在一些精度问题。例如,unix 时间忽略闰秒。每天被定义为具有相同的秒数。因此,当计算 unix 时间之间的时间增量时,您确实会遇到一些错误。
但更重要的是,您假设您的所有日期都是完全已知的,因为您的陈述不可能只减半指定日期的一半。在现实中,有很多你不知道秒(甚至毫秒)精度的事件。因此,如果表示允许指定例如仅天精度,则它是一个特征。理想情况下,您将存储日期及其精确信息。
此外,假设您正在构建一个日历应用程序。有时间,但也有当地时间。很多时候,您需要两个可用的信息。当调度重叠时,你当然可以在同步的时间内做到最好,所以这里的 long 会很好。但是,如果您还想确保不会在当地时间9-20 小时之外安排活动,您还需要始终保留时区信息。对于跨越多个位置的任何事情,您确实需要在日期表示中包含时区。假设您可以将您看到的所有日期转换为您当前的当地时间是非常幼稚的。
请注意,SQL 中的日期可能会导致奇怪的情况。我最喜欢的MySQL 荒谬之一是:
SELECT * FROM Dates WHERE date IS NULL AND date IS NOT NULL;
可能会返回包含 date 的记录0000-00-00 00:00:00
,尽管这违反了对逻辑的普遍理解。
由于这个问题是用 MongoDB 标记的:MongoDB 不会将日期存储在 String 或其他什么中,它们实际上将其存储为 long ( http://www.mongodb.org/display/DOCS/Dates ):
BSON 日期值将自 Unix 纪元(1970 年 1 月 1 日)以来的毫秒数存储为 64 位整数。v2.0+ :此数字已签名,因此 1970 年之前的日期存储为负数。
由于 MongoDB 没有立即计划使用 SQL 在标准查询中具有的复杂日期处理功能(例如仅查询年份等),因此没有真正的缺点,它实际上可能会减少索引和存储的大小。
这里需要考虑一件事,聚合框架:http ://docs.mongodb.org/manual/reference/aggregation/#date-operators有一些奇怪而美妙的事情,你只能使用支持的 BSON 日期类型但是,MongoDB 是否对您很重要取决于您的查询。
您是否认为自己需要聚合框架功能?或者将额外的物体放在头顶会很痛苦吗?
我个人的看法是,BSON 日期类型是一个很小的对象,如果没有它来存储文档,就会无缘无故地影响整个系统及其未来的兼容性。所以,是的,我会使用 BSON 日期类型而不是 long,我认为这样做是一种好习惯。
我认为存储日期不是最佳做法,因为这意味着您将无法执行任何特定于日期的查询。像 :
where date between
我们也无法轻松地使用 sql 查询从表中获取日期月份。
最好在 java 层中使用单个日期格式转换器并将日期转换为该日期并在整个应用程序中使用单个格式。
恕我直言,如果您可以使用字符串,最好将日期存储在数据库中。因此,如果您不需要日历中的所有字段,请避免不必要的数据上下传输到服务器。Calendar 中有很多数据,Calender 的每个实例也很重。
因此,将其存储为 String ,仅包含所需的数据并将其转换回 Calendar ,无论何时需要它们并使用它们。