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

如何让JS/PHP获取英国时区、周日起始的周数?

英国时区周日起始的周数计算方案

问题背景

我需要获取以周日为起始、基于英国时区的周数,但目前国际用户访问网站时,会因为时区差异得到不同的周数。

当前使用的JavaScript代码如下:

Date.prototype.getWeek = function() {
  var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
  d.setUTCDate(d.getUTCDate() - d.getUTCDay());
  var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
  return Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
};

function getWeekNum(dateStr) {
    var date = new Date(dateStr);
    var currentWeekNumber = date.getWeek();
    return currentWeekNumber;
}

console.log(getWeekNum("2023-03-19"));

英国与坎昆的周数差异对比:
英国与坎昆的周数差异对比图

核心问题:如何强制使用英国时区计算周数?若JavaScript无法实现,能否提供PHP版本的实现?


JavaScript实现方案

要强制基于英国时区(Europe/London)计算周日起始的周数,可借助Intl.DateTimeFormat处理时区转换,确保所有计算逻辑基于英国本地时间:

function getUKWeekNumber(dateStr) {
  // 初始化英国时区格式化器
  const ukFormatter = new Intl.DateTimeFormat('en-GB', {
    timeZone: 'Europe/London',
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  });

  // 提取英国时区下的年、月、日
  const dateParts = ukFormatter.formatToParts(new Date(dateStr));
  const ukYear = dateParts.find(p => p.type === 'year').value;
  const ukMonth = dateParts.find(p => p.type === 'month').value;
  const ukDay = dateParts.find(p => p.type === 'day').value;

  // 创建英国本地日期对象
  const ukLocalDate = new Date(`${ukYear}-${ukMonth}-${ukDay}`);
  // 定位到当前日期所在周的周日(getDay()返回0代表周日)
  const weekStart = new Date(ukLocalDate);
  weekStart.setDate(weekStart.getDate() - weekStart.getDay());

  // 定位到英国时区当年的第一个周日
  const yearStart = new Date(`${ukYear}-01-01`);
  const firstWeekSunday = new Date(yearStart);
  firstWeekSunday.setDate(firstWeekSunday.getDate() - firstWeekSunday.getDay());
  // 如果当年1月1日是周日之后的日期,第一周起始要往前推一周
  if (firstWeekSunday > yearStart) {
    firstWeekSunday.setDate(firstWeekSunday.getDate() - 7);
  }

  // 计算周数
  const dayDiff = Math.floor((weekStart - firstWeekSunday) / (1000 * 60 * 60 * 24));
  return Math.floor(dayDiff / 7) + 1;
}

// 测试用例
console.log(getUKWeekNumber("2023-03-19"));

关键说明

  • 用Intl.DateTimeFormat确保提取的日期是英国本地时间,自动适配夏令时
  • 基于英国本地日期计算周日起始,避免UTC转换带来的时区偏差
  • 统一以英国时区当年第一个周日作为第一周的起始点

PHP实现方案

PHP的DateTime类原生支持时区指定,实现起来更简洁:

function getUKWeekNumber(string $dateStr): int {
    // 创建英国时区的日期对象
    $timezone = new DateTimeZone('Europe/London');
    $targetDate = DateTime::createFromFormat('Y-m-d', $dateStr, $timezone);
    
    // 获取目标日期所在周的周日(如果当天是周日则不调整)
    $weekStart = clone $targetDate;
    $weekStart->modify('last Sunday');
    if ($weekStart > $targetDate) {
        $weekStart->modify('-7 days');
    }
    
    // 获取当年的第一个周日
    $yearStart = new DateTime($targetDate->format('Y') . '-01-01', $timezone);
    $firstWeekSunday = clone $yearStart;
    $firstWeekSunday->modify('last Sunday');
    if ($firstWeekSunday > $yearStart) {
        $firstWeekSunday->modify('-7 days');
    }
    
    // 计算周数
    $interval = $firstWeekSunday->diff($weekStart);
    return (int)($interval->days / 7) + 1;
}

// 测试用例
echo getUKWeekNumber("2023-03-19");

关键说明

  • 直接指定Europe/London时区,自动处理夏令时切换
  • 通过modify方法快速定位到周起始周日
  • 用diff方法计算日期差,避免时间戳计算的潜在问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:53:38