我正在尝试将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
}
}当代码运行在具有“澳大利亚/维多利亚”以外的时区的机器上时,就会出现问题。
有人能帮我指出我做错了什么吗?
发布于 2018-04-05 09:08:44
将TimeZone设置为SimpleDateFormat
public class Test {
public static void main(String[] arg){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
ZoneId zoneId = ZoneId.of("Australia/Victoria");
format.setTimeZone(TimeZone.getTimeZone(zoneId));
final LocalDate localDate = LocalDate.now(zoneId).withDayOfMonth(16).withMonth(10).withYear(2017);
final GregorianCalendar gregorianCalendar = GregorianCalendar.from(localDate.atStartOfDay(zoneId));
System.out.println(format.format(gregorianCalendar.getTime())); //prints 2017-10-16
}
}发布于 2019-07-24 04:48:22
tl;dr
您将糟糕的遗留类与现代的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。某些区域中的某些日期从另一个时间开始,例如01:00:00。让java.time确定第一时刻。
ZonedDateTime zdt = ld.atStartOfDay( z ) ; // Determine the first moment of the day on that date in that zone.在世界协调时看到同样的时刻。提取一个Instant,它总是在UTC。
Instant instant = zdt.toInstant() ;请注意,上述所有代码都来自java.time包类系列。
尽可能避免GregorianCalendar。但是,如果您必须与尚未更新为java.time的旧代码进行互操作,请转换。查看添加到旧类中的新的to…/from…转换方法。在本例中,请参见GregorianCalendar.from。
GregorianCalendar gc = GregorianCalendar.from( zdt ) ;

https://stackoverflow.com/questions/49667772
复制相似问题