将日期(没有时间)表示为单个整数

时间:2014-01-13 21:08:38

标签: date

是否有标准方法将日期表示为单个整数? (我只需要存储日期,而不是完整的时间戳。)

如果重要,我想这样做的原因是因为我将日期存储在Android上的SQLite数据库中,并希望将它们存储为数字,以便可以有效地比较/排序它们以返回查询结果。

3 个答案:

答案 0 :(得分:2)

只需将每天的时间设置为您选择的任意时间,例如凌晨2点。

无论如何将它们存储为时间戳可能仍然是一个好主意,因为您有更多的日期格式选项。

答案 1 :(得分:2)

一个不错的选择可能是YYYYMMDD,例如今天(2014年1月13日)编码为整数20140113

优点:

  • 只要您关心<==>;
  • ,它就适用于比较
  • 这是相当人性化的;
  • 它与ISO 8601 standard兼容。

缺点:

  • 计算日期之间的差异并不容易;
  • SQLite不会将其识别为日期。

最后一点:SQLite3 documentation表示SQLite3没有特定的日期和/或时间存储类型。相反,它建议使用以下之一:

  • TEXT 为ISO8601字符串("YYYY-MM-DD HH:MM:SS.SSS")。
  • REAL 作为朱利安日数,是公元前4714年11月24日格林威治中午以来的天数。根据预感格里高利历。
  • INTEGER as Unix Time,自1970-01-01 00:00:00 UTC以来的秒数。

所有这些显然都可以使用SQLite的内置日期和时间函数进行处理。

后者主张bdf's answer中的解决方案。在指定日期内选择任意时间无疑是有问题的,但我建议中午选择UTC不一定会引起太多问题,只要您小心使用它就会一直存在。

答案 2 :(得分:0)

要记住的一个重要细节是时区。如果例如您的时间落在您的时区偏移量和GMT之间,您可能会得到意想不到的结果。因此,首先,我建议我们将date讨论为用户可见的那一个,通常是本地时区之一。

因此,如果我们假设本地时间,并且我们想使用Date对象,那么有2种可能的解决方案,我将以JavaScript单元测试样式进行介绍。第一个是Keith Thompson之前提出的一个:

let date = new Date('1987-12-31T01:02:03')

let simpleDateInteger = (
  date.getFullYear() * 10000 +
  (date.getMonth() + 1) * 100 +
  date.getDate()
)

expect(simpleDateInteger).toBe(19871231)

let fromSimpleDateInteger = new Date(
  simpleDateInteger / 10000, // year
  simpleDateInteger / 100 % 100 - 1, // month
  simpleDateInteger % 100 // day
)

expect(fromSimpleDateInteger.toDateString()).toEqual(date.toDateString())

如果您需要更多紧凑型整数,并且每个整数+1代表第二天,即连续表示,则可以使用以下形式:

let date = new Date('1987-12-31T00:01:02')

const DAY_IN_MILLISECONDS = 86400 * 1000

let timeZoneInMilliSeconds = date.getTimezoneOffset() * 60 * 1000

let continuousDateInteger = Math.floor(
  (date.getTime() - timeZoneInMilliSeconds) / DAY_IN_MILLISECONDS
)

expect(continuousDateInteger).toBe(6573)

let fromContinuousDateInteger = new Date(
  continuousDateInteger * DAY_IN_MILLISECONDS + timeZoneInMilliSeconds
)

expect(fromContinuousDateInteger.toDateString()).toEqual(date.toDateString())