将日期字符串 (EST) 转换为 Java 日期 (UTC)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12919067/
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-10-31 10:47:23  来源:igfitidea点击:

Convert date string (EST) to Java Date (UTC)

javadatesimpledateformatdata-conversion

提问by user619804

I need some advice on this java method. The intent of this method is to take a string that represents a date - this string was created from a date in the EST time zone - and convert it to a java Date object in the UTC time zone.

我需要一些关于这个 java 方法的建议。此方法的目的是获取一个表示日期的字符串(该字符串是根据 EST 时区中的日期创建的)并将其转换为 UTC 时区中的 java Date 对象。

private Date buildValidationDate(String dateString) throws ParseException {
    System.out.println("dateString " + dateString);

    SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyy hh:mm a");
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));  
    dateFormat.setLenient(true);
    Date dt = dateFormat.parse(dateString);

    System.out.println("dt " + dt);

    return dt;
}

the problem I'm seeing is the value of dt seems to be off. For instance, if dateString is '10/16/2012 12:06 PM' - I'm expecting the value of dt (in UTC) to be something like 'Tuesday, October 16, 2012 4:06 PM'. Instead the value of dt is 'Tue Oct 16 07:06:00 CDT 2012'. This does not seem to be the correct UTC time.

我看到的问题是 dt 的值似乎已关闭。例如,如果 dateString 是 '10/16/2012 12:06 PM' - 我期望 dt 的值(UTC 时间)类似于“2012 年 10 月 16 日星期二下午 4:06”。相反,dt 的值是“Tue Oct 16 07:06:00 CDT 2012”。这似乎不是正确的 UTC 时间。

I appreciate any advice, I'm sorry if this seems to be an easy question I have a lot of trouble with Java dates. I'm not sure if I'm coding something incorrectly or if there is something wrong with my methodology. Thanks

我感谢任何建议,如果这似乎是一个简单的问题,我很抱歉我在 Java 日期方面遇到了很多麻烦。我不确定我的编码是否不正确,或者我的方法论是否有问题。谢谢

回答by Yogendra Singh

Your date is getting converted right. Its just printing value in your default timezone format as java.util.Dateis timezone independent. If you want timezone specific handling, please use java.util.Calendar.

您的日期正在正确转换。它只是以您的默认时区格式打印值,因为java.util.Date时区独立。如果您想要特定时区的处理,请使用java.util.Calendar.

回答by Basil Bourque

As the correct accepted answer by Singhsays, your Dateactually isin UTC but its toStringmethod confusingly applies the current default time zone while generating the string.

正如Singh 所接受正确答案所说,您Date实际上在 UTC 中,但它的toString方法在生成字符串时混淆了当前的默认时区。

ISO 8601

ISO 8601

Avoid such formats as 10/16/2012 12:06 PMfor date-time values. When serializing to text, use the ISO 8601formats defined as a standard for this very purpose.

避免诸如10/16/2012 12:06 PM日期时间值之类的格式。序列化为文本时,请使用为此目的定义为标准的ISO 8601格式。

java.time

时间

I'm sorry if this seems to be an easy question I have a lot of trouble with Java dates

如果这似乎是一个简单的问题,我很抱歉我在 Java 日期方面遇到了很多麻烦

It's not you; it's the classes. The old legacy date-time classes were a valiant industry-leading effort at handling date-time. But they proved to be ill-conceived, poorly-designed, very confusing, and troublesome. Now supplanted by the java.time classes – a giganticimprovement.

不是你;这是课程。旧的遗留日期时间类是处理日期时间方面的一项勇敢的行业领先的努力。但事实证明,它们构思不周、设计不当、非常混乱且麻烦。现在被 java.time 类取代 - 一个巨大的改进。

Avoid this troublesome old java.util.Dateclass entirely. Instead use Instantin its place.

java.util.Date完全避免这个麻烦的老类。而是Instant在它的位置使用。

Instant

Instant

The Instantclass represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).

Instant级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。

Get the current moment.

获取当前时刻。

Instant instant = Instant.now();

You can convert a Date to its modern replacement by calling one of the new conversion methods added to the old date-time classes. Just call toInstant, quite easy.

您可以通过调用添加到旧日期时间类的新转换方法之一将日期转换为其现代替代品。只需调用 toInstant,非常简单。

Instant instant = myJavaUtilDate.toInstant(); 

The java.time classes use ISO 8601 formats by default when generating strings. Just call toStringto get a clear representation of the value within the object.

java.time 类在生成字符串时默认使用 ISO 8601 格式。只需调用toString即可获得对象内值的清晰表示。

String output = instant.toString();

2016-12-23T01:33:09.731Z

2016-12-23T01:33:09.731Z

Parsing

解析

To parse your input string, define a formatting pattern to match. The pattern codes are similar to that of SimpleDateFormatbut not exactly the same. So be sure to study the doc carefully.

要解析输入字符串,请定义要匹配的格式模式。模式代码类似于SimpleDateFormat但不完全相同。所以一定要仔细研究文档。

String input = "10/16/2012 12:06 PM" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu hh:mm a" );

Your input lacks any clue about offset-from-UTC or time zone. So we must parse as a LocalDateTime. Lacking any offset or zone, a LocalDateTimeis only a vague idea about possible moments but does notrepresent a point on the timeline.

您的输入缺少关于 UTC 偏移量或时区的任何线索。所以我们必须解析为LocalDateTime. 缺乏任何偏移或区,LocalDateTime大约只有可能瞬间一个模糊的概念,但并不能代表在时间轴上的一个点。

LocalDateTime ldt = LocalDateTime.parse( input , f );

ldt.toString(): 2012-10-16T12:06

ldt.toString(): 2012-10-16T12:06

The Question claims this was meant for “EST time zone”. So we need to apply a time zone, a ZoneId, to our LocalDateTimeto get a ZonedDateTime.

问题声称这是针对“EST 时区”的。因此,我们需要将时区 a 应用ZoneId到我们LocalDateTimeZonedDateTime.

Specify a proper time zone namein the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as ESTor ISTas they are nottrue time zones, not standardized, and not even unique(!).

以、、 或等格式指定正确的时区名称。永远不要使用 3-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/regionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST

Perhaps by ESTyou meant the time zones used across much of the east coast of the United States and Canada. I will arbitrarily choose America/New_York.

也许EST您指的是美国和加拿大东海岸大部分地区使用的时区。我会随意选择America/New_York

ZoneId z = ZoneId.of( "America/New_York" );
ZonedDateTime zdt = ldt.atZone( z );

zdt.toString(): 2012-10-16T12:06-04:00[America/New_York]

zdt.toString(): 2012-10-16T12:06-04:00[美国/纽约]

To get to UTC, simply extract a Instant. You can think of this conceptually as:

要获得 UTC,只需提取一个Instant. 您可以在概念上将其视为:

ZonedDateTime = ( Instant + ZoneId )

ZonedDateTime = ( 即时 + ZoneId )

Instant instant = zdt.toInstant();

instant.toString(): 2012-10-16T16:06:00Z

Instant.toString(): 2012-10-16T16:06:00Z