2015-12-23 54 views
1

這是我原來的代碼 -差異毫米

String dateString = "23 Dec 2015 1:4 PM"; 
Locale locale = new Locale("en_US"); 
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a"); 
DateFormat df = new SimpleDateFormat("dd MMM yyyy HH:mm a", locale); 
Date date = null; 

try { 
    date = formatter.parse(dateString); 
} catch (ParseException e) { 
    LOGGER.error(e); 
} 

String newDate = df.format(date); 
System.out.println("oldDate = " + dateString); 
System.out.println("newDate = " + newDate); 

,這裏是我的輸出 -

oldDate = 23 Dec 2015 1:4 PM 
newDate = 23 Dec 2015 01:04 AM 

還有就是之間AM-PM差異oldDatenewDate。現在我改變了DateFormat代碼TO-

SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm a"); 
DateFormat df = new SimpleDateFormat("dd MMM yyyy hh:mm a", locale); 

,我得到預期的輸出,這是 -

oldDate = 23 Dec 2015 1:4 PM 
newDate = 23 Dec 2015 01:04 PM 

我知道,HH象徵着24小時格式和hh象徵着格式爲12小時

我的問題是

如果我使用HH:mm a代替hh:mm a,不應該這是24小時格式返回的時間?

(或)

如果默認爲12小時格式,不應該它根據日期輸入提供返回各自的AM/PM標記?

這只是爲了我的理解。

回答

7

更新回答

這裏的問題是Program flow

SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a"); 

simple date formatter用於格式化創建Date對象日期字符串,這裏是答案

的重要組成部分,當你正在使用HH,而不是HH,則SimpleDateFormater認爲提供的日期字符串是24-Hour Format,而簡單的忽略了這裏的AM/PM marker

從這個SimpleDateFormatter構建Date對象傳遞給

DateFormat df = new SimpleDateFormat("dd MMM yyyy HH:mm a", locale); 

如果你改變了行

SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a"); 

這就是爲什麼它的打印

newDate = 23 Dec 2015 01:04 AM 

SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm a"); 

一切都會順利的,因爲它應該!

注意:創建區域時,你應該通過語言代碼的語言環境()構造函數。 en-us不是en_us

IMP:代碼還在Java 8上測試。 Java(TM) SE Runtime Environment (build 1.8.0_121-b13)

+0

謝謝@MenoHochschild。請再次看看我的答案! –

+1

好了,但推薦'新Locale(「en-us」)'仍然是錯誤的。 –

+0

@MenoHochschild尊重所有我想知道你我們可以在Java 8(1.8.0_121)'語言中構建一個語言環境,正如我的答案中所述! –

5

HH之間區別:毫米和HH:MM:

HH:mm => will look like 00:12, 23:00... this has 24 hour format. 

    hh:mm => will look like 01:00Am, 02:00Am,...01:00pm this has 12 hour format. 

而在HH的a:毫米或HH:MM一個是獲取更多信息AM/PM標記去link

1

一個簡單的測試是解釋「HH:mm a」模式的最佳答案。首先,讓我們探討打印模式

舊格式引擎SimpleDateFormat

Calendar cal = new GregorianCalendar(2015, 3, 1, 17, 45); 
SimpleDateFormat sf = new SimpleDateFormat("HH:mm a", Locale.US); 
System.out.println(sf.format(cal.getTime())); // 17:45 PM 

的Java-8(新包裝java.time.format):

LocalTime time = LocalTime.of(17, 59); 
DateTimeFormatter tf = DateTimeFormatter.ofPattern("HH:mm a", Locale.US); 
System.out.println(tf.format(time)); // 17:59 PM 

這裏我們在兩個ca中都沒有觀察到任何覆蓋 SES。我更喜歡這種方法,因爲在我看來,使用「HH」和「a」的組合是對編程錯誤的一種指示(用戶顯然對這些模式符號的含義和官方描述沒有足夠的瞭解)。

現在讓我們來探討解析模式(我們將用嚴格的方式來觀察究竟怎麼回事幕後):

String dateString = "23 Dec 2015 1:4 PM"; 
SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy H:m a", Locale.US); 
df.setLenient(false); 
Date date = df.parse(dateString); 
// java.text.ParseException: Unparseable date: "23 Dec 2015 1:4 PM" 

如何是Java-8的行爲?這是相同的,但有一個更清晰的錯誤消息:

DateTimeFormatter tf = DateTimeFormatter.ofPattern("H:m a", Locale.US); 
tf = tf.withResolverStyle(ResolverStyle.STRICT); 
LocalTime.parse("1:4 PM", tf); 
// DateTimeException: Cross check failed: AmPmOfDay 0 vs AmPmOfDay 1 

這個消息告訴我們所分析的小時(!在24小時制)值爲「1」表示AM,而文字輸入包含其他解析AM/PM值「PM」。這種矛盾心理無法解決。

課程:我們必須謹慎從事寬鬆的解析,其中矛盾的信息可以被忽略並導致錯誤的假設。 @Arjun接受的答案是完全錯誤的。

順便說一句:請使用Locale.USnew Locale("en", "US")而不是new Locale("en-US"),因爲語言「en-US」不存在。

+0

你好@MenoHochschild請看看答案!感謝您的建設性批評!我想聽聽你的消息! –