簡體   English   中英

Java 字符串轉日期格式

[英]Java String to Date format

我有以下日期String ,我試圖將其解析並格式化為Sept 21 2021但有ParsingException

String expiryDate ="Tue Sep 21 12:11:37 PHT 2021";
System.out.println(expiryDate);
Date formatter = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy").parse(expiryDate);
Exception in thread "main" java.text.ParseException:
Unparseable date: "Tue Sep 21 12:11:37 PHT 2021"
    at java.base/java.text.DateFormat.parse(DateFormat.java:395)

我想我的解析日期格式不正確,但無法找出正確的格式。

我認為您的問題是SimpleDateFormat缺少Locale 如果您沒有明確設置,代碼可能會使用您的默認Locale ,然后它可能不是ENGLISH而是其他東西,它可能位於菲律賓的計算機上。 例如,它會嘗試解析Tue的菲律賓縮寫,這會導致無法解析的String

在遇到與您相同的Exception后,這是在我的計算機上運行的(也不是ENGLISH ):

String expiryDate = "Tue Sep 21 12:11:37 PHT 2021";
Date date = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH)
                .parse(expiryDate);
System.out.println(date.toString());

這給出了以下輸出:

Tue Sep 21 06:11:37 CEST 2021

這也適用於只有一個E的模式。


帶有java.time Java 8 - 10 解決方案:

這在 Java 8 和 10 上成功運行,但根據@ArvindKumarAvinash 的回答,由於String expiryDate時區的縮寫,這在 Java 11 和上述版本中可能String expiryDate

你可以在java.time這樣做:

String expiryDate = "Tue Sep 21 12:11:37 PHT 2021";
DateTimeFormatter parserDtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu",
                                                            Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(expiryDate, parserDtf);
System.out.println("Something will expire at " + zdt);

它會輸出

Something will expire at 2021-09-21T12:11:37+08:00[Asia/Manila]

可以通過另一個DateTimeFormatter更改輸出格式,或者使用內置的DateTimeFormatter.ISO_ZONED_DATE_TIME或通過.ofPattern(pattern, Locale.ENGLISH)或使用DateTimeFormatterBuilder創建自定義.ofPattern(pattern, Locale.ENGLISH)

考慮到您只需要格式化和輸出日期部分,您可以選擇簡單地提取日期部分(即LocalDate )並在java.timejava.time

String expiryDate = "Tue Sep 21 12:11:37 PHT 2021";
DateTimeFormatter parserDtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu",
                                                            Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(expiryDate, parserDtf);
LocalDate expiryLocalDate = zdt.toLocalDate();
System.out.println("Something will expire at "
                    + expiryLocalDate.format(DateTimeFormatter.ofPattern("MMM dd uuuu",
                                                                        Locale.ENGLISH)));

會輸出

Something will expire at Sep 21 2021

Trails 中閱讀有關java.time更多信息。

deHaar回答很精彩,但在 Java-11 中失敗了。 一個安全的選擇是將 PHT 替換為相應的 Zone-Offset 值

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String expiryDate = "Tue Sep 21 12:11:37 PHT 2021".replace("PHT", "GMT+08:00");
        OffsetDateTime odt = OffsetDateTime.parse(expiryDate,
                DateTimeFormatter.ofPattern("EEE MMM d H:m:s ZZZZ u", Locale.ENGLISH));
        System.out.println(odt);

        // Custom format
        String formatted = odt.format(DateTimeFormatter.ofPattern("EEEE MMMM dd uuuu 'at' hh:mm:ss a", Locale.ENGLISH));
        System.out.println(formatted);
    }
}

輸出:

2021-09-21T12:11:37+08:00
Tuesday September 21 2021 at 12:11:37 PM

注意: java.util日期時間類已經過時且容易出錯,它們的格式化 API SimpleDateFormat也是如此。 我建議您應該完全停止使用它們並切換到現代日期時間 API

如果您正在為您的 Android 項目執行此操作,並且您的 Android API 級別仍然不符合 Java-8,請查看 通過脫糖可用的 Java 8+ API如何在 Android 項目中使用 ThreeTenABP

Trail: Date Time 中了解有關現代日期時間 API 的更多信息。

使用舊 API:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws ParseException {
        String expiryDate = "Tue Sep 21 12:11:37 PHT 2021".replace("PHT", "GMT+08:00");
        Date date = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZZ yyyy").parse(expiryDate);
        System.out.println(date);

        // Custom format
        String formatted = new SimpleDateFormat("EEEE MMMM dd yyyy 'at' hh:mm:ss a", Locale.ENGLISH).format(date);
        System.out.println(formatted);
    }
}

我是新來的,如果我做錯了什么,抱歉。

“Tue”包含三個字符,格式應為

"EEE MMM dd HH:mm:ss z yyyy"

說明

似乎菲律賓標准時間的縮寫是 PHT 到 Java 10 而它是 Java 11 的 PST。查看它的一種方法是運行以下代碼:

    DateTimeFormatter zf = DateTimeFormatter.ofPattern("z", Locale.ROOT);
    ZoneId zid = ZoneId.of("Asia/Manila");
    System.out.println(zf.format(ZonedDateTime.now(zid)));

Java 9 上的輸出:

PHT

Java 11 上的輸出:

太平洋標准時間

起初我認為是 CLDR 的不同版本,即 Unicode 通用語言環境數據存儲庫,是原因。 但是當我使用 Java 的原始語言環境數據(使用-Djava.locale.providers=COMPAT運行)時,我在行為上得到了相同的差異,所以我不太確定。

在任何情況下,如果有任何方法可以避免它,您首先不應該依賴三個字母的時區縮寫。 它們往往是模棱兩可的,並且沒有標准化。 所以你真的不能確定你得到了什么。

除此之外,告訴您為格式化程序指定語言環境的評論和答案也是正確的。

暫無
暫無

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

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