2017-07-27 74 views
1

問候堆棧溢出,爲什麼Java SimpleDateFormat在某些服務器上而不是其他服務器上工作?

我遇到了一個奇怪的問題,我正在爲位於雅典的外國辦事處實施一個應用程序。構建時,應用程序是一個.war文件,部署在Tomcat實例上。

只是爲了一些背景信息,這同一個應用程序成功地工作在幾個不同的操作系統(Ubuntu的12.04,在Windows Server 2012 R2等),無論是在美國和其他國家不同的Java/Tomcat的配置。

但是我用來爲雅典安裝應用程序的操作系統是Windows Server 2008 R2。在這個服務器上安裝了Tomcat 8.5.4使用的Java JRE 1.8.0_111。這臺服務器位於雅典。

一切工作正常,除了我提交日期字段到我的控制器方法的任何地方的應用程序。當試圖日期字符串提交給我的控制器在整個應用程序的不同部分,我得到以下信息:

Failed to convert the value of 'java.lang.String' to required type'java.util.Date'; 
nested exception is java.lang.illegalArgumentException: Could not parse text 
[7/28/2017 7:00 AM] into any available date input formats. 

請記住,當我這個應用程序部署到Tomcat實例上的其他服務器,一切正常罰款,我沒有收到此錯誤消息。

在試圖解決這個錯誤,我決定改變我的請求參數之一,從類型:

@RequestParam("date") Date date 

@RequestParam("date") String dateString 

然後我用的Java的SimpleDateFormat轉換的字符串到日期:

SimpleDateFormat sdf_date = new SimpleDateFormat("MM/dd/yyyy hh:mm a"); 
String startDate = dateString; 
Date date = sdf_date.parse(startDate); 

傳遞給上述函數的日期字符串是:

11/25/2017 12:00 pm 

我在不同OS/Tomcat配置的幾個測試服務器上測試了它,它像一個魅力一樣工作。但是,當在位於雅典的Windows 2008 R2服務器上進行測試時,我仍然收到錯誤消息。我不再收到上述錯誤,但我沒有收到以下:

java.text.ParseException: Unparseable date: "11/25/2017 12:00 pm" 

我不清楚爲什麼這個完全相同的Java代碼將能夠使用一些服務器,但沒有人對相同的SimpleDateFormat模式解析同日。這對我來說似乎很陌生。

請讓我知道如果你需要任何額外的信息,我會很樂意澄清。

謝謝!

編輯:服務器在服務器端調試的截圖在雅典:

enter image description here

正在傳遞到控制器方法「dateString」

+1

難道是部署問題?像一些jar的舊版本? – talex

+0

我正在調查,但奇怪的事情是相同的.war文件將在其他服務器上工作沒有問題。 – MotoDave452

+2

它可以是日期格式問題嗎?在歐洲,日期將採用其他格式,例如「」dd/MM/yyyy ...「」。 –

回答

2

希臘不使用相同的AM/PM與許多其他講拉丁語言的國家一樣。希臘改爲使用π.μ。和μ.μ。因此,當SimpleDateFormat沒有收到語言環境時,它假定它與運行該程序的計算機相同。

要解決這個問題,嘗試一些諸如以下:

SimpleDateFormat sdf_date = new SimpleDateFormat("MM/dd/yyyy hh:mm a", new Locale("en", "US")); 
String startDate = dateString; 
Date date = sdf_date.parse(startDate); 

這將使用英語與美國區域設置此服務器上。儘管如此,仍然需要確保這是在每種情況下在輸入中傳遞的格式。

+2

這是正確的答案。 – ReezaCoriza

+0

這對我有用!我會接受這個答案,也可以讚揚Sergei Sirik提出的同樣建議。 – MotoDave452

1

TL;博士

Instant.parse("2017-11-25T12:00:00Z") 

詳細

Answer by Smith是正確的。

另外還有三個問題。解決這些問題可以消除您在摔跤本地化文本格式方面的問題。

時區

被您忽略的時區的關鍵問題。如果未指定,則隱式依賴JVM的當前默認時區。即使在運行時(!),該默認值也可能會有所不同,因此更好地指定您希望/預期的時區。

通常最好使用UTC,除非你有特定的原因。

ISO 8601

的ISO 8601標準定義了實際明確的格式文本表示日期時間值。

對於在UTC時間線中的時刻,使用YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ其中T分開的時間部分的時間部分,所述Z是短期的和祖魯裝置UTC和時間使用24小時制(無AM/PM)。

將日期時間值序列化爲文本時使用這些標準格式。

java.time

您正在使用的是現在傳統麻煩舊日期時間類,由現代java.time類取代。

Instant類代表UTC中時間軸上的一個時刻,類似於java.time.Date,分辨率爲納秒而非毫秒。

Instant instant = Instant.now() ; 

java.time類在解析/生成字符串時默認使用ISO 8601格式。

String output = instant.toString() ; 

而且......

Instant instant = Instant.parse("2017-01-23T12:34:56Z") ; 

也許你在一定的時間段,而不是UTC意味着中午25。

LocalDateTime.parse("2017-11-25T12:00:00") // LocalDateTime has no concept of time zone or offset-from-UTC. Not on the timeline. Has no real meaning until assigned a time zone. 
      .atZone(ZoneId.of("America/New_York")) // Assign a time zone to determine a moment on the timeline, a ZonedDateTime. 
      .toInstant() // Extract a Instant, always in UTC by definition. 
      .toString() // Generate a string in standard ISO 8601 format. 
+0

謝謝!我感謝你的時間,這是非常有用的信息。 – MotoDave452

相關問題