为什么不能为Java日历设置一个小时和一分钟?

时间:2019-05-26 17:22:55

标签: java date calendar

我试图创建一个新的Java Calendar对象并设置其小时和分钟,但是在设置变量并打印calendar.HOUR_OF_DAY加上分钟和毫秒后,无论给我什么小时,分钟和毫秒,我的设定。

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 3);
calendar.set(Calendar.MINUTE, 30);

System.out.printLn("Alarm created for " +
                        calendar.HOUR_OF_DAY + ":" +
                        calendar.MINUTE + ":" +
                        calendar.MILLISECOND); // Will print 11:12:14 no matter what

如何在Calendar对象中设置小时和分钟?我也尝试了其他值(例如0和0)

1 个答案:

答案 0 :(得分:0)

tl; dr

使用现代的 java.time 类,而不要使用传统的日期时间类。

ZonedDateTime                 // Use the modern class `ZonedDateTime` replacing terrible `Calendar` & `GregorianCalendar` classes.
.now()                        // Capture the current moment as seen in the JVM’s current default time zone. Better to pass explicitly your desired/expected time zone.
.with(                        // Adjust the values within the `ZonedDateTime`. 
    LocalTime.of( 3 , 30 )    // Passing a `LocalTime` changes all the time-of-day fields: hours, minutes, seconds, fractional second.
)                             // Generates a new object based on the values of the original, as the *java.time* classes use the immutable objects pattern.

如果您必须具有Calendar才能与尚未更新为 java.time 的旧代码进行互操作,请进行转换。

GregorianCalendar.from(
    ZonedDateTime.now().with( LocalTime.of( 3 , 30 ) )    
)                         

避免使用旧的日期时间类

可怕的CalendarGregorianCalendar c激光器在几年前被现代的 java.time 类所取代,并采用了JSR 310。具体来说,ZonedDateTime

ZonedDateTime zdt = ZonedDateTime.now() ;
LocalTime lt = LocalTime.of( 3 , 30 ) ;
ZonedDateTime zdtFixedTime = zdt.with( lt ) ;

指定时区

通常最好显式地传递您希望的/期望的时区,而不是隐式依赖JVM当前的默认值。

Continent/Region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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

转化:传统⇄现代

如果您确实需要Calendar,请从ZonedDateTime转换为GregorianCalendar。使用添加到旧类中的新转换方法。要从现代过渡到传统,GregorianCalendar.from

Calendar c = GregorianCalendar.from( zdtFixedTime ) ;

朝另一个方向,GregorianCalendar::toZonedDateTime

ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime() ;

如果以Calendar开头,则查看它是否为GregorianCalendar。如果是这样,投。然后转换。

if( myCalendar instanceof GregorianCalendar ) {                  // Test the concrete class.
    GregorianCalendar gc = ( GregorianCalendar ) myCalendar ;    // Cast.
    ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime() ;  // Convert legacy to modern.
}