Java日期和日历

Java日期和日历,java,date,Java,Date,我知道Java8有一个基于Joda time的改进了很多的日期和时间库,但是我对旧库中的决策非常好奇。我还没有找到关于java.util.Date构造函数弃用原理的任何好的解释。我找到的最接近的问题是:但它没有询问弃用的方法/构造函数,也没有公认的答案 构造函数java.util.Dateyear,month,day被认为是不推荐使用的,我们应该使用新的GregoriaCalendarYear+1900,month,date。如果调用返回日期的getTime。。。在日历实例上,除了避免使用不推荐

我知道Java8有一个基于Joda time的改进了很多的日期和时间库,但是我对旧库中的决策非常好奇。我还没有找到关于java.util.Date构造函数弃用原理的任何好的解释。我找到的最接近的问题是:但它没有询问弃用的方法/构造函数,也没有公认的答案

构造函数java.util.Dateyear,month,day被认为是不推荐使用的,我们应该使用新的GregoriaCalendarYear+1900,month,date。如果调用返回日期的getTime。。。在日历实例上,除了避免使用不推荐的构造函数之外,我们还获得了什么?甚至java.sql.Date.toLocalDate在内部也使用了一些不推荐使用的方法

我的代码库中充斥着这种模式——新的GregorianCalendar加上getTime,只是为了避免不推荐的java.util.Date方法,我需要在JPA和JDBC中使用java.util.Date和java.sql.Date,但我不确定它的意义是什么,或者当时的意义是什么*


*现在,我终于可以将它们全部更改为LocalDate,因为这正是我真正需要的——保存用户键入的内容,而不进行任何时区转换。

请参阅javadoc中的第二段:

在JDK1.1之前,类日期有两个附加函数。它允许将日期解释为年、月、日、小时、分钟和秒值。它还允许格式化和解析日期字符串。不幸的是,这些函数的API不适合国际化。从JDK1.1开始,该类应用于在日期和时间字段之间进行转换,该类应用于格式化和解析日期字符串。Date中的相应方法已弃用

因此,为了回答您的问题,我们获得了什么?答案是支持国际化:

能够使用日历指定时区

能够使用日历使用非公历

能够使用DateFormat对日期字符串进行本地化格式设置和解析


参见javadoc的第二段:

在JDK1.1之前,类日期有两个附加函数。它允许将日期解释为年、月、日、小时、分钟和秒值。它还允许格式化和解析日期字符串。不幸的是,这些函数的API不适合国际化。从JDK1.1开始,该类应用于在日期和时间字段之间进行转换,该类应用于格式化和解析日期字符串。Date中的相应方法已弃用

因此,为了回答您的问题,我们获得了什么?答案是支持国际化:

能够使用日历指定时区

能够使用日历使用非公历

能够使用DateFormat对日期字符串进行本地化格式设置和解析


旧库允许通过传入年、月、日等项,从公历中的条目构造java.util.Date项

这是有问题的,原因有很多。首先,公历系统是从儒略历法系统过渡而来的混合历法系统。这种转变包括需要跳过日期,以使儒略历法系统与季节相一致。因此,我们有缺失的日子。令人惊讶的是,java.util.Date在捕获这种行为方面做得不错,除了:

要跳过的日期取决于采用转换的时间,这主要取决于语言环境。 核心java.util.Date对象与公历的强绑定意味着实现其他日历系统是有问题的,因为您需要在公历系统之上实现它们。 日期与区域设置和时区相关联也意味着您必须调整平台的区域设置和时区,以获得所需的适当日期行为,通常会将其调整回本地以外的日期计算。 新的日历系统试图通过以下方式避免这种情况:

具有传入字段以设置值的API,防止日历字段直接绑定到API方法。 有一个API,允许对日历进行子类化,这样就可以实现月、日、年定义截然不同的日历——比如农历、犹太日历、阿拉伯日历、中国日历等等。
接下来,应该只将java.util.Date用作时间戳的薄包装器,这更能与旧的API兼容。所有日期操作都应在适当的日历实例中完成。

旧库允许通过传入年、月、日等项,从公历中的条目构造java.util.Date项

这是有问题的,原因有很多。首先,公历是从儒略历过渡而来的混合历法 系统这种转变包括需要跳过日期,以使儒略历法系统与季节相一致。因此,我们有缺失的日子。令人惊讶的是,java.util.Date在捕获这种行为方面做得不错,除了:

要跳过的日期取决于采用转换的时间,这主要取决于语言环境。 核心java.util.Date对象与公历的强绑定意味着实现其他日历系统是有问题的,因为您需要在公历系统之上实现它们。 日期与区域设置和时区相关联也意味着您必须调整平台的区域设置和时区,以获得所需的适当日期行为,通常会将其调整回本地以外的日期计算。 新的日历系统试图通过以下方式避免这种情况:

具有传入字段以设置值的API,防止日历字段直接绑定到API方法。 有一个API,允许对日历进行子类化,这样就可以实现月、日、年定义截然不同的日历——比如农历、犹太日历、阿拉伯日历、中国日历等等。
接下来,应该只将java.util.Date用作时间戳的薄包装器,这更能与旧的API兼容。所有日期操作都应在适当的日历实例中进行。

日期的螺母设计为1900年后的年份数,而不是可识别的数字。你得到了什么?略为合理的API。事实上,month在这两种情况下都使用0表示一月。。。令人沮丧。我同意。让我们看看是否还有其他问题:-有,如中所述。遗留日期时间类有一长串问题、缺陷和糟糕的设计选择。我建议不要陷入研究它们的兔子洞,除非学会如何不设计你的课程。通过学习java.time来更明智地利用这段时间,永远不要回头看。尽管有很好的详细答案,但真正解决主要问题的只有@AndyTurner的评论。我猜他们只是认为它太坏了,无法保存,并且没有添加更多的构造函数和方法,例如getFullYear。太糟糕了,JDBC不得不在4.2版之前接受它!Date的螺母设计年份为1900年后的年份数,而不是可识别的数字。你得到了什么?略为合理的API。事实上,month在这两种情况下都使用0表示一月。。。令人沮丧。我同意。让我们看看是否还有其他问题:-有,如中所述。遗留日期时间类有一长串问题、缺陷和糟糕的设计选择。我建议不要陷入研究它们的兔子洞,除非学会如何不设计你的课程。通过学习java.time来更明智地利用这段时间,永远不要回头看。尽管有很好的详细答案,但真正解决主要问题的只有@AndyTurner的评论。我猜他们只是认为它太坏了,无法保存,并且没有添加更多的构造函数和方法,例如getFullYear。太糟糕了,JDBC不得不在4.2版之前接受它!你能补充一下你关于新格雷戈里安·达里,m,d·盖蒂姆模式的回答吗?我仍然需要Date java.util或java.sql的实例来与数据库JPA或JDBC接口,所以这些优势大多在转换过程中被抛弃了,不是吗?@marcus用java.time完成所有工作、所有业务逻辑和所有字符串生成。在最后一刻,当您必须拥有这些可怕的旧遗留类的对象时,转换。从添加到旧类的…调用新的转换方法。查看GregorianCalendar以转换为ZoneDateTime或从ZoneDateTime转换为ZoneDateTime。查看java.util.Date以转换为/从Instant,两者都表示UTC中的一个时刻。另外,从JDBC 4.2开始,我们可以直接与数据库交换java.time对象,而不需要遗留类。您能否补充一下关于模式new GregorianCalendary,m,d.getTime的答案?我仍然需要Date java.util或java.sql的实例来与数据库JPA或JDBC接口,所以这些优势大多在转换过程中被抛弃了,不是吗?@marcus用java.time完成所有工作、所有业务逻辑和所有字符串生成。在最后一刻,当您必须拥有这些可怕的旧遗留类的对象时,转换。从添加到旧类的…调用新的转换方法。查看GregorianCalendar以转换为ZoneDateTime或从ZoneDateTime转换为ZoneDateTime。查看java.util.Date以转换为/从Instant,两者都表示UTC中的一个时刻。另外,从JDBC4.2开始,我们可以直接与数据库交换java.time对象,不需要遗留类。我不同意你们在2018年使用日历,但这是另一回事。有一次是这样。作为时间戳的薄薄包装,为什么会有错误?例如,不推荐使用ne请求例如昨天的午夜时间戳
w Datey,m,d,为什么通过新的GregorianCalendar+getTime问同样的问题是正确的?±1900是我想到的唯一原因。@Marcus A java.util.Date,比如java.time.Instant,总是UTC中的一个时刻,所以它不能直接得到昨天的午夜,除非是UTC。要确定午夜,您必须确定一个日期,要确定一个日期,您需要一个时区,对于一个时区,您必须使用GregorianCalendar,现在由java.time.zoneDateTime替换。小贴士:想想“今天的第一刻”而不是“昨天的午夜”。“午夜”的概念是模棱两可和棘手的。更复杂的是,在某些时区,一天可以从00:00:00.0以外的时间开始,比如01:00:00.0。我想你被昨天午夜的一个不太重要的细节抓住了,忘记了重要的部分:新日期1900,m,d与新格雷戈里安达里,m,d。两者都没有显式设置小时或时区,它们都有类似的默认值,但只有一个不推荐使用。@OleV.V。我同意,新的java.time.*类比Joda time好得多,但由于问题是日期与日历,我忽略了接下来的比日历更好的改进。感谢您的洞察力。我不同意你们在2018年使用日历,但这是另一回事。曾经是这样。作为时间戳的薄薄包装,为什么不推荐使用例如昨天的午夜时间戳和新的Datey,m,d,以及为什么不推荐使用new Gregorianalendar+getTime来使用相同的东西?±1900是我想到的唯一原因。@Marcus A java.util.Date,比如java.time.Instant,总是UTC中的一个时刻,所以它不能直接得到昨天的午夜,除非是UTC。要确定午夜,您必须确定一个日期,要确定一个日期,您需要一个时区,对于一个时区,您必须使用GregorianCalendar,现在由java.time.zoneDateTime替换。小贴士:想想“今天的第一刻”而不是“昨天的午夜”。“午夜”的概念是模棱两可和棘手的。更复杂的是,在某些时区,一天可以从00:00:00.0以外的时间开始,比如01:00:00.0。我想你被昨天午夜的一个不太重要的细节抓住了,忘记了重要的部分:新日期1900,m,d与新格雷戈里安达里,m,d。两者都没有显式设置小时或时区,它们都有类似的默认值,但只有一个不推荐使用。@OleV.V。我同意,新的java.time.*类比Joda time好得多,但由于问题是日期与日历,我忽略了接下来的比日历更好的改进。