[英]How to convert string with this format to Java 8 time and convert to long milliseconds
我有一個 MapperUtility 類,它需要從發送字符串時間"Fri Nov 22 2013 12:12:13 GMT+0000 (UTC)"
的 Web 服務映射字符串
現在,我使用以下代碼將其轉換為 LocalDateTime:
String time = "Fri Nov 22 2013 12:12:13 GMT+0000 (UTC)";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM dd yyyy HH:mm:ssZ");
dtf.withZone(ZoneId.of("UTC"));
LocalDateTime convertedDate = LocalDateTime.parse(time, dtf);
但是我在 GMT+0000 (UTC) 開始時出現異常。 當我刪除格林威治標准時間以外的字符時,它會起作用。 將它們轉換為日期時間后,我需要將它們轉換為長毫秒。 請指教。 謝謝。
使解析器逐字接受您的字符串的低效方法是:
String[] timezones = {"UTC", "BST", "CET", "PST", ...};
StringBuilder sb = new StringBuilder(timezones.length * 8 + 38);
sb.append("E MMM dd yyyy HH:mm:ss' GMT'Z' ('");
for(String timezone : timezones)
sb.append("['").append(timezone).append("']");
sb.append("')'");
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(sb.toString());
String time = "Fri Nov 22 2013 12:12:13 GMT+0000 (UTC)";
ZonedDateTime convertedDate = ZonedDateTime.parse(time, dtf);
System.out.println(convertedDate);
我也更改為ZonedDateTime
,否則它會丟棄時區並始終返回 12:12:13 ,無論GMT+
之后是什么。
但是由於可能的時區縮寫的無窮無盡的列表,它很快變得笨拙。
更好的方法是預處理字符串:
String time = "Fri Nov 22 2013 12:12:13 GMT+0000 (UTC)";
String preprocessed = time.replaceAll("(.*) GMT([+-][0-9]{4}).*", "$1$2");
System.out.println(preprocessed);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM dd yyyy HH:mm:ssZ");
ZonedDateTime convertedDate = ZonedDateTime.parse(preprocessed, dtf);
System.out.println(convertedDate);
然后在廣泛的java.time
API 中找到毫秒的轉換有點棘手,但最終它變得如此簡單:
convertedDate.toInstant().toEpochMilli()
您可以使用DateTimeFormatterBuilder
構建這樣的模式:
static final DateTimeFormatter DF = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ofPattern("E MMM dd yyyy HH:mm:ss"))
.appendLiteral(" GMT")
.appendOffset("+HHmm", "+0000")
.optionalStart()
.appendLiteral(" (")
.appendZoneId()
.appendLiteral(')')
.optionalEnd()
.toFormatter()
.withLocale(Locale.US);
然后,只需:
String date = "Fri Nov 22 2013 12:12:13 GMT+0000 (UTC)";
long ms = OffsetDateTime.parse(date, DF).toInstant().toEpochMilli(); // 1385122333000
String time = "Fri Nov 22 2013 12:12:13 GMT+0000 (UTC)";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM dd yyyy HH:mm:ss 'GMT'xx (zzz)", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(time, dtf);
OffsetDateTime odt = OffsetDateTime.parse(time, dtf);
boolean offsetAgrees = zdt.getOffset().equals(odt.getOffset());
if (offsetAgrees) {
long millisecondsSinceEpoch = odt.toInstant().toEpochMilli();
System.out.println("Milliseoncds: " + millisecondsSinceEpoch);
} else {
System.out.println("Offset " + odt.getOffset() + " does not agree with time zone " + zdt.getZone());
}
輸出:
毫秒:1385122333000
我將GMT
解析為文字,+ +0000
作為偏移量, UTC
作為時區縮寫。 對於偏移量,我們可以使用xx
或ZZZ
。 由於Fri
和Nov
是英語,我們需要指定一個講英語的語言環境。
與您的代碼相比,我增加了一些復雜性,因為我們想要驗證偏移量和時區是否一致。 OffsetDateTime.parse
直接使用偏移量( +0000
),而ZonedDateTime.parse
從時區( UTC
)導出偏移量。 我的支票非常簡單,可能會擴展到接受從夏令時 (DST) 和共享相同縮寫的多個時區過渡中的兩種可能的偏移。
PS 不要使用LocalDateTime
。 這種類型既不能保留偏移量也不能保留時區,因此您不能再將日期和時間附加到時間線上的特定點,您需要這樣做才能獲得自紀元以來的毫秒數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.