[英]How can I parse UTC date/time (String) into something more readable?
我有一個這樣的日期和時間字符串: 2011-04-15T20:08:18Z
。 我對日期/時間格式了解不多,但我認為,如果我錯了,請糾正我,這就是它的 UTC 格式。
我的問題:在 Java 中,將其解析為更正常格式的最簡單方法是什么?
您擁有的是ISO-8601日期格式,這意味着您可以使用SimpleDateFormat
DateFormat m_ISO8601Local = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
然后你可以使用SimpleDateFormat.parse() 。 此外,這是一篇博客文章,其中包含一些可能會有所幫助的示例。
更新:
在使用此解決方案之前,請閱讀以下評論。
String output =
Instant.parse ( "2011-04-15T20:08:18Z" )
.atZone ( ZoneId.of ( "America/Montreal" ) )
.format (
DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL )
.withLocale ( Locale.CANADA_FRENCH )
)
;
2011 年 4 月 15 日 16 時 08 月 EDT
Josh Pinter 的答案是正確的,但可能更簡單。
在 Java 8 及更高版本中,捆綁的 java.util.Date/Calendar 類被JSR 3 定義的 java.time 框架取代。 這些課程受到Joda-Time的啟發,但完全重新設計。
java.time 框架是 Joda-Time 的正式繼承者。 Joda-Time 的創建者建議我們應該盡快遷移到 java.time。 Joda-Time 繼續更新和調整,但進一步的創新將僅在 java.time 及其在ThreeTen-Extra項目中的擴展中進行。
java.time 的大部分功能已被反向移植到 ThreeTen-Backport 項目中的 Java 6 和 7,並進一步適應ThreeTen- Backport 項目中的ZE84E30B9390CDB64DB6DB2C9AB87846D項目。
上面 Joda-Time 代碼的等效代碼非常相似。 概念相似。 和 Joda-Time 一樣,java.time 類在解析/生成日期時間值的文本表示時默認使用ISO 8601格式。
Instant
是UTC時間線上的一個時刻,分辨率為納秒(相對於 Joda-Time 和 java.util.Date 使用的毫秒)。
Instant instant = Instant.parse( "2011-04-15T20:08:18Z" );
應用時區 ( ZoneId
) 以獲取ZonedDateTime
。
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
調整到另一個時區。
ZoneId zoneId_NewYork = ZoneId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt.withZoneSameInstant( zoneId_NewYork );
要創建toString
方法之外的其他格式的字符串,請使用java.time.format類。 您可以指定自己的格式模式或讓 java.time 自動本地化。 為 (a) 翻譯月份/星期幾的名稱時使用的人類語言,以及 (b) 句號與逗號、部分順序等的文化規范指定Locale
。
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL );
formatter = formatter.withLocale( Locale.US );
String output = zdt_NewYork.format( formatter );
美國東部時間 2011 年 4 月 15 日星期五下午 4:08:18
java.time框架內置於 Java 8 及更高版本中。 這些類取代了麻煩的舊日期時間類,例如java.util.Date
、 Calendar
和SimpleDateFormat
。
現在處於維護模式的Joda-Time項目建議遷移到java.time類。
要了解更多信息,請參閱Oracle 教程。 並在 Stack Overflow 上搜索許多示例和解釋。 規范是JSR 310 。
您可以直接與數據庫交換java.time對象。 使用符合JDBC 4.2或更高版本的JDBC 驅動程序。 不需要字符串,不需要java.sql.*
類。
從哪里獲得 java.time 課程?
ThreeTen-Extra項目通過附加類擴展了 java.time。 該項目是未來可能添加到 java.time 的試驗場。 您可以在這里找到一些有用的類,例如Interval
、 YearWeek
、 YearQuarter
等等。
更新: Joda-Time項目現在處於維護模式,團隊建議遷移到java.time類。 本節原封不動地留給歷史。
Joda-Time可以直接使用該字符串。 只需傳遞給DateTime class 上的構造函數。
Joda-Time 理解標准的ISO 8601 日期時間格式,並使用該格式作為默認格式。
以下是在 Mac 上的 Java 7 中運行的 Joda-Time 2.3 中的示例代碼。
我展示了如何通過兩種方式將字符串傳遞給 DateTime 構造函數:有和沒有時區。 指定時區可以解決人們在進行日期時間工作時遇到的許多問題。 如果未指定,您將獲得默認時區,該時區在投入生產時會帶來驚喜。
我還展示了如何使用內置常量DateTimeZone.UTC
指定無時區偏移 ( UTC /GMT)。 這就是最后的Z
, Zulu
時間的縮寫,意思是:沒有時區偏移 (00:00)。
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
// Default time zone.
DateTime dateTime = new DateTime( "2011-04-15T20:08:18Z" );
// Specified time zone.
DateTime dateTimeInKolkata = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "Asia/Kolkata" ) );
DateTime dateTimeInNewYork = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "America/New_York" ) );
// In UTC/GMT (no time zone offset).
DateTime dateTimeUtc = dateTimeInKolkata.toDateTime( DateTimeZone.UTC );
// Output in localized format.
DateTimeFormatter formatter = DateTimeFormat.shortDateTime().withLocale( Locale.US );
String output_US = formatter.print( dateTimeInNewYork );
轉儲到控制台…
System.out.println("dateTime: " + dateTime );
System.out.println("dateTimeInKolkata: " + dateTimeInKolkata );
System.out.println("dateTimeInNewYork: " + dateTimeInNewYork );
System.out.println("dateTimeUtc: " + dateTimeUtc );
System.out.println("dateTime in US format: " + output_US );
運行時…
dateTime: 2011-04-15T13:08:18.000-07:00
dateTimeInKolkata: 2011-04-16T01:38:18.000+05:30
dateTimeInNewYork: 2011-04-15T16:08:18.000-04:00
dateTimeUtc: 2011-04-15T20:08:18.000Z
dateTime in US format: 4/15/11 4:08 PM
Java 7 版本的 SimpleDateFormat支持使用大寫字母X
的 ISO-8601 時區。
String string = "2011-04-15T20:08:18Z";
DateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = iso8601.parse(string);
如果您堅持使用 Java 6 或更早版本,推薦 JodaTime 的答案是一個安全的選擇。
已經有很多答案,但只是想用java 8進行更新,以防任何人在解析字符串日期時遇到問題。
通常我們面臨兩個日期問題
Java 8 中的DateTimeFormatter
class 可用於這兩個目的。 以下方法試圖為這些問題提供解決方案。
方法 1:將您的 UTC 字符串轉換為Instant 。 使用Instant ,您可以通過提供時區字符串為任何時區創建日期,並使用DateTimeFormatter
格式化日期以根據需要顯示。
String dateString = "2016-07-13T18:08:50.118Z";
String tz = "America/Mexico_City";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm a");
ZoneId zoneId = ZoneId.of(tz);
Instant instant = Instant.parse(dateString);
ZonedDateTime dateTimeInTz =ZonedDateTime.ofInstant(instant, zoneId);
System.out.println(dateTimeInTz.format(dtf));
方法二:
使用內置常量的DateTimeFormatter
例如ISO_INSTANT
將字符串解析為LocalDate
。 ISO_INSTANT
可以解析模式的日期
yyyy-MM-dd'T'HH:mm:ssX例如'2011-12-03T10:15:30Z'
LocalDate parsedDate
= LocalDate.parse(dateString, DateTimeFormatter.ISO_INSTANT);
DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("yyyy MM dd");
System.out.println(parsedDate.format(displayFormatter));
方法三:
如果您的日期字符串具有很高的時間精度,例如它捕獲秒的分數以及在這種情況下2016-07-13T18:08:50.118Z那么方法 1 將起作用,但方法 2 將不起作用。 如果您嘗試解析它將拋出DateTimeException
因為ISO_INSTANT
格式化程序將無法解析幾分之一秒,正如您從其模式中看到的那樣。 在這種情況下,您必須通過提供如下日期模式來創建自定義DateTimeFormatter
。
LocalDate localDate
= LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX"));
摘自我寫的博客鏈接。
您必須提供以下格式:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date parse = simpleDateFormat.parse( "2011-04-15T20:08:18Z" );
我在 Andrew White 解決方案中遇到了解析錯誤。 在 Z 周圍添加單引號解決了這個問題
DateFormat m_ISO8601Local = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss'Z'");
@khmarbaise 答案中的模式對我有用,這是我提取的實用方法(請注意,模式字符串中省略了 Z):
/**
* Converts an ISO-8601 formatted UTC timestamp.
*
* @return The parsed {@link Date}, or null.
*/
@Nullable
public static Date fromIsoUtcString(String isoUtcString) {
DateFormat isoUtcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
isoUtcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
return isoUtcFormat.parse(isoUtcString);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
對於所有舊版本的 JDK(6 下),它可能很有用。
擺脫尾隨的“Z”並將其替換為“UTC”時區顯示名稱 - 然后使用適當的簡單日期格式化程序解析整個字符串。
String timeZuluVal = "2011-04-15T20:08:18Z";
timeZuluVal = timeZuluVal.substring( 0, timeZuluVal.length() - 2 ); // strip 'Z';
timeZuluVal += " " + TimeZone.getTimeZone( "UTC" ).getDisplayName();
DateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss zzzz" );
Date dateVal = simpleDateFormat.parse( timeZuluVal );
喬達時間
public static final String SERVER_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static DateTime getDateTimeFromUTC(String time) {
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(SERVER_TIME_FORMAT).withZoneUTC();
Calendar localTime = Calendar.getInstance();
DateTimeZone currentTimeZone = DateTimeZone.forTimeZone(localTime.getTimeZone());
return dateTimeFormatter.parseDateTime(time).toDateTime().withZone(currentTimeZone);
} catch (Exception e) {
return DateTime.now();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.