时区日期转换[将日期对象转换为指定的时区日期对象]


My approach :
// initailize date object
Date date = new Date();
// get time zone
ZoneId zoneId = ZoneId.of("Asia/Dubai");
// create zonedDateTime object
ZonedDateTime zdt = ZonedDateTime.ofInstant(date.toInstant(), zoneId);
// instant of zonedDateTime
Instant instant = zdt.toInstant();
// convert instant to specified zone
instant.atZone(zoneId);
// Get Local Date Time Object
LocalDateTime ldt = LocalDateTime.ofInstant(instant,zoneId);
//Convert it back to Date Object
Date dateFinal = java.util.Date.from(Instant.from(ldt.atZone(zoneId)));

有人能帮我在Java 8中转换时区日期对象吗CCD_ 1。现在我需要将此日期转换为任何给定的时区日期对象

期望结果:

Date resultDate = Fri Mar 31 14:40:13 GST

基本上我在这里使用(亚洲/迪拜)时区

但我的结果是:2023-03-31T16:10:13.854+0530。我只得到IST的结果。它没有被转换为(亚洲/迪拜)。

我已经提到了我尝试过的所有方法。

tl;dr

核心概念:java.util.Date没有时区Date#toString方法取决于您。

如果交给遗留的java.util.Date对象,请立即转换为java.time.Instant

Instant instant = myJavaUtilDate.toInstant() ;

然后应用您想要的时区。

ZonedDateTime zdt = instant.atZone( ZoneId.of( "Asia/Dubai" ) ) ;

仅使用java.time

您的日期时间处理应该只涉及java.time类。

该包之外的日期-时间类现在是遗留的,在糟糕的设计中存在严重缺陷。JSR310中的遗留类被用java 8+实现的java.time所取代。

你说:

// initailize date object
Date date = new Date();

你是说java.util.Date还是java.sql.Date?两者都是遗产。

  • 第一个被Date date = Fri Mar 31 16:10:13 IST0取代。传统类和现代类都表示从UTC偏移0小时-分-秒的时刻
  • 第二个被java.time.LocalDate取代。遗留类假装只表示日期,但由于设计错误,它实际上包含一天中的时间和零偏移的假设。相比之下,现代课程真正代表的只是一个日期,没有一天中的时间,也没有时区或偏移量

请使用以下代码:

Instant instant = Instant.now() ;  // Capture the current moment as seen in UTC (zero offset).

你说:

// get time zone
ZoneId zoneId = ZoneId.of("Asia/Dubai");

很好。ZoneId是表示时区的现代方式。Continent/Region中的Asia/Dubai是对实时区域的正确命名。

你说:

// create zonedDateTime object
ZonedDateTime zdt = ZonedDateTime.ofInstant(date.toInstant(), zoneId);

使用上面看到的Instant对象,使用以下代码:

ZonedDateTime zdt = instant.atZone( zoneId ) ;

CCD_ 16&zdt在这里表示相同的同时时刻,时间线上的相同点。但后者是通过特定地区的人们使用的挂钟时间来观察的。

你说:

// instant of zonedDateTime
Instant instant = zdt.toInstant();

可以,您可以从ZonedDateTime中提取Instant。但是这个代码在这里是不必要的,因为我们已经实例化了一个Instant对象来捕捉当前时刻。

你说:

// convert instant to specified zone
instant.atZone(zoneId);

这里的问题是Instant对象和所有java.time对象一样,是不可变的。您可以在创建Instant对象后更改("mutate")该对象的内容。那一刻被永远冻结了。

此外,调用Instant#atZone返回一个新的ZonedDateTime对象。我们在前面的代码中看到了这一点。上面显示的代码会忽略atZone返回的新ZonedDateTime对象。

你说:

// Get Local Date Time Object
LocalDateTime ldt = LocalDateTime.ofInstant(instant,zoneId);

这里有两个问题:

  • 您可以更容易地从上面实例化的ZonedDateTime中获得LocalDateTimeLocalDateTime ldt = zdt.toLocalDateTime() ;
  • 您可能没有意识到,在创建LocalDateTime时,您正在丢弃有价值的信息:时区。所以你只剩下一个日期和一天中的某个时间。但这样的价值观本质上是模糊的。例如,如果是今年1月23日的中午,我们不知道你是指日本东京的中午、法国图卢兹的中午还是美国俄亥俄州托莱多的中午——三个相隔几个小时的截然不同的时刻

提示:如果您还没有完全了解日期时间处理,请避免使用LocalDateTime。在大多数商业情况下,我们通常关心一个时刻,时间线上的一个特定点。LocalDateTime不适合这种情况。

你说:

//Convert it back to Date Object
Date dateFinal = java.util.Date.from(Instant.from(ldt.atZone(zoneId)));

这里有两个问题:

  • 您可以更容易地编写java.util.Date.from( instant ),因为我们手头已经有了Instant。或者,如果我们只有上面看到的ZonedDateTimejava.util.Date.from( zdt.toInstant() )
  • 你通常不会在新代码中写这个。只有在需要与尚未更新到java.time的旧代码进行互操作的情况下,才能转换为旧代码。否则,请像瘟疫一样避免两个Date类。CalendarSimpleDateFormat等同上

您的标题要求:

[将日期对象转换为指定时区日期对象]

我不明白你的意思。java.util.Date类表示UTC中的一个时刻。它没有时区。

(实际上,有一个时区被它的代码所掩盖,但这个代码实际上是无关紧要的,它代表了遗留日期-时间类中的另一个糟糕的设计决策。)

你说:

JAVA中的时区日期对象8日期=3月31日星期五16:10:13 IST

不要被java.util.Date#toString方法愚弄。不幸的是,该方法在生成文本时注入了JVM的当前默认时区。虽然是出于善意,但这造成了一种错误的错觉,即Date在其意义上包括一个时区,而实际上它是"时区";在UTC中";(与UTC的偏移量为零)。

相关内容

  • 没有找到相关文章

最新更新