当前位置: 首页 > 知识库问答 >
问题:

使用Openweather API获取特定日期的天气-解析JSON响应

湛光明
2023-03-14

我正在尝试使用Android studio和Java构建一个简单的天气预报应用程序。我在这里遵循了一些指示(https://www.androdocs.com/html" target="_blank">java/creating-an-android-weather-app-using-java.html)要启动并运行,这是可行的。然而,我只能得到当前的天气。Openweather预测API调用似乎持续了5天。没关系,但如何获得用户指定的特定日期的天气-比如温度和风速-在未来5天内?

下面是一个JSON响应示例(简短)。即使我可以在中午12点左右取出特定日期的信息,并获得该日期的温度和风速,这也足够了。如何解析这个JSON响应来获取特定日期的温度和风速?非常感谢...抱歉,我是初学者...

{“cod”:“200”,“message”:0,“cnt”:40,“list”:[{“dt”:1574283600,“main”:{“temp”:281.75,“temp_min”:281.68,“temp_max”:281.75,“pressure”:995,“sea_level”:995,“grnd_level”:980,“湿度”:93,“temp_kf”:0.07},“天气”:[{“id”:501,“main”:“Rain”,“description”:“moderate rain”,“icon”:“10n”}],“clouds”:{“all”:100},“wind”:{“speed”:4.82,“deg”:147},“rain”:{“3h”:5.38},“sys”:{“pod”:“n”},“dt_txt”:“2019-11-20 21:00:00”},{“dt”:1574294400,“main”:{“temp”:281.79,“temp_min”:281.74,“temp_max”:281.79,“pressure”:995,“sea_level”:995,“grnd_level”:980,“湿度”:91,“temp_kf”:0.05},“天气”:[{“id”:9 500,“main”:“Rain”,“description”:“light rain”,“icon”:“10n”}],“clouds”:{“all”:100},“wind”:{“speed”:5.55,“deg”:140},“rain”:{“3h”:1.75},“sys”:{“pod”:“n”},“dt_txt”:“2019-11-21 00:00:00”},{“dt”:1574305200,“main”:{“temp”:279.48,“temp_min”:279.44,“temp_max”:279.48,“pressure”:994,“sea_level”:994,“grnd_level”:980,“湿度”:95,“temp_kf”:0.04},“天气”:[{“id”:500,“main”:“Rain”,“description”:“light rain”,“icon”:“10n”}],“clouds”:{“all”:100},“wind”:{“speed”:2.37,“deg”:155},“rain”:{“3h”:0.94},“sys”:{“pod”:“n”},“dt_txt”:“2019-11-21 03:00:00”},{“dt”:1574316000,“main”:{“temp”:278.56,“temp_min”:278.54,“temp_max”:278.56,“气压”:995,“sea_level”:995,“grnd_level”:980,“湿度”:94,“temp_kf”:0.02},“天气”:[{“id”:500,“主要”:“雨”,“描述”:“小雨”,“图标”:“10n”}],“云”:{“所有”:100},“风”:{“速度”:1.73,“deg” :128},“rain”:{“3h”:0.06},“sys”:{“pod”:“n”},“dt_txt”:“2019-11-21 06:00:00”},{“dt”:1574326800,“main”:{“temp”:279.19,“temp_min”:279.19,“temp_max”:279.19,“pressure”:995,“sea_level”:995,“grnd_level”:981,“湿度”:95,“temp_kf”:0},“天气”:[{“id”:804,“main”:“Clouds”,“description”:“overcast clouds”,“icon”:“04d”}],“clouds”:{“all”:100},“wind”:{“speed”:1.79,“deg”:104},“sys”:{“pod”:“d”},“dt_txt”:“2019-11-21 09:00:00”},{“dt”:1574337600,“main”:{“temp”:282.2,“temp_min”:282.2,“temp_max”:282.2,“pressure”:995,“sea_level”:995,“grnd_level”:980,“湿度”:85,“temp_kf”:0},“天气”:[{“id”:500,“main”:“Rain”,“description”:“light rain”,“icon”:“10d”}],“clouds”:{“all”:100},“wind”:{“speed”:2.78,“deg”:129},“rain”:{“3h”:0.19},“sys”:{“pod”:“d”},“dt_txt”:“2019-11-21 12:00:00”}

共有2个答案

蔚琦
2023-03-14

您可以通过任何一个最流行的JSON库(如JacksonGson)将响应JSON字符串序列化为POJO,然后检索日期字段等于给定日期的对象所需的字段。顺便说一句,您的JSON字符串无效,]}在它的末尾缺失。

波霍

@JsonIgnoreProperties(ignoreUnknown = true)
class Response {
    List<Weather> list;

    //general getters and setters
}

@JsonIgnoreProperties(ignoreUnknown = true)
class Weather {
    JsonNode main;
    JsonNode wind;

    @JsonProperty("dt_txt")
    String dtTxt;

    //general getters and setters
}

使用@JsonIgnoreProperties(由 Jackson 提供)忽略序列化时不关心的字段。

代码片段

ObjectMapper mapper = new ObjectMapper();
Response response = mapper.readValue(jsonStr, Response.class);

String givenDate = "2019-11-21 12:00:00";
response.getList().forEach(e -> {
    if (givenDate.equals(e.getDtTxt())) {
        System.out.println("temp: " + e.getMain().get("temp").asText());
        System.out.println("wind speed:" + e.getWind().get("speed").asText());
    }
});

控制台输出

温度:282.2
风速:2.78

曹旭
2023-03-14

下面是一个使用JSON简单库解析从OpenWeatherMap.org下载的JSON数据的示例应用程序。

package work.basil.example;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Weather
{

    public static void main ( String[] args )
    {

        Weather app = new Weather();
        app.demo();
    }

    private void demo ( )
    {
        //Creating a JSONParser object
        JSONParser jsonParser = new JSONParser();
        try
        {
            // Download JSON.
            String yourKey = "b6907d289e10d714a6e88b30761fae22";
            URL url = new URL( "https://samples.openweathermap.org/data/2.5/forecast/hourly?zip=79843&appid=b6907d289e10d714a6e88b30761fae22" + yourKey ); // 79843 = US postal Zip Code for Marfa, Texas.
            URLConnection conn = url.openConnection();
            BufferedReader reader = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );


            // Parse JSON
            JSONObject jsonObject = ( JSONObject ) jsonParser.parse( reader );
            System.out.println( "jsonObject = " + jsonObject );

            JSONArray list = ( JSONArray ) jsonObject.get( "list" );
            System.out.println( "list = " + list );

            // Loop through each item
            for ( Object o : list )
            {
                JSONObject forecast = ( JSONObject ) o;

                Long dt = ( Long ) forecast.get( "dt" );          // Parse text into a number of whole seconds.
                Instant instant = Instant.ofEpochSecond( dt );    // Parse the count of whole seconds since 1970-01-01T00:00Z into a `Instant` object, representing a moment in UTC with a resolution of nanoseconds.
                ZoneId z = ZoneId.of( "America/Chicago" );        // Specify a time zone using a real `Continent/Region` time zone name. Never use 2-4 letter pseudo-zones such as `PDT`, `CST`, `IST`, etc.
                ZonedDateTime zdt = instant.atZone( z );          // Adjust from a moment in UTC to the wall-clock used by the people of a particular region (a time zone). Same moment, same point on the timeline, different wall-clock time.
                LocalTime lt = zdt.toLocalTime() ;
                // … compare with lt.equals( LocalTime.NOON ) to find the data sample you desire. 
                System.out.println( "dt : " + dt );
                System.out.println( "instant : " + instant );
                System.out.println( "zdt : " + zdt );

                JSONObject main = ( JSONObject ) forecast.get( "main" );
                System.out.println( "main = " + main );


                Double temp = ( Double ) main.get( "temp" );  // Better to use BigDecimal instead of Double for accuracy. But I do not know how to get the JSON-Simple library to parse the original string input as a BigDecimal.
                System.out.println( "temp = " + temp );

                JSONObject wind = ( JSONObject ) forecast.get( "wind" );
                System.out.println( "wind = " + wind );

                System.out.println( "BASIL - wind.getCLass: " + wind.getClass() );
                Double speed = ( Double ) wind.get( "speed" );
                System.out.println( "speed = " + speed );

                System.out.println( "\n" );
            }
        }
        catch ( FileNotFoundException e )
        {
            e.printStackTrace();
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }
        catch ( ParseException e )
        {
            e.printStackTrace();
        }
    }
}

请注意,当遇到缺少十进制分隔符的风速数据点时,此代码会爆炸。例如,该数据的发布者应该编写1.0而不是1以保持一致性。如果他们这样做了,库会将1.0解析为Double,而不是将1解析为Long

此外,这段代码使用了JSON Simple的原始版本1,现在已经失效。这个项目被分叉,产生了截然不同的版本2

有关解析十进制问题和指向分叉项目的链接的详细信息,请参阅此页面,使用 JSON 简单 (Java) 在 JSON 数据中解析十进制数(其中一些缺少小数分隔符)。

因此,虽然我不建议将这段代码用于生产,但它可能会对您有所帮助。对于实际工作,可以考虑JSON-Simple的第3版或其他几个可用于Java的JSON处理库。

请参阅此URL上的示例数据。要使其可读,请使用文本编辑器或IDE重新格式化JSON数据。

样本输出:

dt : 1553709600
instant : 2019-03-27T18:00:00Z
zdt : 2019-03-27T13:00-05:00[America/Chicago]
main = {"temp":286.44,"temp_min":286.258,"grnd_level":1002.193,"temp_kf":0.18,"humidity":100,"pressure":1015.82,"sea_level":1015.82,"temp_max":286.44}
temp = 286.44
wind = {"deg":202.816,"speed":5.51}
speed = 5.51


dt : 1553713200
instant : 2019-03-27T19:00:00Z
zdt : 2019-03-27T14:00-05:00[America/Chicago]
main = {"temp":286.43,"temp_min":286.3,"grnd_level":1002.667,"temp_kf":0.13,"humidity":100,"pressure":1016.183,"sea_level":1016.183,"temp_max":286.43}
temp = 286.43
wind = {"deg":206.141,"speed":4.84}
speed = 4.84
 类似资料:
  • 在使用date格式自动设置为IE后,我试图解析某个包含日期条目为纪元数值的json文档。我需要不同的格式(也需要一毫秒) 所以问题是,如何解析IE。转换为带有Bson文档的某种自定义格式字符串。解析方法? 编辑:只是一个更新:问题在document.parse方法中,因为我不知道如何在解析json文档时使用tell.parse函数来使用自定义的日期格式。我总是得到某种默认的日期格式。如何发送给.p

  • 问题内容: 在我的VB.NET项目中,使用JSON.NET,我从Web API获得了一个JSON,该JSON的值表示格式中的日期,我想简单地获取该值。 JSON大致如下所示: 所以我应该序列化它,然后使用该值执行操作,对吗?但是,当我将该键值放入变量中时,日期格式会自动更改! 我需要具有从检索到的JSON中获取的Date。我看到解决此问题的两种方法:将其手动转换,或使用正则表达式直接获取键值对-两

  • 本文向大家介绍利用shell获取指定日期前N天的日期,包括了利用shell获取指定日期前N天的日期的使用技巧和注意事项,需要的朋友参考一下 一、创建测试文件test.sh 二、无参运行 三、传参运行 总结 以上就是利用shell获取指定日期前N天日期的全部内容,希望本文的内容对大家的学习或者工作能有所帮助,如果有疑问大家可以留言交流。

  • 问题内容: 我正在尝试使用其开放的API获取特定Subreddit的顶级提交列表: 不幸的是,这不起作用,因为实际的提交列表嵌套在响应中。如何将数据json数组(在元素中)解组为struct 类型的数组? 问题答案: 创建更多模拟JSON确切形状的结构(就像您的结构一样)。解组到最顶层的结构之一,然后访问该结构的适当成员。

  • 本文向大家介绍android JSON解析数据 android解析天气预报,包括了android JSON解析数据 android解析天气预报的使用技巧和注意事项,需要的朋友参考一下 概要 笔者近期做到对天气预报JSON数据解析,在此小记。 天气预报接口:http://wthrcdn.etouch.cn/weather_mini?citykey=101200101 JSON数据如下: 最终解析效果

  • 你好:)我正在写一个电报机器人,显示今天和明天的天气。作为我正在使用的数据openweathermap.org. 现在,我使用了getTodaysWeather方法从JSON中获取有关Java对象的信息http://www.jsonschema2pojo.org并写道: 现在,我需要编写一个方法,从JSON数据中获取明天的天气数据http://api.openweathermap.org/data