簡體   English   中英

轉換后的 unix 時間戳加上時區(以秒為單位)在 Android 模擬器上給出了真實的本地日期時間,但在真實設備上卻沒有?

[英]Converted unix timestamp with a timezone addition in seconds gives a true local date time on Android emulator but not in real device?

我在 UNIX 時間戳中從 web 服務獲取了一個日期。 我將它乘以 1000L,然后我以秒為單位添加時區(也由 web 服務提供)乘以 1000 以獲得根據應用程序運行所在國家/地區而不是 UTC 日期的日期。 在模擬器中,提供的日期時間是正確的,但當我在真實設備上測試時,它為我提供了 1 小時以上的時間,這與當地時間不符。 問題出在哪里?

long numberOfsecondsRise = json.getJSONObject("city").getInt("timezone");

long res=(json.getJSONObject("city").getLong("sunrise")*1000L +numberOfsecondsRise*1000) ;
 Date rise=new java.util.Date(res);
 DateFormat dfa = DateFormat.getTimeInstance();
 sunFiled.setText(getResources().getString(R.string.sunrise)+": " + dfa.format(rise));

java.time 和 ThreeTenABP

考慮使用 java.time,現代 Java 日期和時間 API,作為您的時間工作。 如果 minSDK 低於 API 級別 26,那么通過反向移植,我會回到那個。 首先是代碼:

    DateTimeFormatter timeFormatter
            = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);

    long sunriseUnixTs = 1_589_581_234;
    ZonedDateTime sunriseApplicationTz = Instant.ofEpochSecond(sunriseUnixTs)
            .atZone(ZoneId.systemDefault());

    System.out.println("Sunrise: " + sunriseApplicationTz.format(timeFormatter));

Output 在我的時區和區域設置中來自此示例片段:

日出:03.50.34

我發現 java.time 的一個優點是,代碼明確表示我們在運行應用程序的 JVM 的默認時區獲取時間。

你的代碼出了什么問題?

添加您查詢的城市的時區偏移是錯誤的。 Unix 時間戳與時區無關。 因此,如果您乘以 1000 並提供給new Date(long) ,您將獲得一個保存正確時間點的Date 如果添加非零偏移量,則會得到錯誤的時間點。 你的模擬器給了你預期的結果,那為什么呢? 這可能是因為與 JSON 的偏移量為 0(零),或者因為模擬器使用與您預期不同的默認時區來平衡錯誤。

問題:java.time 不需要 Android API 26 級嗎?

java.time 在新舊 Android 設備上都能很好地工作。 它只需要至少Java 6

  • 在 Java 8 及更高版本以及更新的 Android 設備(從 API 級別 26)中,現代 API 是內置的。
  • 在非 Android Java 6 和 7 中獲取 ThreeTen Backport,現代類的 backport(ThreeTen 用於 JSR 310;請參閱底部的鏈接)。
  • 在(較舊的)Android 上使用 ThreeTen Backport 的 Android 版本。 它叫做 ThreeTenABP。 並確保使用子包從org.threeten.bp導入日期和時間類。

鏈接

Date (long date)構造函數文檔說:

分配一個 Date object 並將其初始化為表示自稱為“紀元”的標准基准時間以來指定的毫秒數,即 1970 年 1 月 1 日,00:00:00 GMT

這意味着該值應該是 UTC。 格式化顯示日期時,必須應用以秒為單位的時間偏移量。

long numberOfsecondsRise = json.getJSONObject("city").getInt("timezone");
Date rise = new java.util.Date(json.getJSONObject("city").getLong("sunrise") * 1000L);

int offsetMinutes = numberOfsecondsRise / 60;
String sign = (offsetMinutes < 0 ? "-" : "+");
offsetMinutes = Math.abs(offsetMinutes);
String timeZoneID = String.format("GMT%s%d:%02d", sign, offsetMinutes / 60, offsetMinutes % 60);

DateFormat dfa = DateFormat.getTimeInstance();
dfa.setTimeZone(TimeZone.getTimeZone(timeZoneID));
sunFiled.setText(getResources().getString(R.string.sunrise) + ": " + dfa.format(rise));

暫無
暫無

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

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