我正在尝试将 LocalDate 转换为 GregorianCalendar,但 GregorianCalendar 输出给出的日期比 LocalDate 早一天。
下面是代码片段:
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.GregorianCalendar;
public class Test {
public static void main(String[] arg){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
final LocalDate localDate = LocalDate.now(ZoneId.of("Australia/Victoria")).withDayOfMonth(16).withMonth(10).withYear(2017);
final GregorianCalendar gregorianCalendar = GregorianCalendar.from(localDate.atStartOfDay(ZoneId.of("Australia/Victoria")));
System.out.println(format.format(gregorianCalendar.getTime())); //prints 2017-10-15
}
}
当代码在时区不是“澳大利亚/维多利亚”的计算机上运行时,就会出现问题。
谁能帮我指出我做错了什么?
最佳答案
tl;博士
您正在将可怕的遗留类与现代java.time类混合在一起。 不要这样做。
LocalDate
.parse( "2017-10-16" )
.atStartOfDay(
ZoneId.of( "Australia/Victoria" )
)
如果您必须使用糟糕的 GregorianCalendar
类,请使用添加到旧类中的新转换方法。
GregorianCalendar // Terrible legacy class. Use only if you *must*.
.from(
LocalDate
.parse( "2017-10-16" )
.atStartOfDay(
ZoneId.of( "Australia/Victoria" )
)
)
详细信息
您的代码是可怕的遗留日期时间类(SimpleDateFormat
,GregorianCalendar
)与现代java.time 取代它们的类 ( LocalDate
)。
具体来说,ZonedDateTime
取代了 GregorianCalendar
。
LocalDate
仅表示日期,没有时间和时区。相比之下,ZonedDateTime
(和 GregorianCalendar
)表示一个时刻:日期、时间和时区。
从LocalDate
开始。
LocalDate ld = LocalDate.parse( "2017-10-16" ) ;
指定一天中的某个时间。
LocalTime lt = LocalTime.of( 15 , 30 ) ; // 3:30 PM.
指定您想要的时区。
ZoneId z = ZoneId.of( "Australia/Victoria" ) ;
组合起来得到一个ZonedDateTime
、一个时刻、时间轴上的一个特定点。
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
或者您可能想使用一天中的第一时刻作为一天中的时间部分。不要将其硬编码为 00:00:00。某些区域中的某些日期在其他时间开始,例如 01:00:00。让java.time确定第一个时刻。
ZonedDateTime zdt = ld.atStartOfDay( z ) ; // Determine the first moment of the day on that date in that zone.
在 UTC 中查看同一时刻。提取始终采用 UTC 格式的Instant
。
Instant instant = zdt.toInstant() ;
请注意,上述代码全部均来自java.time包系列类。
尽可能避免使用GregorianCalendar
。但如果您必须与尚未更新到 java.time 的旧代码进行互操作,请进行转换。查看添加到旧类中的新to...
/from...
转换方法。在这种情况下,请参阅GregorianCalendar.from
.
GregorianCalendar gc = GregorianCalendar.from( zdt ) ;
关于java - 本地日期到公历日历的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49667772/