import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.LocalDate; import java.time.format.DateTimeFormatter; public class GreenlandHistoryWeather { public static void main(String[] args) { System.out.println("🚀 开始获取格陵兰岛历史天气数据..."); // --- 配置区域 --- double latitude = 64.18; // 努克 (Nuuk) 纬度 double longitude = -51.69; // 努克 (Nuuk) 经度 // --- 设定历史时间段 --- // 这里是你之前设置的 2025 年 1 月 LocalDate startDate = LocalDate.of(2025, 12, 1); LocalDate endDate = LocalDate.of(2026, 1, 31); String dateStartStr = startDate.format(DateTimeFormatter.ISO_LOCAL_DATE); String dateEndStr = endDate.format(DateTimeFormatter.ISO_LOCAL_DATE); System.out.println("📅 查询时间段: " + dateStartStr + " 至 " + dateEndStr); System.out.println("📍 地点: 格陵兰岛 - 努克 (Nuuk)\n"); // --- 构建 API URL --- // ⚠️ 关键修改:使用 archive-api.open-meteo.com/v1/archive 专门获取历史数据 String apiUrl = String.format( "https://archive-api.open-meteo.com/v1/archive?latitude=%f&longitude=%f" + "&start_date=%s&end_date=%s" + "&daily=temperature_2m_max,temperature_2m_min,precipitation_sum" + "&timezone=auto", latitude, longitude, dateStartStr, dateEndStr ); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(apiUrl)) .GET() .build(); try { // 发送请求 HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { String json = response.body(); parseAndPrintHistory(json); } else { System.out.println("❌ 请求失败,状态码: " + response.statusCode()); System.out.println("返回信息: " + response.body()); System.out.println("\n💡 提示:如果状态码是 400,请检查日期是否超出了该站点的数据记录范围。"); } } catch (Exception e) { System.out.println("❌ 发生网络或程序错误: "); e.printStackTrace(); } } // --- 解析并打印数据 --- private static void parseAndPrintHistory(String json) { System.out.println("✅ 数据获取成功!解析结果如下:\n"); System.out.printf("%-12s | %-10s | %-10s | %-10s%n", "日期", "最高温(°C)", "最低温(°C)", "降水(mm)"); System.out.println("-------------------------------------------------------"); // 【关键】API 返回的日期字段名是 "time",不是 "date" String[] dates = extractArray(json, "time"); String[] maxTemps = extractArray(json, "temperature_2m_max"); String[] minTemps = extractArray(json, "temperature_2m_min"); String[] precip = extractArray(json, "precipitation_sum"); int count = Math.min(dates.length, maxTemps.length); if (count == 0) { System.out.println("⚠️ 警告:未解析到数据。可能是该时间段无记录,或 JSON 结构变化。"); return; } for (int i = 0; i < count; i++) { // 清理日期字符串两边的引号 String dateClean = dates[i].replace("\"", ""); System.out.printf("%-12s | %-10s | %-10s | %-10s%n", dateClean, maxTemps[i], minTemps[i], precip[i] ); } System.out.println("-------------------------------------------------------"); System.out.println("💡 任务完成!共获取 " + count + " 天的数据。"); } // --- 辅助方法:简易 JSON 数组提取器 --- private static String[] extractArray(String json, String key) { String searchKey = "\"" + key + "\":["; int startIndex = json.indexOf(searchKey); // 如果找不到键,返回空数组 if (startIndex == -1) return new String[0]; startIndex += searchKey.length(); int endIndex = json.indexOf("]", startIndex); if (endIndex == -1) return new String[0]; String arrayContent = json.substring(startIndex, endIndex); // 按逗号分割,并去除可能的空白字符 if (arrayContent.trim().isEmpty()) return new String[0]; return arrayContent.split(","); } }