java Sping Boot 应用程序中传入时间戳的不必要时区转换

iyfjxgzm  于 2023-03-28  发布在  Java
关注(0)|答案(2)|浏览(163)

我试图在我的spring Boot 应用程序中格式化传入的时间戳,但我编写的代码更改了传入时间戳的时区。它自己添加了5:30小时,这是我不想要的。
以下是我的片段:

String startTime = searchParams.getDeploymentStartDate();
System.out.println("startTime from req body in utc:"+startTime);
DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd' HH:mm:ss"
             , Locale.ENGLISH).ISO_OFFSET_DATE_TIME;
Date startDate = Date.from(ZonedDateTime.parse(startTime, targetFormatter).toInstant());
System.out.println("startDate converted to desired format in IST:"+startDate);

实际产量:

startTime from req body in utc:2023-03-22T11:27:04Z
startDate converted to desired format in IST:Wed Mar 22 16:57:04 IST 2023

预期输出:

startTime from req body in utc:2023-03-22T11:27:04Z
startDate converted to desired format in IST:Wed Mar 22 11:27:04 IST 2023

请帮助我找到一种方法来转换格式不转换时区。

vohkndzv

vohkndzv1#

tldr

java.util.Date juDate = 
    Date                                   // Legacy class. Best to avoid wherever possible. Represents a moment as seen in UTC (zero offset) but it’s poorly designed `toString` applies the JVM’s current default time zone while generating text. 
    .from(                                 // A new method on old legacy class to bridge between legacy and modern classes. 
        java.time.Instant                  // The modern class for representing a moment as seen with an offset of zero. 
        .parse( "2023-03-22T11:27:04Z" )   // Parsing text in standard ISO 8601 format. 
    )
;

最好避免遗留的有严重缺陷的日期-时间类java.util.Date。只使用 java.time 类。

Instant
.parse( "2023-03-22T11:27:04Z" )  // Returns an `Instant` object. 
.atZone(                          // Adjust from UTC to a specific time zone. 
    ZoneId.of( "Asia/Kolkata" )   // Returns a `ZoneId` object. 
)                                 // Returns a `ZonedDateTime` object.

格式错误,也不需要

2023-03-22T11:27:04Z
DateTimeFormatter.ofPattern(“yyyy-MM-dd' HH:mm:ss”,Locale.英语).ISO_OFFSET_DATE_TIME;
您用于解析的格式设置模式与输入数据不匹配。输入末尾的Z表示日期和时间表示与UTC的偏移量为零小时-分钟-秒的时刻。您的格式化程序忽略了这一关键部分。
而且,格式化模式需要其他修复:一个杂散的单引号,以及一个空格,它应该是T
此外,根本不需要定义这种格式模式。您的输入文本恰好符合ISO 8601格式。java.time 类在解析/生成文本时默认使用ISO 8601格式。

Instant instant = Instant.parse( "2023-03-22T11:27:04Z" ) ;

避免遗留日期时间类型

日期开始日期=...
与Java捆绑在一起的两个Date类都有严重的缺陷,它们是由不了解日期-时间处理的人设计的。避免使用这些类。仅使用JSR 310中定义的 java.time 类。
如果您必须使用遗留类的对象来与尚未更新到 java.time 的旧代码进行互操作,请使用添加到旧类的新方法进行转换。

java.util.Date juDate = java.util.Date.from( instant ) ;

请注意:java.util.DatetoString方法在生成结果文本时应用了JVM的当前时区。这个设计缺陷可能会增加您的困惑。java.util.Date实际上表示与UTC的偏移为零小时-分钟-秒的时刻。

调整时区

Instant表示从UTC偏移0小时-分钟-秒的时刻。
如果您想通过特定时区的透镜查看该时刻,请应用ZoneId以获得ZonedDateTime

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;  // Same moment, different wall-clock time.
fkvaft9z

fkvaft9z2#

请不要使用java.util.Date,因为它的设计很差,将来可能会被弃用。
使用java.time.LocalDateTimejava.time.ZonedDateTime

更新日期:

如果你只想在时区变化时保持相同的时间,你必须使用ZonedDateTime.withZoneSameLocal(ZoneId zone)
来自ZonedDateTime.withZoneSameLocal(ZoneId zone)JDK 8文档:
返回此日期-时间的一个具有不同时区的副本,如果可能,保留本地日期-时间。此方法更改时区并保留本地日期-时间。
因此,将代码更新为(不使用java.util.Date):

String startTime = searchParams.getDeploymentStartDate();
System.out.println("startTime from req body in utc:" + startTime);
ZonedDateTime ist = ZonedDateTime.parse(startTime)
                .withZoneSameLocal(ZoneId.of("Asia/Kolkata"));
System.out.println("startDate converted to desired format in IST:" 
             + ist.format(DateTimeFormatter.ofPattern("E MMM dd HH:mm:ss z u")));

输出:

startTime from req body in utc:2023-03-22T11:27:04Z
startDate converted to desired format in IST:Wed Mar 22 11:27:04 IST 2023

**注意:**如果您希望时间戳处于不同的时区,则只需在ZoneId.of(...)中传递该时区即可

我提供了official doc支持的ZoneIds列表:

EST - -05:00
HST - -10:00
MST - -07:00
ACT - Australia/Darwin
AET - Australia/Sydney
AGT - America/Argentina/Buenos_Aires
ART - Africa/Cairo
AST - America/Anchorage
BET - America/Sao_Paulo
BST - Asia/Dhaka
CAT - Africa/Harare
CNT - America/St_Johns
CST - America/Chicago
CTT - Asia/Shanghai
EAT - Africa/Addis_Ababa
ECT - Europe/Paris
IET - America/Indiana/Indianapolis
IST - Asia/Kolkata
JST - Asia/Tokyo
MIT - Pacific/Apia
NET - Asia/Yerevan
NST - Pacific/Auckland
PLT - Asia/Karachi
PNT - America/Phoenix
PRT - America/Puerto_Rico
PST - America/Los_Angeles
SST - Pacific/Guadalcanal
VST - Asia/Ho_Chi_Minh

相关问题