有苹果开发者账号的可以免费调用天气接口
Apple Developer Program 的会员账号每个月自带 500,000 次(50万次)的免费调用额度。无论你是通过 iOS 原生 Swift API 还是通过后端的 REST API(如 Java)调用,这 50 万次都是共享且免费的
如果是通过后端服务器/脚本调用(REST API)
因为你前面提到要调用 API,如果是纯代码/服务器对接,需要创建一个 Service ID:
点击 Identifiers 标题右侧的蓝色
+号。
在新页面中选择 Services IDs,然后点击右上方 Continue。
填写
Description(如 WeatherKit REST)和Identifier(如com.cloudcube.weatherkit)。
创建完成后,点击当前页面右上角的 App IDs 下拉菜单,切换到 Services IDs 列表。
点击你刚创建的 Service ID,勾选 WeatherKit,并点击 Configure 关联一个你已有的主 App ID(比如关联
com.fenghuangma.fhny),然后点击 Save 保存。
配置完 Identifiers 后,点击左侧菜单栏的 Keys:
点击
+号新建一个 Key。
命名为类似
WeatherKitKey,并在列表中勾选 WeatherKit。
点击 Continue 并保存,最后下载
.p8私钥文件(注意:该文件只能下载一次,请妥善保存)。同时记录下页面上显示的 Key ID。
图标下载地址:GitHub - erikflowers/weather-icons: 215 Weather Themed Icons and CSS · GitHub
java示例
1.天气英译中
@Getter
public enum WeatherConditionCodeEnum {
CLEAR("Clear", "晴"),
MOSTLY_CLEAR("MostlyClear", "晴间多云"),
PARTLY_CLOUDY("PartlyCloudy", "多云"),
MOSTLY_CLOUDY("MostlyCloudy", "阴"),
CLOUDY("Cloudy", "阴"),
FOGGY("Foggy", "雾"),
HAZE("Haze", "霾"),
SMOKY("Smoky", "沙尘"),
WINDY("Windy", "大风"),
DRIZZLE("Drizzle", "阵雨"),
RAIN("Rain", "小雨"),
HEAVY_RAIN("HeavyRain", "大雨"),
SUN_SHOWERS("SunShowers", "太阳雨"),
FLURRIES("Flurries", "阵雪"),
SNOW("Snow", "小雪"),
HEAVY_SNOW("HeavySnow", "大雪"),
BLOWING_SNOW("BlowingSnow", "暴风雪"),
FREEZING_DRIZZLE("FreezingDrizzle", "冻雨"),
FREEZING_RAIN("FreezingRain", "冻雨"),
WINTRY_MIX("WintryMix", "雨夹雪"),
SLEET("Sleet", "雨夹雪"),
HAIL("Hail", "冰雹"),
HOT("Hot", "酷热"),
COLD("Cold", "严寒"),
BLIZZARD("Blizzard", "暴风雪"),
THUNDERSTORMS("Thunderstorms", "雷阵雨"),
STRONG_STORMS("StrongStorms", "强雷阵雨"),
SCATTERED_THUNDERSTORMS("ScatteredThunderstorms", "雷阵雨"),
ISOLATED_THUNDERSTORMS("IsolatedThunderstorms", "局地雷阵雨"),
TROPICAL_STORM("TropicalStorm", "热带风暴"),
HURRICANE("Hurricane", "台风");
private final String code;
private final String desc;
WeatherConditionCodeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
/**
* 根据 WeatherKit conditionCode 获取对应的中文描述。
*
* @param code WeatherKit 天气编码
* @return 对应中文描述,未匹配时返回“未知天气”
*/
public static String getDescByCode(String code) {
if (code == null || code.trim().isEmpty()) {
return "未知天气";
}
for (WeatherConditionCodeEnum value : values()) {
if (value.code.equalsIgnoreCase(code)) {
return value.desc;
}
}
return "未知天气";
}
}
2.请求
@Log4j2
public class WeatherKitClient {
/**
* 业务统一按上海时区处理天气小时数据。
*/
private static final ZoneId SHANGHAI_ZONE_ID = ZoneId.of("Asia/Shanghai");
/**
* WeatherKit 图标在对象存储中的目录。
*/
private static final String WEATHER_KIT_ICON_PATH = "icons/weatherkit/";
/**
* 风力等级图标前缀。
*/
private static final String WIND_BEAUFORT_ICON_PREFIX = "wi-wind-beaufort-";
/**
* WeatherKit token 官方允许的有效时长。
* 当前按 1 小时签发。
*/
private static final long WEATHER_KIT_TOKEN_EXPIRE_SECONDS = 3600L;
/**
* Redis 缓存时长。
* 按 token 有效时长减 1 分钟缓存,避免边界时刻使用到即将过期的 token。
*/
private static final long WEATHER_KIT_TOKEN_CACHE_SECONDS = WEATHER_KIT_TOKEN_EXPIRE_SECONDS - 60L;
/**
* JSON 解析器,用于将 WeatherKit 返回的 JSON 字符串转换为 Java 对象。
*/
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
// 1. 填入你的 Apple 开发者后台信息
// 可以在开发者后台右上角账户名下方看到 10 位字符
private static final String TEAM_ID = "";
// Services ID
private static final String SERVICE_ID = "";
// 10 位 Key ID
private static final String KEY_ID = "";
// 下载的 .p8 文件内容。注意:删掉 -----BEGIN PRIVATE KEY----- 和 -----END PRIVATE KEY----- 以及所有换行符
private static final String PRIVATE_KEY_CONTENT =
"";
/**
* WeatherKit token 的 Redis 缓存 key。
* 使用团队、服务、Key 组合,避免不同配置之间相互覆盖。
*/
private static final String WEATHER_KIT_TOKEN_CACHE_KEY =
RedisKeys.WEATHER_KIT_TOKEN + TEAM_ID + ":" + SERVICE_ID + ":" + KEY_ID;
/**
* 生成用于 Apple WeatherKit 认证的 ES256 JWT Token。
*/
public static String generateWeatherKitJwt() throws Exception {
// 解密纯文本的 Base64 私钥
byte[] keyBytes = Base64.getDecoder().decode(PRIVATE_KEY_CONTENT.replaceAll("\\s+", ""));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("EC"); // WeatherKit 必须使用 EC (Elliptic Curve) 算法
PrivateKey privateKey = kf.generatePrivate(spec);
Instant now = Instant.now();
Instant expiry = now.plusSeconds(WEATHER_KIT_TOKEN_EXPIRE_SECONDS);
Map<String, Object> headers = new HashMap<>();
headers.put("alg", "ES256");
headers.put("kid", KEY_ID);
headers.put("id", TEAM_ID + "." + SERVICE_ID);
// 使用已存在的 java-jwt 依赖生成 ES256 token,避免旧版 JJWT 在新 JDK 上依赖 JAXB。
return JWT.create()
.withHeader(headers)
.withIssuer(TEAM_ID)
.withIssuedAt(Date.from(now))
.withExpiresAt(Date.from(expiry))
.withSubject(SERVICE_ID)
.sign(Algorithm.ECDSA256(null, (ECPrivateKey) privateKey));
}
/**
* 获取 WeatherKit 开发者 token。
* 优先从 Redis 读取,未命中时重新生成,并按“有效期减 1 分钟”写入缓存。
*
* @return 可直接用于 Authorization Bearer 的 token
* @throws Exception 生成 token 失败时抛出异常
*/
public static String getWeatherKitJwt() throws Exception {
Object cacheToken = RedisUtil.get(WEATHER_KIT_TOKEN_CACHE_KEY);
if (cacheToken instanceof String token) {
if (!token.trim().isEmpty()) {
return token;
}
}
String token = generateWeatherKitJwt();
RedisUtil.set(WEATHER_KIT_TOKEN_CACHE_KEY, token, WEATHER_KIT_TOKEN_CACHE_SECONDS);
return token;
}
/**
* 发起 HTTP 请求获取 Apple 天气数据,并将返回结果解析为天气对象。
*
* @param lat 纬度,例如 39.9042
* @param lon 经度,例如 116.4074
* @return 成功时返回解析后的天气对象,失败时返回统一错误信息
*/
public static WeatherKitWeatherRes getWeather(Double lat, Double lon) {
try {
// 优先读取缓存中的 token,未命中时再重新生成
String token = getWeatherKitJwt();
// 拼接请求 URL
// dataSets 包含:当前天气(currentWeather)、小时预报(forecastHourly)、每日预报(forecastDaily)
String url = String.format(
"https://weatherkit.apple.com/api/v1/weather/zh-CN/%s/%s" +
"?dataSets=currentWeather,forecastHourly,forecastDaily" +
"&timezone=Asia/Shanghai",
lat, lon
);
// 发起异步或同步请求 (此处采用 Java 11 HttpClient 同步请求)
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer " + token) // 携带 JWT 令牌
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
WeatherKitWeatherRes weatherRes = OBJECT_MAPPER.readValue(response.body(), WeatherKitWeatherRes.class);
fillWeatherIcons(weatherRes);
return weatherRes;
} else {
log.error("Apple WeatherKit 请求失败,状态码: {}", response.statusCode());
log.error("错误响应体: {}", response.body());
}
} catch (Exception e) {
log.error("生成 Token 或请求过程中发生异常");
}
return null;
}
/**
* 从天气响应中获取“上海当前小时”对应的小时预报。
* 优先按上海时区当前整点精确匹配,匹配不到时返回最接近且不晚于当前时间的一条小时预报。
*
* @param weatherRes 天气响应对象
* @return 当前小时预报,不存在时返回 null
*/
public static WeatherKitWeatherRes.HourlyWeather getCurrentHourWeather(WeatherKitWeatherRes weatherRes) {
if (weatherRes == null
|| weatherRes.getForecastHourly() == null
|| weatherRes.getForecastHourly().getHours() == null
|| weatherRes.getForecastHourly().getHours().isEmpty()) {
return null;
}
ZonedDateTime now = ZonedDateTime.now(SHANGHAI_ZONE_ID);
ZonedDateTime currentHour = now.withMinute(0).withSecond(0).withNano(0);
WeatherKitWeatherRes.HourlyWeather fallback = null;
ZonedDateTime fallbackTime = null;
for (WeatherKitWeatherRes.HourlyWeather hourlyWeather : weatherRes.getForecastHourly().getHours()) {
if (hourlyWeather == null || hourlyWeather.getForecastStart() == null || hourlyWeather.getForecastStart().trim().isEmpty()) {
continue;
}
try {
ZonedDateTime forecastTime = OffsetDateTime.parse(hourlyWeather.getForecastStart())
.atZoneSameInstant(SHANGHAI_ZONE_ID)
.withMinute(0)
.withSecond(0)
.withNano(0);
if (forecastTime.equals(currentHour)) {
return hourlyWeather;
}
if (!forecastTime.isAfter(now) && (fallbackTime == null || forecastTime.isAfter(fallbackTime))) {
fallback = hourlyWeather;
fallbackTime = forecastTime;
}
} catch (Exception e) {
log.warn("解析小时预报时间失败: {}", hourlyWeather.getForecastStart(), e);
}
}
if (fallback != null) {
return fallback;
}
return weatherRes.getForecastHourly().getHours().get(0);
}
/**
* 为天气对象补全 Weather Icons 图标名。
* REST API 返回的是 conditionCode,这里统一转换为前端所使用的 weather-icons 命名。
*
* @param weatherRes 天气响应对象
*/
private static void fillWeatherIcons(WeatherKitWeatherRes weatherRes) {
if (weatherRes == null) {
return;
}
WeatherKitWeatherRes.CurrentWeather currentWeather = weatherRes.getCurrentWeather();
if (currentWeather != null) {
currentWeather.setConditionName(WeatherConditionCodeEnum.getDescByCode(currentWeather.getConditionCode()));
currentWeather.setIconName(resolveWeatherIconName(currentWeather.getConditionCode(), currentWeather.getDaylight()));
currentWeather.setIconUrl(resolveWeatherIconUrl(currentWeather.getIconName()));
currentWeather.setWindIconName(resolveWindIconName(currentWeather.getWindSpeed()));
currentWeather.setWindIconUrl(resolveWeatherIconUrl(currentWeather.getWindIconName()));
}
WeatherKitWeatherRes.ForecastHourly forecastHourly = weatherRes.getForecastHourly();
if (forecastHourly != null && forecastHourly.getHours() != null) {
for (WeatherKitWeatherRes.HourlyWeather hourlyWeather : forecastHourly.getHours()) {
if (hourlyWeather != null) {
hourlyWeather.setConditionName(WeatherConditionCodeEnum.getDescByCode(hourlyWeather.getConditionCode()));
hourlyWeather.setIconName(resolveWeatherIconName(hourlyWeather.getConditionCode(), hourlyWeather.getDaylight()));
hourlyWeather.setIconUrl(resolveWeatherIconUrl(hourlyWeather.getIconName()));
hourlyWeather.setWindIconName(resolveWindIconName(hourlyWeather.getWindSpeed()));
hourlyWeather.setWindIconUrl(resolveWeatherIconUrl(hourlyWeather.getWindIconName()));
}
}
}
WeatherKitWeatherRes.ForecastDaily forecastDaily = weatherRes.getForecastDaily();
if (forecastDaily != null && forecastDaily.getDays() != null) {
for (WeatherKitWeatherRes.DailyWeather dailyWeather : forecastDaily.getDays()) {
if (dailyWeather == null) {
continue;
}
WeatherKitWeatherRes.DayPartForecast daytimeForecast = dailyWeather.getDaytimeForecast();
if (daytimeForecast != null) {
daytimeForecast.setConditionName(WeatherConditionCodeEnum.getDescByCode(daytimeForecast.getConditionCode()));
daytimeForecast.setIconName(resolveWeatherIconName(daytimeForecast.getConditionCode(), true));
daytimeForecast.setIconUrl(resolveWeatherIconUrl(daytimeForecast.getIconName()));
daytimeForecast.setWindIconName(resolveWindIconName(daytimeForecast.getWindSpeed()));
daytimeForecast.setWindIconUrl(resolveWeatherIconUrl(daytimeForecast.getWindIconName()));
dailyWeather.setIconName(daytimeForecast.getIconName());
dailyWeather.setIconUrl(daytimeForecast.getIconUrl());
}
WeatherKitWeatherRes.DayPartForecast nighttimeForecast = dailyWeather.getNighttimeForecast();
if (nighttimeForecast != null) {
nighttimeForecast.setConditionName(WeatherConditionCodeEnum.getDescByCode(nighttimeForecast.getConditionCode()));
nighttimeForecast.setIconName(resolveWeatherIconName(nighttimeForecast.getConditionCode(), false));
nighttimeForecast.setIconUrl(resolveWeatherIconUrl(nighttimeForecast.getIconName()));
nighttimeForecast.setWindIconName(resolveWindIconName(nighttimeForecast.getWindSpeed()));
nighttimeForecast.setWindIconUrl(resolveWeatherIconUrl(nighttimeForecast.getWindIconName()));
if (dailyWeather.getIconName() == null || dailyWeather.getIconName().trim().isEmpty()) {
dailyWeather.setIconName(nighttimeForecast.getIconName());
dailyWeather.setIconUrl(nighttimeForecast.getIconUrl());
}
}
dailyWeather.setMoonPhaseIconName(resolveMoonPhaseIconName(dailyWeather.getMoonPhase()));
dailyWeather.setMoonPhaseIconUrl(resolveWeatherIconUrl(dailyWeather.getMoonPhaseIconName()));
}
}
}
/**
* 根据 Weather Icons 图标名生成前端可直接访问的图片地址。
* 图标文件默认放在 MinIO 的 icons/weatherkit 目录下,文件名与 iconName 保持一致。
*
* @param iconName Weather Icons 图标名,例如 wi-day-rain
* @return 图标访问地址,若图标名为空则返回 null
*/
private static String resolveWeatherIconUrl(String iconName) {
if (iconName == null || iconName.trim().isEmpty()) {
return null;
}
return FileService.createFileUrl(WEATHER_KIT_ICON_PATH + iconName + ".svg");
}
/**
* 根据 WeatherKit 风速计算 weather-icons 的蒲福风级图标名。
* WeatherKit 风速单位为公里/小时。
*
* @param windSpeed 风速,单位 km/h
* @return 风力等级图标名,例如 wi-wind-beaufort-3
*/
private static String resolveWindIconName(Double windSpeed) {
if (windSpeed == null) {
return null;
}
double speed = windSpeed;
int beaufort;
if (speed < 1) {
beaufort = 0;
} else if (speed < 6) {
beaufort = 1;
} else if (speed < 12) {
beaufort = 2;
} else if (speed < 20) {
beaufort = 3;
} else if (speed < 29) {
beaufort = 4;
} else if (speed < 39) {
beaufort = 5;
} else if (speed < 50) {
beaufort = 6;
} else if (speed < 62) {
beaufort = 7;
} else if (speed < 75) {
beaufort = 8;
} else if (speed < 89) {
beaufort = 9;
} else if (speed < 103) {
beaufort = 10;
} else if (speed < 118) {
beaufort = 11;
} else {
beaufort = 12;
}
return WIND_BEAUFORT_ICON_PREFIX + beaufort;
}
/**
* 根据 WeatherKit 月相值映射为 weather-icons 月相图标名。
*
* @param moonPhase WeatherKit 月相值
* @return 月相图标名,例如 wi-moon-waxing-gibbous-3
*/
private static String resolveMoonPhaseIconName(String moonPhase) {
if (moonPhase == null || moonPhase.trim().isEmpty()) {
return null;
}
if ("new".equalsIgnoreCase(moonPhase) || "newMoon".equalsIgnoreCase(moonPhase)) {
return "wi-moon-new";
}
if ("waxingCrescent".equalsIgnoreCase(moonPhase)) {
return "wi-moon-waxing-crescent-3";
}
if ("firstQuarter".equalsIgnoreCase(moonPhase)) {
return "wi-moon-first-quarter";
}
if ("waxingGibbous".equalsIgnoreCase(moonPhase)) {
return "wi-moon-waxing-gibbous-3";
}
if ("full".equalsIgnoreCase(moonPhase) || "fullMoon".equalsIgnoreCase(moonPhase)) {
return "wi-moon-full";
}
if ("waningGibbous".equalsIgnoreCase(moonPhase)) {
return "wi-moon-waning-gibbous-3";
}
if ("lastQuarter".equalsIgnoreCase(moonPhase) || "thirdQuarter".equalsIgnoreCase(moonPhase)) {
return "wi-moon-third-quarter";
}
if ("waningCrescent".equalsIgnoreCase(moonPhase)) {
return "wi-moon-waning-crescent-3";
}
return "wi-moon-full";
}
/**
* 根据 WeatherKit 的 conditionCode 和昼夜状态,映射为 weather-icons 的图标名。
*
* @param conditionCode WeatherKit 天气编码
* @param daylight 是否为白天,允许为空
* @return 可供前端使用的 weather-icons 图标名
*/
private static String resolveWeatherIconName(String conditionCode, Boolean daylight) {
boolean isDaylight = daylight == null || daylight;
if (conditionCode == null || conditionCode.trim().isEmpty()) {
return isDaylight ? "wi-day-cloudy" : "wi-night-alt-cloudy";
}
if ("Clear".equals(conditionCode)) {
return isDaylight ? "wi-day-sunny" : "wi-night-clear";
}
if ("MostlyClear".equals(conditionCode)) {
return isDaylight ? "wi-day-sunny-overcast" : "wi-night-alt-partly-cloudy";
}
if ("PartlyCloudy".equals(conditionCode)) {
return isDaylight ? "wi-day-cloudy" : "wi-night-alt-cloudy";
}
if ("MostlyCloudy".equals(conditionCode) || "Cloudy".equals(conditionCode)) {
return "wi-cloudy";
}
if ("Foggy".equals(conditionCode) || "Haze".equals(conditionCode) || "Smoky".equals(conditionCode)) {
return isDaylight ? "wi-day-fog" : "wi-night-fog";
}
if ("Windy".equals(conditionCode)) {
return "wi-cloudy-gusts";
}
if ("Drizzle".equals(conditionCode)) {
return isDaylight ? "wi-day-sprinkle" : "wi-night-alt-sprinkle";
}
if ("Rain".equals(conditionCode) || "HeavyRain".equals(conditionCode) || "SunShowers".equals(conditionCode)) {
return isDaylight ? "wi-day-rain" : "wi-night-alt-rain";
}
if ("Flurries".equals(conditionCode) || "Snow".equals(conditionCode) || "HeavySnow".equals(conditionCode) || "BlowingSnow".equals(conditionCode)) {
return isDaylight ? "wi-day-snow" : "wi-night-alt-snow";
}
if ("FreezingDrizzle".equals(conditionCode)
|| "FreezingRain".equals(conditionCode)
|| "WintryMix".equals(conditionCode)
|| "Sleet".equals(conditionCode)
|| "Hail".equals(conditionCode)) {
return isDaylight ? "wi-day-sleet" : "wi-night-alt-sleet";
}
if ("Hot".equals(conditionCode)) {
return "wi-hot";
}
if ("Cold".equals(conditionCode)) {
return "wi-snowflake-cold";
}
if ("Blizzard".equals(conditionCode)) {
return "wi-snow-wind";
}
if ("Thunderstorms".equals(conditionCode)
|| "StrongStorms".equals(conditionCode)
|| "ScatteredThunderstorms".equals(conditionCode)
|| "IsolatedThunderstorms".equals(conditionCode)) {
return isDaylight ? "wi-day-thunderstorm" : "wi-night-alt-thunderstorm";
}
if ("TropicalStorm".equals(conditionCode) || "Hurricane".equals(conditionCode)) {
return "wi-hurricane";
}
return isDaylight ? "wi-day-cloudy" : "wi-night-alt-cloudy";
}
public static void main(String[] args) {
// 测试获取指定坐标的天气
WeatherKitWeatherRes jsonResult = getWeather(39.88, 124.16);
System.out.println(jsonResult);
}
}
3.对象
@Data
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "Apple WeatherKit 天气响应")
public class WeatherKitWeatherRes {
/**
* 当前天气信息。
*/
@Schema(description = "当前天气信息")
private CurrentWeather currentWeather;
/**
* 逐小时天气预报。
*/
@Schema(description = "逐小时天气预报")
private ForecastHourly forecastHourly;
/**
* 逐日天气预报。
*/
@Schema(description = "逐日天气预报")
private ForecastDaily forecastDaily;
/**
* WeatherKit 通用元数据。
* 不同数据集会携带各自的元数据,例如经纬度、时区、单位、过期时间等。
*/
@Data
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "WeatherKit 数据元信息")
public static class Metadata {
/**
* 纬度。
*/
@Schema(description = "纬度")
private Double latitude;
/**
* 经度。
*/
@Schema(description = "经度")
private Double longitude;
/**
* 时区名称。
*/
@Schema(description = "时区名称")
private String timezone;
/**
* 数据读取时间。
*/
@Schema(description = "数据读取时间")
private String readTime;
/**
* 数据发布时间。
*/
@Schema(description = "数据发布时间")
private String reportedTime;
/**
* 数据过期时间。
*/
@Schema(description = "数据过期时间")
private String expireTime;
/**
* 天气数据单位体系。
*/
@Schema(description = "天气数据单位体系")
private String units;
/**
* 天气数据版本。
*/
@Schema(description = "天气数据版本")
private Integer version;
}
/**
* 当前天气对象。
*/
@Data
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "当前天气")
public static class CurrentWeather {
/**
* 数据元信息。
*/
@Schema(description = "数据元信息")
private Metadata metadata;
/**
* 观测时间。
*/
@Schema(description = "观测时间")
private String asOf;
/**
* 云量百分比。
*/
@Schema(description = "云量百分比")
private Double cloudCover;
/**
* 天气状况编码。
*/
@Schema(description = "天气状况编码")
private String conditionCode;
/**
* 天气状况中文名称。
*/
@Schema(description = "天气状况中文名称")
private String conditionName;
/**
* 对应的天气图标标识。
*/
@Schema(description = "Weather Icons 图标名,例如 wi-day-rain")
private String iconName;
/**
* 天气图标访问地址。
*/
@Schema(description = "天气图标访问地址")
private String iconUrl;
/**
* 风力图标名,例如 wi-wind-beaufort-3。
*/
@Schema(description = "风力图标名,例如 wi-wind-beaufort-3")
private String windIconName;
/**
* 风力图标访问地址。
*/
@Schema(description = "风力图标访问地址")
private String windIconUrl;
/**
* 是否为白天。
*/
@Schema(description = "是否为白天")
private Boolean daylight;
/**
* 湿度百分比。
*/
@Schema(description = "湿度百分比")
private Double humidity;
/**
* 降水强度。
*/
@Schema(description = "降水强度")
private Double precipitationIntensity;
/**
* 气压。
*/
@Schema(description = "气压")
private Double pressure;
/**
* 气压变化趋势。
*/
@Schema(description = "气压变化趋势")
private String pressureTrend;
/**
* 实际温度。
*/
@Schema(description = "实际温度")
private Double temperature;
/**
* 体感温度。
*/
@Schema(description = "体感温度")
private Double temperatureApparent;
/**
* 露点温度。
*/
@Schema(description = "露点温度")
private Double temperatureDewPoint;
/**
* 紫外线指数。
*/
@Schema(description = "紫外线指数")
private Integer uvIndex;
/**
* 能见度。
*/
@Schema(description = "能见度")
private Double visibility;
/**
* 风向角度。
*/
@Schema(description = "风向角度")
private Integer windDirection;
/**
* 阵风风速。
*/
@Schema(description = "阵风风速")
private Double windGust;
/**
* 持续风速。
*/
@Schema(description = "持续风速")
private Double windSpeed;
}
/**
* 逐小时预报对象。
*/
@Data
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "逐小时天气预报")
public static class ForecastHourly {
/**
* 预报名称。
*/
@Schema(description = "预报名称")
private String name;
/**
* 数据元信息。
*/
@Schema(description = "数据元信息")
private Metadata metadata;
/**
* 小时级天气列表。
*/
@Schema(description = "小时级天气列表")
private List<HourlyWeather> hours;
}
/**
* 单小时天气信息。
*/
@Data
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "单小时天气信息")
public static class HourlyWeather {
/**
* 预报开始时间。
*/
@Schema(description = "预报开始时间")
private String forecastStart;
/**
* 云量百分比。
*/
@Schema(description = "云量百分比")
private Double cloudCover;
/**
* 天气状况编码。
*/
@Schema(description = "天气状况编码")
private String conditionCode;
/**
* 天气状况中文名称。
*/
@Schema(description = "天气状况中文名称")
private String conditionName;
/**
* 对应的天气图标标识。
*/
@Schema(description = "Weather Icons 图标名,例如 wi-day-rain")
private String iconName;
/**
* 天气图标访问地址。
*/
@Schema(description = "天气图标访问地址")
private String iconUrl;
/**
* 风力图标名,例如 wi-wind-beaufort-3。
*/
@Schema(description = "风力图标名,例如 wi-wind-beaufort-3")
private String windIconName;
/**
* 风力图标访问地址。
*/
@Schema(description = "风力图标访问地址")
private String windIconUrl;
/**
* 是否为白天。
*/
@Schema(description = "是否为白天")
private Boolean daylight;
/**
* 湿度百分比。
*/
@Schema(description = "湿度百分比")
private Double humidity;
/**
* 降水概率。
*/
@Schema(description = "降水概率")
private Double precipitationChance;
/**
* 降水强度。
*/
@Schema(description = "降水强度")
private Double precipitationIntensity;
/**
* 气压。
*/
@Schema(description = "气压")
private Double pressure;
/**
* 气压变化趋势。
*/
@Schema(description = "气压变化趋势")
private String pressureTrend;
/**
* 温度。
*/
@Schema(description = "温度")
private Double temperature;
/**
* 体感温度。
*/
@Schema(description = "体感温度")
private Double temperatureApparent;
/**
* 露点温度。
*/
@Schema(description = "露点温度")
private Double temperatureDewPoint;
/**
* 紫外线指数。
*/
@Schema(description = "紫外线指数")
private Integer uvIndex;
/**
* 能见度。
*/
@Schema(description = "能见度")
private Double visibility;
/**
* 风向角度。
*/
@Schema(description = "风向角度")
private Integer windDirection;
/**
* 阵风风速。
*/
@Schema(description = "阵风风速")
private Double windGust;
/**
* 持续风速。
*/
@Schema(description = "持续风速")
private Double windSpeed;
}
/**
* 逐日预报对象。
*/
@Data
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "逐日天气预报")
public static class ForecastDaily {
/**
* 预报名称。
*/
@Schema(description = "预报名称")
private String name;
/**
* 数据元信息。
*/
@Schema(description = "数据元信息")
private Metadata metadata;
/**
* 每日天气列表。
*/
@Schema(description = "每日天气列表")
private List<DailyWeather> days;
}
/**
* 单日天气信息。
*/
@Data
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "单日天气信息")
public static class DailyWeather {
/**
* 预报日期开始时间。
*/
@Schema(description = "预报日期开始时间")
private String forecastStart;
/**
* 预报日期结束时间。
*/
@Schema(description = "预报日期结束时间")
private String forecastEnd;
/**
* 当日最高温度。
*/
@Schema(description = "当日最高温度")
private Double temperatureMax;
/**
* 当日最低温度。
*/
@Schema(description = "当日最低温度")
private Double temperatureMin;
/**
* 白天天气预报。
*/
@Schema(description = "白天天气预报")
private DayPartForecast daytimeForecast;
/**
* 对应的天气图标标识。
*/
@Schema(description = "Weather Icons 图标名,例如 wi-day-rain")
private String iconName;
/**
* 天气图标访问地址。
*/
@Schema(description = "天气图标访问地址")
private String iconUrl;
/**
* 月相图标名,例如 wi-moon-waxing-gibbous-3。
*/
@Schema(description = "月相图标名,例如 wi-moon-waxing-gibbous-3")
private String moonPhaseIconName;
/**
* 月相图标访问地址。
*/
@Schema(description = "月相图标访问地址")
private String moonPhaseIconUrl;
/**
* 夜间天气预报。
*/
@Schema(description = "夜间天气预报")
private DayPartForecast nighttimeForecast;
/**
* 月相。
*/
@Schema(description = "月相")
private String moonPhase;
/**
* 日出时间。
*/
@Schema(description = "日出时间")
private String sunrise;
/**
* 日落时间。
*/
@Schema(description = "日落时间")
private String sunset;
/**
* 全天降水量。
*/
@Schema(description = "全天降水量")
private Double precipitationAmount;
/**
* 全天降水概率。
*/
@Schema(description = "全天降水概率")
private Double precipitationChance;
/**
* 全天降雪量。
*/
@Schema(description = "全天降雪量")
private Double snowfallAmount;
}
/**
* 白天或夜间天气片段信息。
*/
@Data
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "白天或夜间天气片段")
public static class DayPartForecast {
/**
* 片段开始时间。
*/
@Schema(description = "片段开始时间")
private String forecastStart;
/**
* 片段结束时间。
*/
@Schema(description = "片段结束时间")
private String forecastEnd;
/**
* 天气状况编码。
*/
@Schema(description = "天气状况编码")
private String conditionCode;
/**
* 天气状况中文名称。
*/
@Schema(description = "天气状况中文名称")
private String conditionName;
/**
* 对应的天气图标标识。
*/
@Schema(description = "Weather Icons 图标名,例如 wi-day-rain")
private String iconName;
/**
* 天气图标访问地址。
*/
@Schema(description = "天气图标访问地址")
private String iconUrl;
/**
* 风力图标名,例如 wi-wind-beaufort-3。
*/
@Schema(description = "风力图标名,例如 wi-wind-beaufort-3")
private String windIconName;
/**
* 风力图标访问地址。
*/
@Schema(description = "风力图标访问地址")
private String windIconUrl;
/**
* 云量百分比。
*/
@Schema(description = "云量百分比")
private Double cloudCover;
/**
* 湿度百分比。
*/
@Schema(description = "湿度百分比")
private Double humidity;
/**
* 降水概率。
*/
@Schema(description = "降水概率")
private Double precipitationChance;
/**
* 降水量。
*/
@Schema(description = "降水量")
private Double precipitationAmount;
/**
* 降雪量。
*/
@Schema(description = "降雪量")
private Double snowfallAmount;
/**
* 风向角度。
*/
@Schema(description = "风向角度")
private Integer windDirection;
/**
* 持续风速。
*/
@Schema(description = "持续风速")
private Double windSpeed;
}
}
-
梦想成为科学家 07-09 18:391楼芜湖,正在做这个呢,哈哈哈哈哈,感谢大佬