elasticsearch,Java,elasticsearch" /> elasticsearch,Java,elasticsearch" />

Java 从历元到1582年之前的日历日期转换毫秒时出现问题

Java 从历元到1582年之前的日历日期转换毫秒时出现问题,java,elasticsearch,Java,elasticsearch,我需要从elasticsearch获取日期,该日期在java中存储为1581年5月14日。我有elasticsearch的日期,单位为毫秒(-12264134400000)。在Java中转换为日期时,日期计算错误。我知道这与格鲁吉亚历和朱利安历有关,但我无法找到解决办法。我使用的代码很简单: Date dt = new Date(-12264134400000L); 上面给出的是1581年5月4日,而不是1581年5月14日 为了提供更多详细信息,我在Oracle数据库中输入了许多这样的日期,

我需要从elasticsearch获取日期,该日期在java中存储为1581年5月14日。我有elasticsearch的日期,单位为毫秒(-12264134400000)。在Java中转换为日期时,日期计算错误。我知道这与格鲁吉亚历和朱利安历有关,但我无法找到解决办法。我使用的代码很简单:

Date dt = new Date(-12264134400000L);
上面给出的是1581年5月4日,而不是1581年5月14日


为了提供更多详细信息,我在Oracle数据库中输入了许多这样的日期,这些日期被移动到Elasticsearch。从弹性搜索中获取日期的方式是毫秒(这就是Lucene索引读取的方式。把它看作一个约束)。所以我想把毫秒转换回原始日期,这样我就可以将它与另一个日期进行比较。因此,如果elasticsearch将1581年5月14日转换为-12264134400000,我希望1581年5月14日能够返回。

您应该使用java.time软件包,该软件包在java 8中引入:

LocalDate date = 
    Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDate();

这将给出预期的结果

您应该使用java 8中引入的
java.time
包:

LocalDate date = 
    Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDate();
这将产生预期的结果

< >我从RealCyStk中获取日期的方式是毫秒(这就是Lucene索引读取的方式。将此视为约束)。

我会重新评估你提到的约束的必要性。是谁强加的,为什么

在1950年之后(大约)的时间点上,以毫秒为单位处理实例是可以接受的,但通过将16世纪的历史日期转换为毫秒,您将面临大量问题;包括但不限于确定要使用哪个时区,以及如何确保将日期转换为毫秒的一侧和将日期转换回日期的一侧使用相同的时区。ElasticSearch如何将日期转换为毫秒时间戳

还有一个非常现实的风险是,您使用的软件堆栈从未在类似时间戳的字段中使用历史日期测试过,这些字段用于最近和当前的时间

如果您需要中间格式来传输这些日期,请使用
yyyyy-MM-DD
YYYYMMDD
字符串表示法中的日历日期。这至少意味着对它们进行排序是开箱即用的

要使用Java中的历史日期,请从Java8中引入的开始(如@sharon ben asher所述)

< >我从RealCyStk中获取日期的方式是毫秒(这就是Lucene索引读取的方式。将此视为约束)。

我会重新评估你提到的约束的必要性。是谁强加的,为什么

在1950年之后(大约)的时间点上,以毫秒为单位处理实例是可以接受的,但通过将16世纪的历史日期转换为毫秒,您将面临大量问题;包括但不限于确定要使用哪个时区,以及如何确保将日期转换为毫秒的一侧和将日期转换回日期的一侧使用相同的时区。ElasticSearch如何将日期转换为毫秒时间戳

还有一个非常现实的风险是,您使用的软件堆栈从未在类似时间戳的字段中使用历史日期测试过,这些字段用于最近和当前的时间

如果您需要中间格式来传输这些日期,请使用
yyyyy-MM-DD
YYYYMMDD
字符串表示法中的日历日期。这至少意味着对它们进行排序是开箱即用的


要使用Java中的历史日期,请从Java 8中引入的开始(如@sharon ben asher所述)。

那是在公历生效之前。你只是期望得到错误的结果。是的,但我在数据库中有这样的日期。我只需要在Java中以某种方式将这些日期从毫秒中恢复过来。请在创建日期之后告诉我们您正在使用它做什么。
日期
只是时间上的瞬间-将其转换为年/月/日的日期需要额外的操作。(出于各种原因,我会避免使用
dt.toString()
)这里的答案取决于你想用它做什么。“我想要1581年5月14日回来”-作为一个字符串?还有别的吗?同样,需要更多的细节。理想情况下,提供一些代码来显示你对日期做了什么。但这绝对重要。您已经在
Date
中获得了正确的值-只有您查看该值的方式才会给出错误的结果。它是将日期转换成年/月/日的形式…这是在公历生效之前。你只是期望得到错误的结果。是的,但我在数据库中有这样的日期。我只需要在Java中以某种方式将这些日期从毫秒中恢复过来。请在创建日期之后告诉我们您正在使用它做什么。
日期
只是时间上的瞬间-将其转换为年/月/日的日期需要额外的操作。(出于各种原因,我会避免使用
dt.toString()
)这里的答案取决于你想用它做什么。“我想要1581年5月14日回来”-作为一个字符串?还有别的吗?同样,需要更多的细节。理想情况下,提供一些代码来显示你对日期做了什么。但这绝对重要。您已经在
Date
中获得了正确的值-只有您查看该值的方式才会给出错误的结果。它是将
日期
转换成具有年/月/日的形式…对于一些值来说似乎是正确的。让我测试一下,我会更新。注意,在这里使用系统默认时区可能不是正确的方法-我建议仔细检查一下。@JonSkeet,我不明白为什么时区在这个场景中很重要,因为它涉及到