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 IST
0取代。传统类和现代类都表示从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
中获得LocalDateTime
。LocalDateTime 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
。或者,如果我们只有上面看到的ZonedDateTime
,java.util.Date.from( zdt.toInstant() )
- 你通常不会在新代码中写这个。只有在需要与尚未更新到java.time的旧代码进行互操作的情况下,才能转换为旧代码。否则,请像瘟疫一样避免两个
Date
类。Calendar
、SimpleDateFormat
等同上
您的标题要求:
[将日期对象转换为指定时区日期对象]
我不明白你的意思。java.util.Date
类表示UTC中的一个时刻。它没有时区。
(实际上,有一个时区被它的代码所掩盖,但这个代码实际上是无关紧要的,它代表了遗留日期-时间类中的另一个糟糕的设计决策。)
你说:
JAVA中的时区日期对象8日期=3月31日星期五16:10:13 IST
不要被java.util.Date#toString
方法愚弄。不幸的是,该方法在生成文本时注入了JVM的当前默认时区。虽然是出于善意,但这造成了一种错误的错觉,即Date
在其意义上包括一个时区,而实际上它是"时区";在UTC中";(与UTC的偏移量为零)。