【问题标题】:Why do I keep getting the wrong date/time when converting from a UTC timestamp?从 UTC 时间戳转换时,为什么我总是收到错误的日期/时间?
【发布时间】:2020-05-11 16:22:12
【问题描述】:

我正在尝试制作一个天气预报应用程序,并且我从 api 获得了一个 UTC 时间戳:OpenWeatherMap。我通过创建 Date 对象将其转换为日期。例如,对于 UTC 时间戳 1589220000,UTC 时间是 5 月 11 日下午 6 点。我做这个转换,我总是得到 5 月 11 日下午 2 点。巧合的是,我确实住在一个时间比 UTC 晚 4 小时的地方,但是当我使用假 gps 位置转换器测试我的应用程序时,我仍然得到了 5 月 11 日下午 2 点。这表明 Android 没有根据我当前的位置创建日历,因为以迪拜的时区为例,它并没有落后 4 小时。

这是我的代码:

public String convertDate(long unixTimeStamp) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("EEEE, MMM d, h:mm aaa");
        Date date = new Date(unixTimeStamp*1000 );
        String nowDate = dateFormat.format(date);

        return nowDate;
    }

【问题讨论】:

  • 您的目标是哪个 API 级别?无论如何,您应该使用 java.time 包中的类。然后,您可以简单地使用Instant.ofEpochSecond 获得Instant,然后可以将其转换为OffsetDateTime,然后可以使用DateTimeFormatter 对其进行格式化。

标签: java android android-studio date utc


【解决方案1】:

帮自己一个忙,使用java.time.* 而不是Date/SimpleDateFormat

如果您不能使用 API 26/Gradle 4.x 或更高版本(因此可以访问 Java 8),请使用 https://www.threeten.org/threetenbp/,直到可以使用,您可以通过 Jake Wharton 的改编在 Android 上使用它:https://github.com/JakeWharton/ThreeTenABP

要转换自纪元以来的瞬间:

    val instant = Instant.ofEpochMilli(milliseconds)

    val result = instant.atOffset(ZoneOffset.UTC).toLocalDateTime() //for example

有很多方法可以玩。

不要忘记初始化要加载的 TimeZone 数据库的库。在您的 Application 课程中,将此添加到 onCreate()

    AndroidThreeTen.init(this)

要格式化你的日期,你可以继续上面的“结果”:

val result = ...
result.format(DateTimeFormatter...)

有很多 DateTimeFormatter 辅助函数,阅读文档,它非常容易使用。

其中一个是ofPattern(...)

DateTimeFormatter
   .ofPattern("EEEE, MMM d, h:mm aaa")
   .withLocale(Locale.US) // you can use systemDefault or chose another

天空,是极限。

【讨论】:

  • 好的和有用的答案。由于提问者有一个以秒为单位的时间戳(不是毫秒),Instant.ofEpochSecond() 更加有用。
【解决方案2】:

SimpleDateFormat上没有设置时区,所以会得到JVM的默认时区:

dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

Demo

【讨论】:

  • 嘿,这确实有效,谢谢你的演示。我像您一样手动设置时区,并且可以正常工作。还有一个问题。我可以从世界各地的许多城市获取天气数据,这个 api 以秒为单位给出一个时区偏移量,无论是负数还是正数。这是否意味着我可以采用 UTC 时间,并添加偏移秒数 * 1000 以获得该城市的当地时间?即我的位置落后 4 小时,而 api 给了我 -14400 秒。我可以(时间戳 * 1000L + offset_seconds * 1000L)吗?
猜你喜欢
  • 2018-12-21
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多