在Java中使用LocalDate时未完成的时间

时间:2016-04-05 18:42:33

标签: java java-time

我正在尝试将今天的日期格式化为“MM / dd / yyy HH:00”,其中分钟始终为零。使用此格式时,小时数不正确:

LocalDate date = DateTime.now().withZone(DateTimeZone.forID("America/New_York")).toLocalDate();
String format = date.toString("MM/dd/yyyy HH:00");

logger.info(format);

输出

enter image description here

使用LocalDate获取小时数有不同的方法吗?

2 个答案:

答案 0 :(得分:3)

来自LocalDate的JavaDoc:

  

ISO-8601日历系统中没有时区的日期,例如2007-12-03。

  

此类不存储或表示时间或时区。相反,它是日期的描述,用于生日。如果没有附加信息(如偏移或时区),它就不能代表时间线上的瞬间。

改为使用LocalDateTime

答案 1 :(得分:1)

TL;博士

ZonedDateTime.now( ZoneId.of( "America/New_York" ) )
         .truncatedTo( java.time.temporal.ChronoUnit.HOURS )
         .format( DateTimeFormatter.ofPattern( "MM/dd/uuuu HH:mm" , Locale.US ) )
  

02/27/2017 23:00

详细

Answer by rmuller是正确的。

java.time vs Joda-Time

更大的问题:您似乎使用的是Joda-Time类,但使用java-time标记了您的问题,这意味着java.time类。

Meno Hochschild对该问题发表了评论,指出了图书馆明显的混淆。

Joda-Time项目是一个独立的库,不是内置于Java中的。该项目为java.time提供了灵感和经验。虽然概念类似,但java.time完全是经过重新设计的,完全不是替代品。 Joda-Time和java.time都由同一个人Stephen Colebourne (“jodastephen”)领导。 Joda-Time项目现在位于maintenance mode,团队建议迁移到java.time类。

java.time中没有DateTimeDateTimeZone类。

使用java.time

在java.time中,你的代码就是这样。

ZoneId z = ZoneId.of( "America/New_York" ) ;
LocalDate localDate = LocalDate.now( z ) ;

但是你想要一个时间,而rmuller pointed out,你需要使用另一个类LocalDate只有日期,没有任何时间。而是使用ZonedDateTime来获取wall-clock time确定的特定地区ZoneId所见的日期和时间。

ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;

滥用格式化模式

另一个问题:对格式化模式进行硬编码以显示零来代替分钟,这是实现目标的一种棘手方法。这样做并不能使你的意图明确。其他程序员在阅读您的代码时可能会错过您的操作。

如果代码“说实话”,我发现代码更易于维护。因此,通过使用硬编码的零数字来改变分钟的显示而不是“撒谎”,最好更改基础数据本身。好处包括使您的意图清晰,并使调试器中的值与字符串的输出相匹配。

truncatedTo

我建议您明确更改日期时间对象的值。调用truncatedTo方法来关闭分钟和秒以及小数秒。那些削弱的值变为零。

java.time使用immutable objects。因此,我们不是更改对象的值(“mutate”),而是生成一个新对象,其值基于原始对象的值。

ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
ZonedDateTime zdtTruncatedToHour = zdt.truncatedTo( java.time.temporal.ChronoUnit.HOURS ) ;
  

zdtTruncatedToHour.toString():2017-02-27T23:00-05:00 [America / New_York]

从那里,你可以使用通常的toStringDateTimeFormatter方式生成一个字符串,只有分钟,秒和小数秒出现零。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu HH:mm" , Locale.US );
String output = zdtTruncatedToHour.format( f );
  

02/27/2017 23:00

请参阅此示例code running live in IdeOne.com

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore