簡體   English   中英

PeriodFormatter 在不同設備上的不同行為 (JodaTime)

[英]Different behavior of PeriodFormatter on different devices (JodaTime)

我正在使用 JodaTime 為 android 應用程序實現倒數計時器。 根據設備的不同,輸出是不同的。

       DateTime openingDateTime = new DateTime(2018, DateTimeConstants.JUNE, 14, 21, 0, 0, DateTimeZone.forID("Europe/Moscow"));
        DateTime nowDateTime = DateTime.now(DateTimeZone.forID("Europe/Moscow"));
        long difference = openingDateTime.getMillis() - nowDateTime.getMillis();
(...)
onTick(difference);

(...)

    PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
            .printZeroAlways()
            .appendDays().appendSuffix(" day", " days")
            .appendSeparator(" ")
            .appendHours()
            .appendSeparator(":")
            .appendMinutes()
            .appendSeparator(":")
            .appendSeconds()
            .toFormatter();
(...)    

        @Override
        public void onTick(long millisUntilFinished) {
            Duration duration = new Duration(millisUntilFinished);
            Period period = duration.toPeriod(PeriodType.dayTime());
            tvCounter.setText(periodFormatter.print(period));
        }

在一個設備上輸出正確: 491 days 4:39:18另一台錯誤: 0 days 11788:49:11 我究竟做錯了什么?

感謝您的評論,我現在可以重現您的問題 只需將以下靜態初始化程序添加到您的測試類(首先)以模擬您觀察預期輸出的設備:

static {
    TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
}

根據規范(另請參閱此 SO-post 上接受的答案),轉換duration.toPeriod(periodType)應僅使用所謂的精確持續時間字段,即小時、分鍾、秒和毫秒,而不是天。

我對Joda-Time(v2.9.6)源碼的分析:

內部類org.joda.time.chrono.BasicChronology包含以下常量:

private static final DurationField cDaysField = new PreciseDurationField(DurationFieldType.days(), 86400000L);

所以我們看到這里這個持續時間字段被標記為“精確”,但是:子類 ZonedChronology 包裝它並覆蓋方法isPrecise()的行為:

public boolean isPrecise() { 
  return iTimeField ? iField.isPrecise() : iField.isPrecise() && this.iZone.isFixed(); 
} 

這顯示了 days()-duration-field 的 precision 屬性的額外區域依賴性,即對於 UTC 等固定區域是精確的,否則是不精確的。

我不知道分析和觀察到的行為是功能還是錯誤。 比方說,期望通過duration.toPeriod(...)創建Period -objects 與區域無關是危險的。 如果系統區域是固定的,則那里沒有記錄有精確的天數組件。

不幸的是,對默認時區的隱式依賴通過其年表設計深深地編碼到 Joda-Time 中。 作為解決方法,您可以使用

Period p = new Period(nowDateTime, openingDateTime, PeriodType.dayTime());

暫無
暫無

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

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