首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LocalDate到GregorianCalendar转换

LocalDate到GregorianCalendar转换
EN

Stack Overflow用户
提问于 2018-04-05 08:36:35
回答 2查看 2.1K关注 0票数 0

我正在尝试将LocalDate转换为GregorianCalendar,但是GregorianCalendar输出给我的日期是比LocalDate早一天。

下面是代码片段:

代码语言:javascript
复制
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
    }
}

当代码运行在具有“澳大利亚/维多利亚”以外的时区的机器上时,就会出现问题。

有人能帮我指出我做错了什么吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-05 09:08:44

TimeZone设置为SimpleDateFormat

代码语言:javascript
复制
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
    }
}
票数 2
EN

Stack Overflow用户

发布于 2019-07-24 04:48:22

tl;dr

您将糟糕的遗留类与现代的java.time类混合在一起。不要那样做。

代码语言:javascript
复制
LocalDate
.parse( "2017-10-16" )
.atStartOfDay(
    ZoneId.of( "Australia/Victoria" )
)

如果必须使用可怕的GregorianCalendar类,请使用添加到旧类的新转换方法。

代码语言:javascript
复制
GregorianCalendar  // Terrible legacy class. Use only if you *must*. 
.from(
    LocalDate
    .parse( "2017-10-16" )
    .atStartOfDay(
        ZoneId.of( "Australia/Victoria" )
    )
)

详细信息

您的代码是可怕的遗留日期时间类( SimpleDateFormatGregorianCalendar )与取代它们的现代java.time类( LocalDate )的奇怪的混合。

具体来说,ZonedDateTime取代了GregorianCalendar

LocalDate只代表一个日期,没有一天的时间,也没有时区.相反,ZonedDateTime (和GregorianCalendar)代表一个时刻:日期、时间和时区。

LocalDate开始。

代码语言:javascript
复制
LocalDate ld = LocalDate.parse( "2017-10-16" ) ;

指定一天的时间。

代码语言:javascript
复制
LocalTime lt = LocalTime.of( 15 , 30 ) ;  // 3:30 PM.

指定您心目中的时区。

代码语言:javascript
复制
ZoneId z = ZoneId.of( "Australia/Victoria" ) ;

组合得到一个ZonedDateTime,一个时间点,一个时间线上的特定点。

代码语言:javascript
复制
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

或者,您可能希望使用一天中的第一分钟作为一天中的时间。不要把这个硬编码到00:00。某些区域中的某些日期从另一个时间开始,例如01:00:00。让java.time确定第一时刻。

代码语言:javascript
复制
ZonedDateTime zdt = ld.atStartOfDay( z ) ;  // Determine the first moment of the day on that date in that zone.

在世界协调时看到同样的时刻。提取一个Instant,它总是在UTC。

代码语言:javascript
复制
Instant instant = zdt.toInstant() ;

请注意,上述所有代码都来自java.time包类系列。

尽可能避免GregorianCalendar。但是,如果您必须与尚未更新为java.time的旧代码进行互操作,请转换。查看添加到旧类中的新的to…/from…转换方法。在本例中,请参见GregorianCalendar.from

代码语言:javascript
复制
GregorianCalendar gc = GregorianCalendar.from( zdt ) ;

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49667772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档