You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
4.9 KiB
117 lines
4.9 KiB
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<String> 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(",");
|
|
}
|
|
}
|