我正在使用 OpenWeather API 创建一个简单的网页,用于显示动态天气数据,包括日出和日落时间。 API 以秒为单位提供这些时间(Unix 时间戳),我尝试将它们转换为每个城市的当地时间。不过,我不确定我的转换是否准确。
例如,API 为我提供多伦多的日出时间为凌晨 2:00,日落时间为上午 11:00。然而,根据谷歌(今天)的说法,多伦多的日出应该是上午 7:26,日落应该是下午 4:44。
这是我的代码片段
var timezoneOffset = weatherData.timezone; // Offset in seconds
var sunriseDate = new Date((weatherData.sys.sunrise + timezoneOffset) * 1000)
.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
var sunsetDate = new Date((weatherData.sys.sunset + timezoneOffset) * 1000)
.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
console.log(sunriseDate);
console.log(sunsetDate);
我想确保这段代码给出了正确的输出。
这是多伦多的 Json 输出
{
"coord": {
"lon": -79.4163,
"lat": 43.7001
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04n"
}
],
"base": "stations",
"main": {
"temp": -0.86,
"feels_like": -7.86,
"temp_min": -1.56,
"temp_max": -0.34,
"pressure": 1011,
"humidity": 72,
"sea_level": 1011,
"grnd_level": 994
},
"visibility": 10000,
"wind": {
"speed": 12.07,
"deg": 250,
"gust": 14.31
},
"clouds": {
"all": 75
},
"dt": 1732929417,
"sys": {
"type": 2,
"id": 2099289,
"country": "CA",
"sunrise": 1732883394,
"sunset": 1732916569
},
"timezone": -18000,
"id": 6167865,
"name": "Toronto",
"cod": 200
}
一些与帖子进行比较的工作代码:
var weatherData = {
"coord": {
"lon": -79.4163,
"lat": 43.7001
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04n"
}
],
"base": "stations",
"main": {
"temp": -0.86,
"feels_like": -7.86,
"temp_min": -1.56,
"temp_max": -0.34,
"pressure": 1011,
"humidity": 72,
"sea_level": 1011,
"grnd_level": 994
},
"visibility": 10000,
"wind": {
"speed": 12.07,
"deg": 250,
"gust": 14.31
},
"clouds": {
"all": 75
},
"dt": 1732929417,
"sys": {
"type": 2,
"id": 2099289,
"country": "CA",
"sunrise": 1732883394,
"sunset": 1732916569
},
"timezone": -18000,
"id": 6167865,
"name": "Toronto",
"cod": 200
};
// sunrise and sunset from UTC seconds
const sunrise = new Date((weatherData.sys.sunrise) * 1000);
const sunset = new Date((weatherData.sys.sunset) * 1000);
function UTC_offset(seconds) {
const sign = seconds < 0 ? '-' : '+';
seconds = Math.abs(seconds);
let hours = Math.floor( seconds/3600);
seconds -= hours * 3600;
let mins = Math.floor( seconds/60);
return sign+hours.toString().padStart(2, '0')+mins.toString().padStart(2, '0');
}
function options( weatherData) {
return {
hour: '2-digit',
minute: '2-digit',
timeZone: UTC_offset( weatherData.timezone)
}
}
console.log( "%s Sunrise: %s",
weatherData.name,
sunrise.toLocaleTimeString( [], options(weatherData))
);
console.log( "%s Sunset: %s",
weatherData.name,
sunset.toLocaleTimeString( [], options(weatherData))
);
决定报告日出和日落的时区。用于从 API 获取数据的地理位置的时区是一个不错的选择,并在上面使用。
将选择用于报告的实际时区指定为作为第二个参数传递给 timeZone
的options 对象的
toLocaleTimeSting
属性。
编写一个晦涩且混乱的转换,从记录为以秒为单位的时区偏移量到上面 2. 中的
"±hhmm"
链接中提到的 timeZone
偏移量字符串。
将您编写的代码与 API 文档相结合以获得正确的结果。例如。将时区偏移应用于
toLocaleString
生成的输出,而不是日期计算。
讨论
帖子中报告的输出有问题。上面的工作代码基于发布的代码,并且在任何阶段都没有将日出和日落时间的分钟数更改为与 API 报告的时间不相同或 30 分钟不同的分钟数。
需要考虑的两点
生活在格林尼治标准时间以东 9:30 的时区很容易导致 30 分钟值的差异 如果我的电脑上以当地时间报告日落/日出时间。
如果您继续将分钟值设置为零,且与 API 中的时间不对应,则代码中存在问题,但帖子中没有。