简体   繁体   English

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

[英]Convert date string (EST) to Java Date (UTC)

I need some advice on this java method. 我需要有关此java方法的一些建议。 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. 此方法的目的是采用表示日期的字符串-该字符串是从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. 我看到的问题是dt的值似乎已关闭。 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'. 例如,如果dateString为'10 / 16/2012 12:06 PM'-我期望dt(以UTC为单位)的值类似于“ 2012年10月16日,星期二,下午4:06”。 Instead the value of dt is 'Tue Oct 16 07:06:00 CDT 2012'. 而是dt的值为“ 2012年10月16日星期二CDT 2012”。 This does not seem to be the correct UTC time. 这似乎不是正确的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. 我感谢任何建议,如果这似乎是一个简单的问题,我对Java日期有很多麻烦,感到抱歉。 I'm not sure if I'm coding something incorrectly or if there is something wrong with my methodology. 我不确定我的编码是否错误或我的方法是否有问题。 Thanks 谢谢

Your date is getting converted right . 您的日期已正确转换 Its just printing value in your default timezone format as java.util.Date is timezone independent. 它仅以默认时区格式(如java.util.Date )打印值是与时区无关的。 If you want timezone specific handling, please use java.util.Calendar . 如果要进行时区特定的处理,请使用java.util.Calendar

As the correct accepted answer by Singh says, your Date actually is in UTC but its toString method 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 PM for date-time values. 避免使用诸如10/16/2012 12:06 PM这样的格式作为日期时间值。 When serializing to text, use the ISO 8601 formats defined as a standard for this very purpose. 为此,序列化为文本时,请使用定义为标准的ISO 8601格式。

java.time 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 gigantic improvement. 现在已被java.time类所取代–一项巨大的改进。

Avoid this troublesome old java.util.Date class entirely. 完全避免使用麻烦的旧java.util.Date类。 Instead use Instant in its place. 而是在其位置使用Instant

Instant

The Instant class represents a moment on the timeline in UTC with 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. 只需调用即时即可,非常简单。

Instant instant = myJavaUtilDate.toInstant(); 

The java.time classes use ISO 8601 formats by default when generating strings. 生成字符串时,java.time类默认使用ISO 8601格式。 Just call toString to get a clear representation of the value within the object. 只需调用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 SimpleDateFormat but not exactly the same. 模式代码与SimpleDateFormat相似,但不完全相同。 So be sure to study the doc carefully. 因此,请务必仔细研究文档。

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. 您的输入缺少有关UTC偏移量或时区的任何线索。 So we must parse as a LocalDateTime . 因此,我们必须将其解析为LocalDateTime Lacking any offset or zone, a LocalDateTime is only a vague idea about possible moments but does not represent a point on the timeline. 缺少任何偏移量或区域, 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”. 该课题声称这是针对“ EST时区”的。 So we need to apply a time zone, a ZoneId , to our LocalDateTime to get a ZonedDateTime . 因此,我们需要将一个时区ZoneId应用于我们的LocalDateTime以获得ZonedDateTime

Specify a proper time zone name in the format of continent/region , such as America/Montreal , Africa/Casablanca , or Pacific/Auckland . continent/region的格式指定正确的时区名称 ,例如America/MontrealAfrica/CasablancaPacific/Auckland Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!). 切勿使用ESTIST等3-4个字母的缩写,因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。

Perhaps by EST you meant the time zones used across much of the east coast of the United States and Canada. EST可能是指美国和加拿大东海岸大部分地区使用的时区。 I will arbitrarily choose America/New_York . 我将随意选择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 . 要进入UTC,只需提取Instant You can think of this conceptually as: 您可以在概念上将其视为:

ZonedDateTime = ( Instant + ZoneId ) ZonedDateTime =(即时+ ZoneId)

Instant instant = zdt.toInstant();

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM