簡體   English   中英

Java 本地應用程序和 Jenkins 部署之間的日期時間不一致

[英]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:00DateTime (因為 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:302020-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.

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