Java 使用 Java 8 时间库将 UTC 转换为 PDT/PST

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38447216/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:24:53  来源:igfitidea点击:

Java Convert UTC to PDT/PST with Java 8 time library

javaspringtimejava-8

提问by Minjun Yu

I would like to use built-in Java 8 time library to convert from UTC to PST/PDT.

我想使用内置的 Java 8 时间库从 UTC 转换为 PST/PDT。

I am writing a program that talks to an API that returns a list of objects according to a time frame. E.g. objects created/modified from a certain date time.

我正在编写一个与 API 对话的程序,该 API 根据时间范围返回对象列表。例如,从某个日期时间创建/修改的对象。

My program uses LocalDateTimeand the value is always in UTC.
The API accepts PST/PDT.
"The time zone represented in all API responses is PST/PDT. Similarly, CompanyNameasks that you make all time zone convertions and submit any dateTime requests in PST/PDT." -- quote from API documentation

我的程序使用LocalDateTime并且该值始终为 UTC。
API 接受 PST/PDT。
“所有 API 响应中表示的时区是 PST/PDT。同样,CompanyName要求您进行所有时区转换并提交 PST/PDT 中的任何 dateTime 请求。” -- 引用自 API 文档

I think what they mean by PST/PDT is that the time value should reflect whether it is in day-light-saving or not.
E.g. the time value changes twice a year.

我认为他们所说的 PST/PDT 的意思是时间值应该反映它是否处于夏令时。
例如,时间值一年变化两次。

If that is the case, is there a practical/conventional way to convert from UTC to PST/PDT without manually figuring out if it is in day-light-saving time by looking at the exact date?

如果是这种情况,是否有一种实用/传统的方法可以将 UTC 转换为 PST/PDT,而无需通过查看确切日期手动确定是否处于夏令时?

UPDATE

更新

The API returns the objects in JSON format.
My app send a request to their API with a query parameter api.com/objects?modified-date=${yyyy-MM-dd hh:mm:ss}

API 以 JSON 格式返回对象。
我的应用程序使用查询参数向他们的 API 发送请求api.com/objects?modified-date=${yyyy-MM-dd hh:mm:ss}

I am currently using the following method to do the conversion:

我目前正在使用以下方法进行转换:

public static String toSsTimeStr(LocalDateTime utcTime){
    String pattern  = "yyyy-MM-dd HH:mm:ss";

    ZonedDateTime zdt = ZonedDateTime.ofInstant(utcTime, ZoneOffset.UTC, ZoneId.of("America/Los_Angeles"));

    String timeStr = zdt.format(DateTimeFormatter.ofPattern(pattern));
    return timeStr;
}  

Will this help adjust the day-light-saving time, in other words, return the correct value according to the current day-light-saving-time status for me?

这是否有助于调整夏令时,即根据当前的夏令时状态为我返回正确的值?

Thank you.

谢谢你。

回答by Basil Bourque

My program uses LocalDateTime and the value is always in UTC.

我的程序使用 LocalDateTime 并且该值始终采用 UTC。

A LocalDateTimehas no time zone at all, so it is notin UTC.

ALocalDateTime根本没有时区,所以它不是UTC。

For a moment in UTC, use the Instantclass. This represents a moment on the timeline in up to nanosecond resolution.

在 UTC 中,使用Instant类。这代表时间线上的一个时刻,分辨率高达纳秒。

Instant now = Instant.now();

To adjust into a time zone, apply a ZoneIdto get a ZonedDateTime.

要调整到时区,请应用 aZoneId以获取ZonedDateTime.

Never use the 3-4 letter abbreviations like PST& PDTso commonly seen in the mainstream media. They are not real time zones, not standardized, and are not even unique(!). Use proper time zone namesin continent/regionformat.

切勿使用主流媒体中常见的 3-4 个字母缩写,例如PST& PDT。它们不是实时时区,不是标准化的,甚至不是唯一的(!)。在格式中使用正确的时区名称continent/region

ZoneId zoneId = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime zdt = instant.atZone( zoneId );

It sounds like your data sink has the poor design of taking an input of a string that represents a date-time value assumedto be in America/Los_Angelestime zone but lacking any indicator (no offset-from-UTC, no time zone).

听起来您的数据接收器的设计很糟糕,无法输入一个字符串,该字符串表示假定America/Los_Angeles时区但缺少任何指示符(没有与 UTC 的偏移量,没有时区)的日期时间值。

To get such a string, lacking any offset or zone, use the predefined DateTimeFormatternamed ISO_LOCAL_DATE_TIME. You will get a string in standard ISO 8601format like this: 2011-12-03T10:15:30.

要获得这样一个没有任何偏移量或区域的字符串,请使用预定义的DateTimeFormatter命名ISO_LOCAL_DATE_TIME. 你会得到在标准的字符串ISO 8601的格式如下:2011-12-03T10:15:30

String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME );

Your data sink omits the Tfrom the middle, so replace with SPACE.

您的数据接收器T从中间省略了,因此请替换为 SPACE。

output = output.replace( `T` , " " );

If your data sink expects only whole seconds, you can truncate any fractional second from your date-time value.

如果您的数据接收器只需要整秒,您可以从日期时间值中截断任何小数秒。

zdt = zdt.truncatedTo( ChronoUnit.SECONDS );

Going the other direction, from string to object, define a formatter, parse as a LocalDateTimeand apply the assumed time zone.

从另一个方向,从字符串到对象,定义一个格式化程序,解析为 aLocalDateTime并应用假定的时区。

String input = "2011-12-03 10:15:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss" );
LocalDateTime ldt = LocalDateTime.parse( input , formatter );
ZoneId zoneId = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime zdt = ldt.atZone( zoneId );