有苹果开发者账号的可以免费调用天气接口

Simshen 2026-07-08 14:31 1

Apple Developer Program 的会员账号每个月自带 500,000 次(50万次)的免费调用额度。无论你是通过 iOS 原生 Swift API 还是通过后端的 REST API(如 Java)调用,这 50 万次都是共享且免费的

如果是通过后端服务器/脚本调用(REST API)

因为你前面提到要调用 API,如果是纯代码/服务器对接,需要创建一个 Service ID




  1. 点击 Identifiers 标题右侧的蓝色 + 号。




  2. 在新页面中选择 Services IDs,然后点击右上方 Continue。




  3. 填写 Description(如 WeatherKit REST)和 Identifier(如 com.cloudcube.weatherkit)。




  4. 创建完成后,点击当前页面右上角的 App IDs 下拉菜单,切换到 Services IDs 列表。




  5. 点击你刚创建的 Service ID,勾选 WeatherKit,并点击 Configure 关联一个你已有的主 App ID(比如关联 com.fenghuangma.fhny),然后点击 Save 保存。




配置完 Identifiers 后,点击左侧菜单栏的 Keys




  1. 点击 + 号新建一个 Key。




  2. 命名为类似 WeatherKitKey,并在列表中勾选 WeatherKit




  3. 点击 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;
}
}

最新回复 (1)
  • 梦想成为科学家 07-09 18:39
    1

    芜湖,正在做这个呢,哈哈哈哈哈,感谢大佬

* 帖子来源Linux.do
返回