cle*_*tus 375
Date是一个更简单的类,主要是出于向后兼容的原因.如果您需要设置特定日期或进行日期算术,请使用日历.日历还处理本地化.之前的Date日期操作函数已被弃用.
就个人而言,当有选择时,我倾向于使用毫秒作为长(或适当的长)或日历.
日期和日历都是可变的,在API中使用时往往会出现问题.
dme*_*ter 66
新代码的最佳方式(如果您的策略允许第三方代码)是使用Joda Time库.
无论,日期和日历,有这么多的设计问题,无论是对新代码良好的解决方案.
oxb*_*kes 57
Date
并且Calendar
实际上是相同的基本概念(两者都代表了一个瞬间,并且是基础long
价值的包装).
人们可能会争辩说Calendar
实际上甚至比实际上更加破碎Date
,因为它似乎提供了关于诸如星期几和时间等事情的具体事实,而如果你改变它的timeZone
属性,具体就会变成白痴!由于这个原因,这两个对象都不能用作年月日或时间的存储.
使用Calendar
仅作为一个计算器其中,由于在Date
和TimeZone
对象,会为你做计算.避免将其用于应用程序中的属性类型.
使用SimpleDateFormat
连同TimeZone
和Date
生成显示字符串.
如果你喜欢冒险使用Joda-Time,虽然它是不必要的复杂恕我直言,并且很快就会被JSR-310 date API取代.
我之前已经回答过,在你自己的YearMonthDay
课程中使用它并不困难,它可以Calendar
在引擎盖下进行日期计算.我对这个建议进行了投票,但我仍然相信这是一个有效的建议,因为Joda-Time(和JSR-310)对于大多数用例来说真的太复杂了.
KLE*_*KLE 25
日期最适合存储日期对象.它是持久的,序列化的......
日历最适合操纵日期.
注意:我们有时也喜欢java.lang.Long而不是Date,因为Date是可变的,因此不是线程安全的.在Date对象上,使用setTime()和getTime()在两者之间切换.例如,应用程序中的常量日期(示例:零1970/01/01,或者您设置为2099/12/31的应用END_OF_TIME;那些将空值替换为开始时间和结束时间非常有用,尤其是当你将它们保存在数据库中时,因为SQL对于null来说是如此奇特).
Arc*_*ano 17
如果可能,我通常使用日期.尽管它是可变的,但实际上不推荐使用mutators.最后它基本上包裹了一个代表日期/时间的长.相反,如果我必须操纵值,我会使用日历.
您可以这样想:只有当您需要使用可以轻松操作的字符串然后使用toString()方法将它们转换为字符串时,才使用StringBuffer.同样,如果我需要操作时态数据,我只使用Calendar.
对于最佳实践,我倾向于在域模型之外尽可能多地使用不可变对象.它显着降低了任何副作用的机会,它由编译器为您完成,而不是JUnit测试.您可以通过在类中创建私有最终字段来使用此技术.
并回到StringBuffer类比.以下是一些代码,向您展示如何在日历和日期之间进行转换
String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String
// immutable date with hard coded format. If you are hard
// coding the format, best practice is to hard code the locale
// of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");
// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// mutate the value
cal.add(Calendar.YEAR, 1);
// convert back to Date
Date newDate = cal.getTime();
//
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);
Run Code Online (Sandbox Code Playgroud)
And*_*yle 15
Date
s应该用作不可变时间点; Calendar
s是可变的,如果您需要与其他类协作以提出最终日期,则可以传递和修改.考虑它们类似于String
和StringBuilder
,你就会明白我是如何认为他们应该被使用.
(是的,我知道Date实际上并不是技术上不可变的,但意图是它不应该是可变的,如果没有任何东西调用已弃用的方法那么它就是这样.)
Bas*_*que 12
建议当前的"最佳实践"
Date
和Calendar
总是喜欢
Calendar
过来是最好的Date
完全避免使用这些遗留类.请改用java.time类.
Instant
Date
ZonedDateTime
GregorianCalendar
OffsetDateTime
LocalDateTime
在通过Ortomala答案 Lokni是正确运用现代暗示java.time类,而不是麻烦的旧的遗留日期时间类(Date
,Calendar
,等).但是那个答案表明错误的等级是等同的(参见我对该答案的评论).
java.time类是对传统日期时间类,日夜差异的巨大改进.旧的课程设计糟糕,令人困惑,麻烦.你应该尽可能避免使用旧课程.但是当你需要转换为旧/新转换时,你可以通过调用新方法添加到旧类来实现.
有关转换的更多信息,请参阅我的答案和另一个问题的漂亮图表,将java.util.Date转换为"java.time"类型?.
搜索Stack Overflow在使用java.time时提供了数百个示例问题和解答.但这是一个快速的概要.
Instant
获取当前时刻Instant
.该Instant
级表示时间轴上的时刻UTC,分辨率为纳秒(最多9个(9)小数的位数).
Instant instant = Instant.now();
Run Code Online (Sandbox Code Playgroud)
ZonedDateTime
要通过某个特定区域的挂钟时间镜头看到相同的同时时刻,请应用时区()来获得a .ZoneId
ZonedDateTime
指定适当的时区名称,格式continent/region
,如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
.切勿使用3-4字母缩写,例如EST
或IST
因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone();
Run Code Online (Sandbox Code Playgroud)
时区是区域与UTC的偏移量变化的历史记录.但有时你只给出一个没有完整区域的偏移量.在这种情况下,请使用该OffsetDateTime
课程.
ZoneOffset offset = ZoneOffset.parse( "+05:30" );
OffsetDateTime odt = instant.atOffset( offset );
Run Code Online (Sandbox Code Playgroud)
使用时区优于仅使用偏移.
LocalDateTime
类中的"本地" Local…
表示任何地点,而不是特定地点.所以这个名字可能违反直觉.
LocalDateTime
,LocalDate
并LocalTime
故意缺乏有关偏移或时区的任何信息.所以它们并不代表实际时刻,它们不是时间轴上的点.如果有疑问或混淆,请使用ZonedDateTime
而不是LocalDateTime
.搜索Stack Overflow进行更多讨论.
不要将日期时间对象与表示其值的字符串混淆.您可以解析字符串以获取日期时间对象,并且可以从日期时间对象生成字符串.但字符串永远不是日期时间本身.
了解标准ISO 8601格式,默认情况下在java.time类中使用.
该java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date
,Calendar
,和SimpleDateFormat
.
现在处于维护模式的Joda-Time项目建议迁移到java.time类.
要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.
使用符合JDBC 4.2或更高版本的JDBC驱动程序,您可以直接与数据库交换java.time对象.不需要字符串也不需要java.sql.*类.
从哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval
,YearWeek
,YearQuarter
,和更多.
Ort*_*kni 10
使用Java 8,应该使用新的java.time包.
对象是不可变的,时区和日光节省被考虑在内.
您可以ZonedDateTime
从旧java.util.Date
对象创建对象,如下所示:
Date date = new Date();
ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
Run Code Online (Sandbox Code Playgroud)
我总是提倡乔达时间.这就是原因.
编辑:如果您可以迁移到Java 8,Java 8引入的Java日期/时间类现在是首选解决方案
归档时间: |
|
查看次数: |
175831 次 |
最近记录: |