【问题标题】:Convert current time(dt) from seconds to real time format(hour and minute)将当前时间(dt)从秒转换为实时格式(小时和分钟)
【发布时间】:2021-05-11 13:24:28
【问题描述】:

我能够使用来自 JSON 响应的改造在我的应用程序上显示一些天气数据,但当前时间 (dt)、日出和日落在我的文本视图上显示为秒,即 1612730263。 所以我需要将时间转换为实时格式(小时和分钟),例如晚上 9:30。 免责声明Java: Date from unix timestampHow to convert seconds to time format? 对我不起作用,因为我的响应来自 API。因此我的问题不是重复的。

我的 API 响应:

    {
   "lat":9.0765,
   "lon":7.3986,
   "timezone":"Africa/Lagos",
   "timezone_offset":3600,
   "current":{
      "dt":1612779720,
      "sunrise":1612763455,
      "sunset":1612805901,
      "temp":304.15,
      "feels_like":302.14,
      "pressure":1013,
      "humidity":33,
      "dew_point":286,
      "uvi":8.42,
      "clouds":42,
      "visibility":7000,
      "wind_speed":4.12,
      "wind_deg":100,
      "weather":[
         {
            "id":802,
            "main":"Clouds",
            "description":"scattered clouds",
            "icon":"03d"
         }
      ]
   }
}

HomeActivity 中我的 Retrofit 调用:

Retrofit retrofit = new Retrofit.Builder().baseUrl(BaseUrl).addConverterFactory(GsonConverterFactory.create()).build();
        WeatherService service = retrofit.create(WeatherService.class);
        Call<WeatherResponse> call = service.getCurrentWeatherData(lat, lon, AppId);
        call.enqueue(new Callback<WeatherResponse>() {

            @Override
            public void onResponse(@NonNull Call<WeatherResponse> call, @NonNull Response<WeatherResponse> response) {
                if (response.code() == 200) {
                    WeatherResponse weatherResponse = response.body();
                    assert weatherResponse != null;

                    assert response.body() != null;
// current time textview
                  time_field.setText(String.valueOf(response.body().getCurrent().getDt()));

我在 FirstFragment 中的 Retrofit 调用:

Retrofit retrofit = new Retrofit.Builder().baseUrl(BaseUrl).addConverterFactory(GsonConverterFactory.create()).build();
                WeatherService service = retrofit.create(WeatherService.class);
                Call<WeatherResponse> call = service.getCurrentWeatherData(lat, lon, AppId);
                call.enqueue(new Callback<WeatherResponse>() {
                    @Override
                    public void onResponse(@NonNull Call<WeatherResponse> call, @NonNull Response<WeatherResponse> response) {
                        if (response.code() == 200) {
                            WeatherResponse weatherResponse = response.body();
                            assert weatherResponse != null;

                            assert response.body() != null; 
// sunrise & sunset time textviews                                                             
rise_time.setText(response.body().getCurrent().getSunrise() + " AM");                                
set_time.setText(response.body().getCurrent().getSunset() + " PM");

编辑

WeatherResponse.java

public class WeatherResponse {

    @SerializedName("lat")
    @Expose
    private Double lat;
    @SerializedName("lon")
    @Expose
    private Double lon;
    @SerializedName("timezone")
    @Expose
    private String timezone;
    @SerializedName("timezone_offset")
    @Expose
    private Integer timezoneOffset;
    @SerializedName("current")
    @Expose
    private Current current;

    public Double getLat() {
        return lat;
    }

    public void setLat(Double lat) {
        this.lat = lat;
    }

    public Double getLon() {
        return lon;
    }

    public void setLon(Double lon) {
        this.lon = lon;
    }

    public String getTimezone() {
        return timezone;
    }

    public void setTimezone(String timezone) {
        this.timezone = timezone;
    }

    public Integer getTimezoneOffset() {
        return timezoneOffset;
    }

    public void setTimezoneOffset(Integer timezoneOffset) {
        this.timezoneOffset = timezoneOffset;
    }

    public Current getCurrent() {
        return current;
    }

    public void setCurrent(Current current) {
        this.current = current;
    }

}

Current.java

public class Current {

    @SerializedName("dt")
    @Expose
    private Integer dt;
    @SerializedName("sunrise")
    @Expose
    private Integer sunrise;
    @SerializedName("sunset")
    @Expose
    private Integer sunset;
    @SerializedName("temp")
    @Expose
    private Double temp;
    @SerializedName("feels_like")
    @Expose
    private Double feelsLike;
    @SerializedName("pressure")
    @Expose
    private Integer pressure;
    @SerializedName("humidity")
    @Expose
    private Integer humidity;
    @SerializedName("dew_point")
    @Expose
    private Double dewPoint;
    @SerializedName("uvi")
    @Expose
    private Double uvi;
    @SerializedName("clouds")
    @Expose
    private Integer clouds;
    @SerializedName("visibility")
    @Expose
    private Integer visibility;
    @SerializedName("wind_speed")
    @Expose
    private Double windSpeed;
    @SerializedName("wind_deg")
    @Expose
    private Integer windDeg;
    @SerializedName("weather")
    @Expose
    private List<Weather> weather = null;

    public Integer getDt() {
        return dt;
    }

    public void setDt(Integer dt) {
        this.dt = dt;
    }

    public Integer getSunrise() {
        return sunrise;
    }

    public void setSunrise(Integer sunrise) {
        this.sunrise = sunrise;
    }

    public Integer getSunset() {
        return sunset;
    }

    public void setSunset(Integer sunset) {
        this.sunset = sunset;
    }

    public Double getTemp() {
        return temp;
    }

    public void setTemp(Double temp) {
        this.temp = temp;
    }

    public Double getFeelsLike() {
        return feelsLike;
    }

    public void setFeelsLike(Double feelsLike) {
        this.feelsLike = feelsLike;
    }

    public Integer getPressure() {
        return pressure;
    }

    public void setPressure(Integer pressure) {
        this.pressure = pressure;
    }

    public Integer getHumidity() {
        return humidity;
    }

    public void setHumidity(Integer humidity) {
        this.humidity = humidity;
    }

    public Double getDewPoint() {
        return dewPoint;
    }

    public void setDewPoint(Double dewPoint) {
        this.dewPoint = dewPoint;
    }

    public Double getUvi() {
        return uvi;
    }

    public void setUvi(Double uvi) {
        this.uvi = uvi;
    }

    public Integer getClouds() {
        return clouds;
    }

    public void setClouds(Integer clouds) {
        this.clouds = clouds;
    }

    public Integer getVisibility() {
        return visibility;
    }

    public void setVisibility(Integer visibility) {
        this.visibility = visibility;
    }

    public Double getWindSpeed() {
        return windSpeed;
    }

    public void setWindSpeed(Double windSpeed) {
        this.windSpeed = windSpeed;
    }

    public Integer getWindDeg() {
        return windDeg;
    }

    public void setWindDeg(Integer windDeg) {
        this.windDeg = windDeg;
    }

    public List<Weather> getWeather() {
        return weather;
    }

    public void setWeather(List<Weather> weather) {
        this.weather = weather;
    }
}

我需要将提供的代码链接到我的应用程序,以便更容易实施。我有 dt 转换的基本知识,但不是来自天气 API 响应。我认为使用我的 textviews 来转换数据会更好(如果有任何方法可以使用我的 textviews 来做)

【问题讨论】:

  • 您需要阅读您正在调用的 Web 服务的文档,以确定如何解释 JSON 中返回的值。时间值看起来像自 Unix 纪元以来的秒数。
  • 我已经阅读了完整的文档openweathermap.org/api/one-call-api,没有说明如何解释这些值
  • 您链接到的页面有一个“API 响应中的字段”部分,描述了如何解释响应中的值。
  • 这正是我在改造中所称的领域。好吧,我想你说得有道理,数据以秒为单位显示,所以我需要将其实时转换为小时和分钟
  • 这能回答你的问题吗? Java: Date from unix timestamp

标签: java android api datetime retrofit


【解决方案1】:

只需使用该值作为参数创建一个日期对象:

java.util.Date time=new java.util.Date(((long)timeStamp)*1000);

由于 java 期望毫秒作为参数,您需要将值(以秒为单位)乘以 1000。

【讨论】:

  • 在我的代码上写了这个,上面写着'时间从不使用'并且代码不起作用
  • @Chinez 在使用 API 之前,您应该了解一些基础知识,例如如何使用变量和对象……我发布的代码会根据您提供的任何时间戳创建一个 Date 对象。在这里,您的时间戳是dt 的结果,您可以使用基本的字符串操作将其隔离。我不会提供准备烘焙的代码,但还有一些关键字需要研究:String.splitjava DateSimpleDateFormatjava parse Integer
  • 好吧,我在工作之前学习了基础知识。你不需要提供准备烘焙的代码,如果你知道怎么做就回答,谢谢
  • @Chinez 尝试查看我发送的关键字,看看它们是否可以帮助您解决问题。
【解决方案2】:

您可以使用Instant#ofEpochSecond获取Instant,您可以将其转换为指定时区ID的ZonedDateTime,然后使用DateTimeFormatter格式化获取的ZonedDateTime

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(
                "Sunrise date and time with timezone: " + getDateTimeWithTzString(1608529251L, "Africa/Lagos"));
        System.out.println("Sunrise date and time: " + getDateTimeString(1608529251L, "Africa/Lagos"));
        System.out.println("Sunrise time: " + getTimeString(1608529251L, "Africa/Lagos"));
        System.out.println("Date: " + getDateString(1608529251L, "Africa/Lagos"));
    }

    static String getDateTimeWithTzString(long epochSecond, String strTz) {
        ZoneId zoneId = ZoneId.of(strTz);
        Instant instant = Instant.ofEpochSecond(epochSecond);
        ZonedDateTime zdt = instant.atZone(zoneId);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd h:m:s a '['VV']'", Locale.ENGLISH);
        return zdt.format(dtf);
    }

    static String getDateTimeString(long epochSecond, String strTz) {
        ZoneId zoneId = ZoneId.of(strTz);
        Instant instant = Instant.ofEpochSecond(epochSecond);
        ZonedDateTime zdt = instant.atZone(zoneId);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd h:m:s a", Locale.ENGLISH);
        return zdt.format(dtf);
    }

    static String getTimeString(long epochSecond, String strTz) {
        ZoneId zoneId = ZoneId.of(strTz);
        Instant instant = Instant.ofEpochSecond(epochSecond);
        ZonedDateTime zdt = instant.atZone(zoneId);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("h:m:s a", Locale.ENGLISH);
        return zdt.format(dtf);
    }

    static String getDateString(long epochSecond, String strTz) {
        ZoneId zoneId = ZoneId.of(strTz);
        Instant instant = Instant.ofEpochSecond(epochSecond);
        ZonedDateTime zdt = instant.atZone(zoneId);
        return zdt.toLocalDate().toString();
    }
}

输出:

Sunrise date and time with timezone: 2020-12-21 6:40:51 AM [Africa/Lagos]
Sunrise date and time: 2020-12-21 6:40:51 AM
Sunrise time: 6:40:51 AM
Date: 2020-12-21

通过 Trail: Date Time 了解有关现代日期时间 API 的更多信息。

无论出于何种原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7。如果您是为 Android 项目工作,而您的 Android API 级别仍不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

【讨论】:

  • 感谢您为帮助我所做的努力,但这并没有奏效,因为这就像获得一个独立的时间(与应用程序分开),它与应用程序没有链接,因此无法运行它t 以小时/分钟格式显示
【解决方案3】:
String timezone = "Africa/Lagos"; // "timezone":"Africa/Lagos"
long dt = 1612779720L; // "dt":1612779720
long sunriseTime = 1612763455L; // "sunrise":1612763455
long sunsetTime = 1612805901L; // "sunset":1612805901
double temp = 304.15D; // "temp":304.15 (in Kelvin).
        
SimpleDateFormat sdf = new SimpleDateFormat("h:mm aa"); // h:mm AM/PM (hh:mm aa == hh:mm AM/PM).
sdf.setTimeZone(TimeZone.getTimeZone(timezone));
        
// current local time
String time = sdf.format(new Date(dt));
// sunrise
String sunrise = sdf.format(new Date(sunriseTime));
// sunset
String sunset = sdf.format(new Date(sunsetTime));
// temperature in Celcius
String celcius = String.format("%.2f °C", temp - 273.16D);
// temperature in Fahrenheit
String fahrenheit = String.format("%.2f °F", ((temp - 273D) * 9D/5D) + 32D);
        
System.out.println(time); //4:59 PM
System.out.println(sunrise); //4:59 PM
System.out.println(sunset); //5:00 PM
System.out.println(celcius); //30.99 °C
System.out.println(fahrenheit); //88.07 °F

【讨论】:

  • 使用此代码。虽然它没有给出任何错误,但它不起作用。我认为使用我的 textviews 来转换数据会更好(如果有的话你可以使用我的 textviews 来做)
  • response.body().getCurrent()。这返回什么类型的类?是WeatherResponse吗?例如WeatherResponse curr = response.body().getCurrent()?
  • 使用 API openweathermap.org/api/one-call-api,当前类返回一些当前天气数据。我已经包含了源代码以获取更多信息
  • 很抱歉回复晚了,最近上课很忙
【解决方案4】:

您似乎需要从WeatherResponse 和相关类中返回的信息中获取正确的日期模式。

为此,您需要自定义您在代码中使用的 Gson 库,以通过 Retrofit 反序列化 openweathermap API 返回的信息。

有几种方法可以做到这一点,但只要您有能力修改jsonschema2pojo 生成的类,我建议采用以下方法。

这个想法基本上在于实现一个custom Gson deserializer 来处理所需的转换。

您可以选择为整个 Current 类实现此自定义反序列化器,但我认为只处理必要字段的反序列化会更容易。

为此,首先,让我们创建一个新类型;它将作为需要自定义反序列化的字段的标记。例如:

public class PrettyTime {

  private String value;

  public PrettyTime() {
  }

  public PrettyTime(String value) {
    this.value = value;
  }

  public String getValue() {
    return value;
  }

  public void setValue(String value) {
    this.value = value;
  }

  @Override
  public String toString() {
    return getValue();
  }
}

将此标记应用于Current 类中需要转换的字段:

public class Current {

  @SerializedName("dt")
  @Expose
  private PrettyTime dt;
  @SerializedName("sunrise")
  @Expose
  private PrettyTime sunrise;
  @SerializedName("sunset")
  @Expose
  private PrettyTime sunset;

  // The rest of the fields and setters and getters

  public PrettyTime getDt() {
    return dt;
  }

  public void setDt(PrettyTime dt) {
    this.dt = dt;
  }

  public PrettyTime getSunrise() {
    return sunrise;
  }

  public void setSunrise(PrettyTime sunrise) {
    this.sunrise = sunrise;
  }

  public PrettyTime getSunset() {
    return sunset;
  }

  public void setSunset(PrettyTime sunset) {
    this.sunset = sunset;
  }
  
}

接下来,让我们创建自定义反序列化器:

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.Date;

public class PrettyTimeDeserializer implements JsonDeserializer<PrettyTime> {
  // Modify the date pattern as you consider appropriate
  private static final SimpleDateFormat HMM = new SimpleDateFormat("hh:mm");

  public PrettyTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    final long seconds = json.getAsJsonPrimitive().getAsLong();
    final Date date = new Date(seconds * 1000);
    final String prettyFormatted = HMM.format(date);
    return new PrettyTime(prettyFormatted);
  }
}

最后,将此反序列化器集成到您的代码中,包括 HomeActivityFirstFragment 类:

Gson gson = new GsonBuilder()
  .registerTypeAdapter(PrettyTime.class, new PrettyTimeDeserializer())
  .create();

Retrofit retrofit = new Retrofit.Builder()
  .baseUrl(BaseUrl)
  // Please note the gson argument
  .addConverterFactory(GsonConverterFactory.create(gson))
  .build()
;

// The rest of your code

【讨论】:

  • 非常感谢您的帮助!反序列化成功了,应用程序终于实时显示了!虽然现在的问题是日出和日落显示双重 AM 和 PM,即 9:30 PM PM。我想淘汰一个,请帮忙
  • 另外,如果你想得到实际的温度,即从 temp":304.15 到 30。我会很感激,但如果你不能,我会把它作为一个新问题发布,谢谢
  • 嗨@Chinez。我很高兴听到这个答案很有帮助。当然,请参阅编辑后的答案:要从日期字符串中删除 AM/PM 部分,您需要将模式 hh:mm a 更改为 hh:mm。话虽如此,请考虑使用hh:mm a 模式,而不是之后在代码中手动添加 AM/PM。关于temp 字段问题,您可以采用与为这些日期提供的方法类似的方法,但根据API documentation,我认为更好的方法是提供units 参数。
  • 使用适当的值,例如:api.openweathermap.org/data/2.5/onecall?lat={lat}&lon={lon}&units=metric。注意单位metric 值。它将直接以摄氏度返回信息。我希望它有所帮助。
猜你喜欢
  • 2021-12-27
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多