2017-09-01 69 views
0

我想UTC转换为本地时间,的Java UTC到当地时间不灵

下面是我使用的代码,

public static String utcToLocalDateFormat(String dateString) { 

     Log.i("DateFormat", "utcToLocal:Before===>" + dateString); 

     String formattedDate = null; 
     if (dateString != null) { 
      DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
      dateFormat.setTimeZone(TimeZone.getDefault()); 
      Date date = null; 
      try { 

       Log.i("DateFormat", "getTimeZone===>" +dateFormat.getTimeZone()); 
       date = dateFormat.parse(dateString); 
       System.out.println(date); 
      } catch (ParseException e) { 
       e.printStackTrace(); 
      } 
      formattedDate = dateFormat.format(date); 
      Log.i("DateFormat", "utcToLocal:After===>" + formattedDate); 

     } 
     return formattedDate; 
    } 

但问题是,之前和之后的时区转换时间它不会转换为UTC到当地时间。 任何帮助表示赞赏。

以下是我的输入: 1)2017年8月31日20时四十分59秒 2)2017年9月1日11:16:24.024

以下是输出: 1)2017-08- 31 20时40分59秒 2)2017年9月1日11点16分24秒

+1

能否请您提供一些输入和输出(预期VS你在说什么)? – 2017-09-01 12:25:50

+1

您的'dateFormat'解析输入为本地TZ可以吗? – yegodm

+0

在你的日期格式模式中,你不知道什么时区会传递给你的方法。所以字符串被解析,因为它已经在默认的时区。 – Damian0o

回答

0

改变线

dateFormat.setTimeZone(TimeZone.getDefault()); 

dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 
2

当你这样做:

dateFormat.setTimeZone(TimeZone.getDefault()); 

然后解析String,你说的格式:“我会给你在这个时区的日期和时间的字符串”。如您使用TimeZone.getDefault(),它将使用JVM的默认时区。所以,第一件事就是告诉格式化使用UTC在解析时:

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
// use UTC to parse 
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 
.... 
date = dateFormat.parse(dateString); 

我与dateString测试等于2017-08-01 10:00:00。因此,date将等于2017-08-01 10:00:00 UTC。当您用System.out.println打印日期时,它会调用toString()并将其转换为JVM的默认时区。

在我使用的JVM,默认的时区为America/Sao_Paulo,所以当我把这个:

System.out.println(date); 

它打印:

周二8月1日07:00:00 BRT 2017年

因为在8月1日,上午10时在UTC相当于在圣保罗7 AM。 这将导致根据您的JVM默认时区更改。

如果你想打印日期,但日期和时间等同于另一个时区(UTC相比其他),你需要用不同的时区设定的另一格式:

DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
// use my default timezone to format (America/Sao_Paulo) 
dateFormat2.setTimeZone(TimeZone.getDefault()); 
formattedDate = dateFormat2.format(date); 

这将打印:

2017年8月1日07:00:00

而不是默认的时区,你可以使用任何你想要的时区(我使用America/New_York为例):

DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
// use New York timezone 
dateFormat2.setTimeZone(TimeZone.getTimeZone("America/New_York")); 
formattedDate = dateFormat2.format(date); 

这将转换的日期/时间到纽约的时区:

2017年8月1日06:00:00

如果您想要在UTC中打印日期/时间,则不需要创建另一个格式化程序,只需使用第一个格式程序(因为它已设置为UTC)。


JVM的默认时区can be changed without notice, even at runtime,所以最好使用特定的一个,而不是只用getDefault()的。

倾向于使用IANA timezones names(总是格式为Region/City,如America/Sao_PauloEurope/Berlin)。 避免使用3字母缩写(如CST或),因为它们是ambiguous and not standard

通过调用TimeZone.getAvailableIDs(),您可以获得可用时区列表(并选择最适合您系统的时区)。


新的日期/时间API

老班(DateCalendarSimpleDateFormat)有lots of problemsdesign issues,他们正在被新的API取代。

在Android中,您可以使用ThreeTen Backport,它是Java 8新日期/时间类的一个很好的后端。要使其工作,您还需要ThreeTenABP(更多关于如何使用它here)。

该API使用起来要容易得多。首先创建一个org.threeten.bp.format.DateTimeFormatter并将输入String解析为org.threeten.bp.LocalDateTime

然后将其转换为UTC(创建org.threeten.bp.ZonedDateTime),然后到你想要的时区,并使用其他格式以进行输出:

// date/time with optional milliseconds 
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSS]"); 
// parse to LocalDateTime 
LocalDateTime dt = LocalDateTime.parse(dateString, parser); 

// convert to UTC 
ZonedDateTime z = dt.atZone(ZoneOffset.UTC); 

// convert to another timezone 
z = z.withZoneSameInstant(ZoneId.of("America/New_York")); 
// format it 
// date/time without milliseconds 
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 
System.out.println(fmt.format(z)); 

您还可以使用使用ZoneId.systemDefault()默认的时区,并使用ZoneId.getAvailableZoneIds()获得所有可用时区。

如果你想要UTC的日期/时间,你可以跳过withZoneSameInstant()


要将其转换为java.util.Date,你可以使用org.threeten.bp.DateTimeUtils类:

// convert ZonedDateTime to java.util.Date 
Date d = DateTimeUtils.toDate(z.toInstant()); 
+0

谢谢,但我不想指定像时区(TimeZone.getTimeZone(“America/New_York”))你提到的,我的应用程序使用世界的任何部分,它应该根据该时区工作。 – Joe

+0

@Joe我已经更新了答案,使其更加清晰。 – 2017-09-01 13:11:30