【问题标题】:Convert string to appropriate date with timezone java使用时区java将字符串转换为适当的日期
【发布时间】:2014-07-03 13:14:30
【问题描述】:

我的时区有日期,我想将其转换为另一个时区,例如我有日期“2013 年 3 月 15 日下午 3:01:53”,它位于时区“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);

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

编辑:

我正在使用 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();
    }

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

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

现在,我告诉日历我想要“格林威治标准时间”的日期

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

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

输出:

Fri Mar 15 03:01:53 CDT 2013

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

【问题讨论】:

标签: java date timezone


【解决方案1】:

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

// 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);

输出:2013 年 3 月 15 日 04:01:53 PM -05:00

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

hh:mm:ss aaa 

通过

HH:mm:ss

在打印格式模式中。


评论问题的其他方面:

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

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

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

【讨论】:

  • 现在,如果我想要字符串中的 Date 对象,当我在解析 Date 对象后打印它时会显示我的本地时区和日期时间
  • @minu Date from String = 使用解析格式,打印 Date = 在 printFormat 上设置时区(本地时区使用 TimeZone.getDefault())并定义模式(你也应该避免使用Date.toString(),因为后者只是使用基于系统时区的预定义格式——仅对调试有用)。
  • 我使用 SimpleDateFormat 的解析来获取日期对象 String newDateString = printFormat.format(dt); try { dt = printFormat.parse(newDateString); }catch (ParseException e) { e.printStackTrace(); } System.out.println(dt); 它显示本地时间,我也只是返回 dt 并尝试将它存储在数据库中它显示时间'00:00:00'
  • @minu System.out.println(dt) 使用 Date.toString()。请避免它。而是使用专用的打印格式并在其上指定模式、区域设置和时区,以获得您想要的输出。关于时间 00:00:00:可能您在 db 中有一个 SQL-DATE-column,它使时间部分无效 - 另请参阅适配器 jdbc 类java.sql.Date。干杯。
【解决方案2】:

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

java.time

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

将您的输入字符串解析为 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

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

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

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

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

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

生成字符串

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

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

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

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

2013-03-15 16:01:53


关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

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

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

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    猜你喜欢
    • 2012-03-21
    • 2020-09-24
    • 2011-05-11
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    相关资源
    最近更新 更多