首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.util.Calendar没有正确更新时区

java.util.Calendar没有正确更新时区
EN

Stack Overflow用户
提问于 2022-09-30 18:01:00
回答 1查看 71关注 0票数 1

此方法的目标是获取utc日期,将其转换为指定的时区并返回DateTimeValue对象。但是,我们最近在使用此方法时,发现了一个与特定时区有关的错误。

代码语言:javascript
复制
private static DateTimeValue toDateTimeValue(Date endDate, TimeZone timeZone) {     
    Calendar cal = Calendar.getInstance();
    cal.setTime(endDate);
    cal.setTimeZone(timeZone);
    cal.set(Calendar.HOUR_OF_DAY, 23); // move to the end of the day
    cal.set(Calendar.MINUTE, 59);
    cal.set(Calendar.SECOND, 59);
    int year = cal.get(Calendar.YEAR);
    int month = cal.get(Calendar.MONTH) + 1;
    int day = cal.get(Calendar.DAY_OF_MONTH);  //ends up being 3 but should be 4
    int hour = cal.get(Calendar.HOUR_OF_DAY);
    int minute = cal.get(Calendar.MINUTE);
    int second = cal.get(Calendar.SECOND);

    return new DateTimeValueImpl(year, month, day, hour, minute, second);
}

说明错误的主要案例:

  • endDate值:010月3日21:00:00UTC 2022
  • 时区值:欧洲/赫尔辛基+3

在上面的方法中,日值最后是第3天,但是它应该是自10月03 21:00在UTC的第4天,实际上是在赫尔辛基时区的10月4日。

我用这个代码代替了那个方法做了一些进一步的测试。

代码语言:javascript
复制
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    String utcDate = sdf.format(endDate); 
    System.out.println(utcDate);   //2022-10-03 09:00:00

    sdf.setTimeZone(timeZone);
    String timeZoneDate = sdf.format(endDate);
    System.out.println(timeZoneDate);   //2022-10-04 12:00:00

这显示了正确的/预期的结果,但是这是一个字符串,我需要它作为一个DateTimeValue

为什么当我们将时区设置为赫尔辛基时,java.util.calendar不更新日期(日期)?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-30 18:36:03

java.util的日期-时间API已经过时,并且容易出错.建议完全停止使用它们,并切换到现代日期时间API

下面的演示演示了如何使用现代的日期时间API轻松、干净地进行/测试。

Demo

代码语言:javascript
复制
public class Main {
    public static void main(String[] args) {
        ZonedDateTime endDate = ZonedDateTime.of(LocalDate.of(2022, 10, 3), LocalTime.of(21, 0), ZoneOffset.UTC);
        ZonedDateTime zdtDesired = endDate.withZoneSameInstant(ZoneId.of("Europe/Helsinki"));
        System.out.println(zdtDesired);
        System.out.println(zdtDesired.getDayOfMonth());
    }
}

输出

代码语言:javascript
复制
2022-10-04T00:00+03:00[Europe/Helsinki]
4

如何将java.util.Date转换为ZonedDateTime

您可以将java.util.Date转换为Instant,后者可以转换为ZonedDateTime。这意味着您甚至不需要使用ZonedDateTime#withZoneSameInstant,如上面的演示所示。

代码语言:javascript
复制
public class Main {
    public static void main(String[] args) {
        // In your case, it will be endDate.toInstant()
        Instant instant = new Date().toInstant();
        ZonedDateTime zdtDesired = instant.atZone(ZoneId.of("Europe/Helsinki"));
        System.out.println(zdtDesired);
    }
}

输出

代码语言:javascript
复制
2022-09-30T21:57:50.487+03:00[Europe/Helsinki]

现代日期时间API上了解更多关于日期:时间的信息。

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

https://stackoverflow.com/questions/73912411

复制
相关文章

相似问题

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