簡體   English   中英

如何解析和格式化此字符串日期 2022-11-08 10:28:04.282551-06?

[英]How can I parse and format this string date 2022-11-08 10:28:04.282551-06?

我有這段代碼:

public static void main(String[] args) throws ParseException {
        String fecha = "2022-11-08 10:28:04.282551-06";
        
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
        Date e = simpleDateFormat.parse(fecha);
        SimpleDateFormat newSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        System.out.println(newSimpleDateFormat.format(e));
        
    }

這個錯誤:

Exception in thread "main" java.text.ParseException: Unparseable date: "2022-11-08 10:28:04.282551-06"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at Ejemplos.main(Ejemplos.java:11)

我希望我的新日期是這樣的: 2022-11-08 10:28:04.282551這個點后的值 *282551 *有時可以更少,例如:*282 * 或2825有時沒有點,例如: 2022 -11-08 10:28:04-06

強烈建議停止使用過時的DateCalendarSimpleDateFormat ……類——這些類已被java.time package 和LocalDateTimeZonedDateTimeDateTimeFormatter等子包中的類替換……

由於我們有一個大小可變的小數部分,我們需要DateTimeFormatterBuilder來創建相應的格式化程序來解析字符串。 在其中,我們重用了現有的ISO_LOCAL_TIME ,它通過接受從無小數到 9 小數秒的小數來處理要求。

private static final DateTimeFormatter PARSE_FORMATTER = 
        new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE)
                .appendLiteral(' ')
                .append(DateTimeFormatter.ISO_LOCAL_TIME) // accepts presence or absence of fraction
                .appendOffset("+HHmm", "+00") // accepts -06 and +0530
                .toFormatter(Locale.ROOT);  // replace as needed

public static OffsetDateTime convert(String str) {
    return OffsetDateTime.parse(str, PARSE_FORMATTER);
}

要獲得類似“2022-11-08 10:28:04.282551”格式的字符串,我們需要一個額外的格式化程序:

private static final DateTimeFormatter FORMAT_FORMATTER = 
        DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS");  // time zone is IGNORED!!

public static String convertToString(OffsetDateTime dateTime) {
    return dateTime.format(FORMAT_FORMATTER);
}

前面的兩種方法(顯然)可以合並到一個方法中,但最好使用日期時間對象( ZonedDateTimeOffsetDateTimeLocalDateTime ……)而不是字符串——字符串應該只用於輸入和輸出!

上面的 Formatter 沒有在結果中包含時區信息,這可能會讓人非常困惑(恕我直言)——請參閱下面的最后測試日期 output。 請確保確實需要這樣的東西!!!
否則我們可能會將OffsetDateTme轉換為ZonedDateTime ,如dateTime.atZoneSameInstant(ZoneId.systemDefault()).format(FORMAT_FORMATTER);
或者在 output 格式化程序中包含時區信息,如底部所示。


測試以上方法:

public static void main(String[] args) {
    // just for testing
    Locale.setDefault(Category.DISPLAY, Locale.GERMANY);
    Locale.setDefault(Category.FORMAT, Locale.GERMANY);
    TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"));
    
    var data = """
        2022-11-08 10:28:04.282551-06
        2022-11-08 10:28:04.282-06
        2022-11-08 10:28:04-06
        2022-11-08 10:28:04+02
        """.split("\n");
    for (var str : data) {
        test(str);
    }
}

private static void test(String str) {
    try {
        System.out.printf("%-30s  ->  %s%n", str, convertToString(convert(str)));
    } catch (Exception ex) {
        System.err.printf("%-30s  ->   %s%n", str, ex);
    }
}

Output:

 openjdk version "20-ea" 2023-03-21 OpenJDK Runtime Environment (build 20-ea+12-790) OpenJDK 64-Bit Server VM (build 20-ea+12-790, mixed mode, sharing) 2022-11-08 10:28:04.282551-06 -> 2022-11-08 10:28:04.282551 2022-11-08 10:28:04.282-06 -> 2022-11-08 10:28:04.282000 2022-11-08 10:28:04-06 -> 2022-11-08 10:28:04.000000 2022-11-08 10:28:04+02 -> 2022-11-08 10:28:04.000000

如果我們想確保 output 是某個特定的時區,我們可以在格式格式化程序上指定它,如下所示:

private static final DateTimeFormatter FORMAT_FORMATTER = 
        DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS")
                .withZone(ZoneId.of("Europe/Berlin"));

現在 output 將是:

 2022-11-08 10:28:04.282551-06 -> 2022-11-08 17:28:04.282551 2022-11-08 10:28:04.282-06 -> 2022-11-08 17:28:04.282000 2022-11-08 10:28:04-06 -> 2022-11-08 17:28:04.000000 2022-11-08 10:28:04+02 -> 2022-11-08 09:28:04.000000

編輯:此答案中首次出現的解析格式化程序的版本是:

private static final DateTimeFormatter PARSE_FORMATTER = 
    new DateTimeFormatterBuilder()
    .appendPattern("uuuu-MM-dd HH:mm:ss")  // date time
    .optionalStart()
    .appendFraction(ChronoField.MICRO_OF_SECOND, 3, 6, true)  // optional fractions
    .optionalEnd()
    .appendPattern("x")  // time zone offset
    .toFormatter()
    .withLocale(Locale.ROOT);  // replace as needed

我找到了解決您問題的方法。 首先你需要拆分你的字符串,然后你可以格式化它。 嘗試這個

public static void main(String[] args) throws ParseException {
    String fecha = "2022-11-08 10:28:04.282551-06";
    String[] parts = fecha.split("\\.");
    String part1 = parts[0];
    String part2 = parts[1];

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(simpleDateFormat.parse(part1));

}

暫無
暫無

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

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