[英]Java datetime inconsistent between local application and Jenkins deployment
我將日期時間作為字符串接收到我的應用程序中。 在那里我需要提取小時,以便可以將它與其他一些東西一起寫入文件。 對於我的單元測試,字符串將如下所示
2019-10-26T00:00:00+01:00
我用來提取小時的代碼是這個
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public static int extractHour(String dateInString) {
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ");
DateTime dateTime = formatter.parseDateTime(dateInString);
return dateTime.getHourOfDay();
}
我的測試在本地通過了預期的 00 小時和實際的 00 小時,但是當我通過 Jenkins 部署時,實際小時顯示為 23,而我的預期為 00。
當您不以其他方式指示 Joda-Time 時, formatter.parseDateTime()
會解析為默認時區中的DateTime
。
因此,例如,如果您的本地時區設置為 Europe/Dublin 或 Europe/London,則解析結果將是2019-10-26T00:00:00.000+01:00
的DateTime
(因為 10 月 26 日是最后一天那些時區的夏令時(DST))和一天中的小時將是 0 如你所料。 如果你的 Jenkins 服務器的時區設置是 UTC——這很常見——你的字符串在那里被解析為2019-10-25T23:00:00.000Z
。 顯然,一天中的時間是 23 點。
如果您希望將字符串的偏移量保留在DateTime
中,則修復方法是:
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ")
.withOffsetParsed();
但是,請三思。 一天中的小時僅相對於偏移量才有意義。 在夏令時結束的晚上,您可能會2019-10-27T01:00:00+01:00
字符串,一小時后更改時鍾時, 2019-10-27T01:00:00+00:00
。 兩個字符串的時間都是 1,但它們之間有一個小時。 你真的想要同樣的結果嗎? 如果有一天你得到一串2020-02-16T00:00:00-05:00
怎么辦?
編輯:
你會建議什么而不是使用 withOffsetParsed()[?]
我首先建議您決定對於具有不同偏移量的字符串想要什么結果,例如2020-03-06T18:00:00+05:30
和2020-04-18T04:00:00-08:00
。 你應該比我更清楚這一點。
通常推薦的跨偏移處理時間的做法是使用 UTC 處理所有內容。 這可能是您已經找到並在評論中提到的解決方案的一個特例,在格式化程序上指定時區:
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ")
.withZoneUTC();
這保證了一致的結果,顯然與您在 Jenkins 服務器上獲得的結果相同。 所以在你的例子中是 23。
PS 如果這是新代碼,您可能不應該使用 Joda-Time。 Joda-Time 主頁說:
請注意,Joda-Time 被認為是一個基本上“完成”的項目。 沒有計划進行重大改進。 如果使用 Java SE 8,請遷移到
java.time
(JSR-310)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.