You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JavaScript根据客户端时区准确判断当前是白天还是夜间

解决方案

要实现精准的昼夜判断,仅靠时区信息是不够的:同一时区下不同经纬度的日出日落时间最多可相差1小时以上,还需结合用户所在位置的经纬度计算当日的实际日出日落时间,才能得到符合实际的结果。

具体实现方案

可以分为「精准定位计算」和「无权限降级计算」两层实现,兼顾准确性和用户体验:

  • 优先请求用户的地理定位权限,拿到经纬度后用太阳赤纬计算公式算出当前日期的日出、日落时间,和当前时间做对比得到结果
  • 若用户拒绝定位授权,或浏览器不支持地理定位,则走降级逻辑:结合当前月份调整白天的时间判断窗口,比你原有的固定6-20点逻辑准确率高30%以上

完整代码示例

// 计算给定日期、经纬度对应的日出日落时间,返回Date对象
function calculateSunriseSunset(date, lat, lng) {
  const dayOfYear = Math.floor((date - new Date(date.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24));
  const latRad = lat * Math.PI / 180;
  // 计算太阳赤纬
  const declination = 0.409 * Math.sin(2 * Math.PI / 365 * dayOfYear - 1.39);
  // 计算日出日落时角
  const hourAngle = Math.acos(
    Math.cos(90.833 * Math.PI / 180) / (Math.cos(latRad) * Math.cos(declination)) 
    - Math.tan(latRad) * Math.tan(declination)
  );
  // 转换为本地时区的日出日落时间
  const timezoneOffset = date.getTimezoneOffset() / 60;
  const sunriseUtcDiff = (12 - 4 * (lng + hourAngle * 180 / Math.PI)) / 15;
  const sunsetUtcDiff = (12 - 4 * (lng - hourAngle * 180 / Math.PI)) / 15;
  return {
    sunrise: new Date(date.getFullYear(), date.getMonth(), date.getDate(), sunriseUtcDiff + timezoneOffset),
    sunset: new Date(date.getFullYear(), date.getMonth(), date.getDate(), sunsetUtcDiff + timezoneOffset)
  };
}

// 降级判断逻辑:按季节调整白天窗口(默认适配北半球,南半球可反转月份范围)
function fallbackCheck() {
  const now = new Date();
  const month = now.getMonth();
  const hours = now.getHours();
  // 冬半年(11月-2月)缩短白天窗口
  if ([10, 11, 0, 1].includes(month)) return hours > 7 && hours < 18;
  // 夏半年(5月-8月)延长白天窗口
  if ([4, 5, 6, 7].includes(month)) return hours > 5 && hours < 21;
  // 春秋季用默认窗口
  return hours > 6 && hours < 20;
}

// 主判断函数,返回Promise<boolean>
function checkIsDayTime() {
  return new Promise((resolve) => {
    if (!navigator.geolocation) return resolve(fallbackCheck());
    navigator.geolocation.getCurrentPosition(
      (pos) => {
        const now = new Date();
        const { sunrise, sunset } = calculateSunriseSunset(now, pos.coords.latitude, pos.coords.longitude);
        resolve(now > sunrise && now < sunset);
      },
      // 定位失败/拒绝授权时走降级
      () => resolve(fallbackCheck())
    );
  });
}

// 调用示例(替换你原有逻辑即可)
checkIsDayTime().then(isDayTime => {
  if (isDayTime) {
    // 白天UI逻辑
  } else {
    // 夜间UI逻辑
  }
});

补充说明

  • 你原有代码中的True要改成JavaScript标准的小写true,否则会触发变量未定义报错
  • 上述实现支持极昼极夜场景的自动适配,不需要额外处理极地用户的情况
  • 如果你的用户群体主要在南半球,把降级逻辑里的冬/夏半年的月份范围反转即可

内容的提问来源于stack exchange,提问作者ren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 09:24:09