簡體   English   中英

如何使用日期格式 yyyy-MM-dd hh:mm a 在 Java 8 中解決無法解析的日期異常

[英]How to resolve Unparseable date Exception in Java 8 with Date format yyyy-MM-dd hh:mm a

我有一個文本文件,從中讀取和設置事務 POJO 類數據,為了獲取開始時間和結束時間之間的差異,我需要解析日期對象中的時間信息。

DateFormat format = new SimpleDateFormat(dateFormat);
System.out.println("Date format in play:"+dateFormat);
Transaction transaction = storageRepositroy.getTransaction(key);
Date start = format.parse(transaction.getStartDate() + " " + transaction.getStartTime());//line no. 29
Date end = format.parse(transaction.getEndDate() + " " + transaction.getEndTime());

運行此代碼時出現異常

例外是

Date format in play:yyyy-MM-dd hh:mm a
java.text.ParseException: Unparseable date: "2020–03–01 03:15 PM"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at dc.tech.transaction.util.TimeUtil.calculateAverageTime(TimeUtil.java:29)

yyyy-MM-dd hh:mm a 是我傳遞給 SimleDateFormat 構造函數的日期格式。 我無法理解和調試為什么會出現此錯誤。

時間

我建議您使用 java.time,現代 Java 日期和時間 API,用於您的日期和時間工作。

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu\u2013MM\u2013dd");
    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
    
    String dateString = "2020–03–01";
    String timeString = "03:15 PM";
    
    LocalDate date = LocalDate.parse(dateString, dateFormatter);
    LocalTime time = LocalTime.parse(timeString, timeFormatter);
    LocalDateTime dateTime = date.atTime(time);
    
    System.out.println(dateTime);

輸出:

2020-03-01T15:15

使用 java.time 很容易在解析后組合日期和時間,所以我更喜歡單獨解析它們。

你的代碼出了什么問題?

感謝 Ajeetkumar 在評論中進行注意和報告:日期字符串中的連字符不是通常的減號或字符值為 2D 十六進制(十進制 45)的連字符,而是字符值為 2013 十六進制(十進制 8211)的破折號 因此,當您在格式模式字符串中指定通常的連字符時,它們不匹配,並且解析失敗。 相反,我使用 Unicode 轉義符將短划線放入格式模式字符串中。 簡單地將它粘貼在那里也可以工作(前提是您使用支持它的字符編碼保存 .java 文件),但我想讓讀者知道這里發生了一些特別的事情,所以我更喜歡 Unicode 轉義\\u\u003c/code> 。

您的代碼還有另一個問題:您沒有為格式化程序提供任何語言環境。 因此,它使用 JVM 的默認語言環境。 只要該語言環境需要PM ,解析就會起作用。 如果有一天您更改了語言環境設置或在具有不同默認語言環境的計算機或 JVM 上運行代碼,解析將突然失敗,您可能很難找出原因。 我已經指定了用於解析時間的英語語言環境。 有些人也更喜歡在約會時這樣做,即使從技術上講這不是必需的。

鏈接

我始終堅持這個口頭禪:使用與日期時間字符串完全相同的格式。

在下面給出的解決方案中,我已將您的日期時間字符串復制到我為SimpleDateFormatDateTimeFormatter指定的模式中,並將數字替換為相應的字母,例如2020yyyy同時保留其余內容(符號、空格等)。 ) 完整。

import java.text.DateFormat;
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 {
        DateFormat sdf = new SimpleDateFormat("yyyy–MM–dd hh:mm a", Locale.ENGLISH);// Make sure to use Locale
        String dateTimeString = "2020–03–01 03:15 PM";// The string copied from the exception you have got
        Date date = sdf.parse(dateTimeString);
        System.out.println(sdf.format(date));
    }
}

輸出:

2020–03–01 03:15 PM

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

使用現代日期時間 API:

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

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy–MM–dd hh:mm a", Locale.ENGLISH);// Make sure to use Locale
        String dateTimeString = "2020–03–01 03:15 PM";// The string copied from the exception you have got
        System.out.println(LocalDateTime.parse(dateTimeString, dtf));
    }
}

輸出:

2020-03-01T15:15

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

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

暫無
暫無

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

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