【问题标题】:Showing correct sunrise/sunset times using unix timestamp使用 unix 时间戳显示正确的日出/日落时间
【发布时间】:2020-05-07 17:22:32
【问题描述】:

我从 DarkSkyApi 获取所选位置的日出和日落时间的 UNIX 时间戳,我想将其转换为 DateTime 格式并将其显示给用户。我希望时间值是本地的。

示例:用户在意大利并选择“Tokyo, JP”作为获取天气信息的所需位置。日出和日落时间值应格式化并显示为当地时间。所以对于东京来说,日出应该在凌晨 4 点 34 分和晚上 18 点 36 分左右才能看到日落。

就我现在所拥有的而言,我得到了错误的值,例如日出 12:17 和日落 2:29。关于我在这里做错了什么有什么想法吗?

附: tmz var 是所选位置的时区,因此在本例中为“亚洲/东京”。这是我现在在日落时间(日出时间相同)所做的事情:

private fun setViewHolderWeekDaySunsetTime(holder: ViewHolder, sunsetTime: Long, tmz: String) {
    val dt = Instant.ofEpochSecond(sunsetTime).atZone(
        ZoneId.of(tmz)
    )
    val formatted = dt.format(DateTimeFormatter.ofPattern("HH:mm"))
    holder.weekDaySunsetTime.text = formatted
}

【问题讨论】:

  • 您没有使用 unix 时间戳,而是将其乘以 1000。因此您正在对未来 50000 年左右的日期进行日期格式化。登录dt查看
  • @FrankNeblung 我不应该将它乘以 1000 以获得以毫秒为单位的纪元时间吗?
  • 可以在线查看unix时间戳的含义here。在线转换 System.currentTimeMillis here
  • @FrankNeblung 如果我不将 unix 时间戳乘以 1000,我会得到这个 unix time = 1588930440 sunset time = 1970-01-19T11:22:10.440+02:00[Europe/Athens]。当我乘以它时,我得到:unix time = 1588930440 sunset time = 2020-05-08T12:34+03:00[Europe/Athens] 使用此日志语句Log.i("WEEKLYWEATHER","unix time = $sunsetTime sunset time = $dt")
  • 应该格式化并显示为当地时间 - 这是一种会导致时区问题的愚蠢想法。本地到where - 用户(在意大利)还是到日落(在日本)?为什么不显示sunsetTimetmzholder 的实际值?

标签: android kotlin datetime-format darksky


【解决方案1】:

听起来 api 会根据您请求数据的城市返回不同的时区

因此考虑到这一点,在将时间戳转换为日期时间对象时,您需要执行以下操作:

import java.time.*

val dt = Instant.ofEpochSecond(/*put time value here*/)
                .atZone(/*put time zone here*/)
                .toLocalDateTime() //this will convert it to your system's date time

【讨论】:

  • 这仍然使用val dt = Instant.ofEpochSecond(sunsetTime).atZone( ZoneId.of(tmz) ).toLocalDateTime()而不是2020-05-08T20:23返回unix time = 1588930440 sunset time = 2020-05-08T12:34
  • 好的,我不熟悉暗夜 API。我想知道时间戳是否为UTC,无论位置在哪里,然后他们只是礼貌地给你时区。所以尝试将时区设置为 UTC,看看会发生什么 .atZone(ZoneId.of("UTC"))
  • 它现在返回unix time = 1588930440 sunset time = 2020-05-08T09:34。来自黑暗的天空 api doc:“时间:此数据点开始的 UNIX 时间。每日数据点(我正在使用的)始终与当天的午夜对齐,全部根据当地时区。”和 Timezone : "timezone (e.g. America/New_York) required 所请求位置的 IANA 时区名称。"
【解决方案2】:

使用此功能查找您想要的每个地方的时区及其纬度和经度:

fun timezonecalculator(latitude:Double,longitude:Double):Double {
    val resultTimeZone = TimezoneMapper.latLngToTimezoneString(latitude, longitude)
    var tz= TimeZone.getTimeZone(resultTimeZone).getDisplayName(
        TimeZone.getTimeZone(resultTimeZone).inDaylightTime(Date()), TimeZone.SHORT)
    if ((tz=="GMT")||(tz=="UTC")||(tz=="WET"))
        tz+="+00:00"
    if ((tz=="CST")||(tz=="MDT"))
        tz+="-06:00"
    if (tz=="AST")
        tz+="-04:00"
    if ((tz=="EST")||(tz=="CDT"))
        tz+="-05:00"
    if (tz=="MST")
        tz+="+05:00"
    if ((tz=="CET")||(tz=="BST"))
        tz+="+01:00"
    if (tz=="EET")
        tz+="+02:00"
    if (tz=="CEST")
    {tz+="+02:00"
        tz=tz.drop(1)}
    if (tz=="PDT")
        tz+="-07:00"
    if (tz=="EDT")
        tz+="-04:00"
    if (tz=="EEST")
    {tz+="+03:00"
    tz=tz.drop(1)}
    if (tz=="WEST")
    {tz+="+01:00"
        tz=tz.drop(1)}
    var sign=tz[3]
    tz=tz.drop(4)
    val minute=tz.drop(3)
    val hour=tz.dropLast(3)
    val min=Integer.parseInt(minute)
    val hou=Integer.parseInt(hour)
    var timezone=hou+(min.toDouble()/60)
    if (sign=='-')
        timezone*=-1
    return timezone
}

TimeZoneMapper 类是https://raw.githubusercontent.com/drtimcooper/LatLongToTimezone/master/src/main/java/com/skedgo/converter/TimezoneMapper.java

看这里了解如何使用这个类:https://github.com/drtimcooper/LatLongToTimezone

你可以这样调用它:timezonecalculator(latitude, longitude)

示例:timezonecalculator(36.2, 59.6) 输出:4.5

【讨论】:

    猜你喜欢
    • 2010-10-02
    • 1970-01-01
    • 2011-10-01
    • 2018-09-03
    • 2015-06-14
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多