簡體   English   中英

如何將這種格式的字符串轉換為 Java 8 時間並轉換為長毫秒

[英]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作為時區縮寫。 對於偏移量,我們可以使用xxZZZ 由於FriNov是英語,我們需要指定一個講英語的語言環境。

與您的代碼相比,我增加了一些復雜性,因為我們想要驗證偏移量和時區是否一致。 OffsetDateTime.parse直接使用偏移量( +0000 ),而ZonedDateTime.parse從時區( UTC )導出偏移量。 我的支票非常簡單,可能會擴展到接受從夏令時 (DST) 和共享相同縮寫的多個時區過渡中的兩種可能的偏移。

PS 不要使用LocalDateTime 這種類型既不能保留偏移量也不能保留時區,因此您不能再將日期和時間附加到時間線上的特定點,您需要這樣做才能獲得自紀元以來的毫秒數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM