使用时区java将字符串转换为适当的日期

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

Convert string to appropriate date with timezone java

javadatetimezone

提问by minu

I am Having Date with it's timezone, I want to convert it to another Timezone, E.g. I have Date '3/15/2013 3:01:53 PM' which is in TimeZone 'GMT-06:00'. I want to convert this in 'GMT-05:00' timezone. I have search lot, and I am confuse about How actually Date is working. How to Apply timezone to date. I have try with SimpleDateFormat, Calender and also with offset.

我有它的时区日期,我想将它转换为另一个时区,例如我有日期'3/15/2013 3:01:53 PM',它在时区'GMT-06:00'。我想在“GMT-05:00”时区转换它。我有很多搜索,但我对 Date 的实际工作方式感到困惑。如何将时区应用到日期。我尝试使用 SimpleDateFormat、Calender 和偏移量。

DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss aaa XXX");
df.setTimeZone(TimeZone.getTimeZone("GMT")); 
Date dt = null;
try {
    dt = df.parse("3/15/2013 3:01:53 PM -06:00");
} catch (ParseException e) {
    e.printStackTrace();
} 
String newDateString = df.format(dt);
System.out.println(newDateString);

It returns output 03/15/2013 09:01:53 AM Z. I guess it should be 03/15/2013 09:01:53 PM Z, because time in 'GMT-06:00' timezone, so it should be HH+6 to get time in GMT. I want Date in "yyyy-MM-dd HH:mm:ss" format where HH is in 24 hour.Please Help me with example. Thanks in advance.

它返回输出 03/15/2013 09:01:53 AM Z。我想应该是 03/15/2013 09:01:53 PM Z,因为时间在“GMT-06:00”时区,所以应该是 HH+6 以获取格林威治标准时间的时间。我想要“yyyy-MM-dd HH:mm:ss”格式的日期,其中 HH 是 24 小时。请帮我举例。提前致谢。

EDIT :

编辑 :

I am converting the string into date using SimpleDateFormat

我正在使用 SimpleDateFormat 将字符串转换为日期

DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss aaa");
    Date dt = null;
    try {
        dt = df.parse("3/15/2013 3:01:53 PM");
    } catch (ParseException e) {
        e.printStackTrace();
    }

Now, as you say, I specify to Calendar that my date is in 'GMT-06:00' timezone and set my date,

现在,正如您所说,我向日历指定我的日期在“GMT-06:00”时区并设置我的日期,

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-6"));
cal.setTime(dt);

Now, I am telling calendar that I want date in 'GMT'

现在,我告诉日历我想要“GMT”中的日期

cal.setTimeZone (TimeZone.getTimeZone("GMT"));

System.out.println(cal.getTime());

System.out.println(cal.getTime());

OutPut:

输出:

Fri Mar 15 03:01:53 CDT 2013

Please know me if i am going wrong.

如果我出错了,请知道我。

采纳答案by Meno Hochschild

You need TWO format objects, one for parsing and another one for printing because you use two different timezones, see here:

您需要两个格式对象,一个用于解析,另一个用于打印,因为您使用两个不同的时区,请参见此处:

// h instead of H  because of AM/PM-format
DateFormat parseFormat = new SimpleDateFormat("M/dd/yyyy hh:mm:ss aaa XXX"); 
Date dt = null;
try {
  dt = parseFormat.parse("3/15/2013 3:01:53 PM -06:00");
}catch (ParseException e) {
  e.printStackTrace();
} 

DateFormat printFormat = new SimpleDateFormat("M/dd/yyyy hh:mm:ss aaa XXX"); 
printFormat.setTimeZone(TimeZone.getTimeZone("GMT-05")); 
String newDateString = printFormat.format(dt);
System.out.println(newDateString);

Output: 3/15/2013 04:01:53 PM -05:00

输出:3/15/2013 04:01:53 PM -05:00

If you want HH:mm:ss (24-hour-format) then you just replace

如果你想要 HH:mm:ss(24 小时格式),那么你只需替换

hh:mm:ss aaa 

by

经过

HH:mm:ss

in printFormat-pattern.

在打印格式模式中。



Comment on other aspects of question:

评论问题的其他方面:

A java.util.Datehas no internal timezone and always refers to UTC by spec. You cannot change it inside this object. A timezone conversion is possible for the formatted string, however as demonstrated in my code example (you wanted to convert to zone GMT-05).

Ajava.util.Date没有内部时区,并且总是按照规范引用 UTC。您不能在此对象内更改它。格式化字符串可以进行时区转换,但如我的代码示例所示(您想转换为区域 GMT-05)。

The question then switches to the new requirement to print the Date-object in ISO-format using UTC timezone (symbol Z). This can be done in formatting by replacing the pattern with "yyyy-MM-dd'T'HH:mm:ssXXX" and explicitly setting the timezone of printFormat to GMT+00. You should clarify what you really want as formatted output.

然后问题切换到Date使用 UTC 时区(符号 Z)以 ISO 格式打印-object的新要求。这可以通过用“yyyy-MM-dd'T'HH:mm:ssXXX”替换模式并将printFormat的时区显式设置为GMT+00来完成。您应该澄清您真正想要的格式化输出。

About java.util.GregorianCalendar: Setting the timezone here is changing the calendar-object in a programmatical way, so it affects method calls like calendar.get(Calendar.HOUR_OF_DAY). This has nothing to do with formatting however!

关于java.util.GregorianCalendar:在此处设置时区是以编程方式更改日历对象,因此它会影响诸如calendar.get(Calendar.HOUR_OF_DAY). 然而,这与格式无关!

回答by Basil Bourque

tl;dr

tl;博士

OffsetDateTime.parse( 
    "3/15/2013 3:01:53 PM -06:00" , 
    DateTimeFormatter.ofPattern( "M/d/yyyy H:mm:ss a XXX" )
).withOffsetSameInstant( 
    ZoneOffset.of( -5 , 0 ) 
)

2013-03-15T15:01:53-06:00

2013-03-15T15:01:53-06:00

java.time

时间

The Answer by Hochschildis correct but uses outdated classes. The troublesome old date-time classes bundled with the earliest versions of Java have been supplanted by the modern java.timeclasses.

Hochschild答案是正确的,但使用了过时的课程。与最早版本的 Java 捆绑在一起的麻烦的旧日期时间类已被现代java.time类所取代。

Parse your input string as a OffsetDateTimeas it contains an offset-from-UTC but not a time zone.

将您的输入字符串解析为 a,OffsetDateTime因为它包含与 UTC 的偏移量但不包含时区。

String input = "3/15/2013 3:01:53 PM -06:00";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/yyyy h:mm:ss a XXX" );
OffsetDateTime odt = OffsetDateTime.parse( input , f );

odt.toString(): 2013-03-15T15:01:53-06:00

odt.toString(): 2013-03-15T15:01:53-06:00

Tip: Save yourself some hassle and use the ISO 8601 formats when exchanging date-time data as text. The java.time classes use these standard formats by default when parsing/generating strings.

提示:将日期时间数据作为文本交换时,可以省去一些麻烦并使用 ISO 8601 格式。java.time 类在解析/生成字符串时默认使用这些标准格式。

Apparently you want to see the same moment as viewed by the people elsewhere using a different offset-from-UTC.

显然,您希望看到与其他地方的人使用不同的 UTC 偏移量所看到的同一时刻。

ZoneOffset offset = ZoneOffset.of( -5 , 0 ) ;
OffsetDateTime odt2 = odt.withOffsetSameInstant( offset ) ;

We see the offset changes from 6 to 5, and the hour-of-day changes accordingly from 15 to 16. Same simultaneous moment, different wall-clock time.

我们看到偏移量从 6 变为 5,一天中的小时相应地从 15 变为 16。同一时刻,不同的挂钟时间。

odt2.toString(): 2013-03-15T16:01:53-05:00

odt2.toString(): 2013-03-15T16:01:53-05:00

Generating strings

生成字符串

I want Date in "yyyy-MM-dd HH:mm:ss" format where HH is in 24 hour.

我想要“yyyy-MM-dd HH:mm:ss”格式的日期,其中 HH 为 24 小时。

I suggest you always include some indication of the offset or zoneunless your are absolutely certain the user understands from the greater context.

我建议你总是包含一些偏移或区域的指示,除非你绝对确定用户从更大的上下文中理解。

Your format is nearly in standard ISO 8601 format. You could define your own formatting pattern, but I would just do string manipulation to replace the Tin the middle with a SPACE.

您的格式几乎是标准的 ISO 8601 格式。您可以定义自己的格式模式,但我只会进行字符串操作以T将中间的替换为空格。

String output = odt2.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ).replace( "T" , " " ) ;

2013-03-15 16:01:53

2013-03-15 16:01:53



About java.time

关于java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

With a JDBC drivercomplying with JDBC 4.2or later, you may exchange java.timeobjects directly with your database. No need for strings or java.sql.* classes.

使用符合JDBC 4.2或更高版本的JDBC 驱动程序,您可以直接与您的数据库交换java.time对象。不需要字符串或 java.sql.* 类。

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多