【问题标题】:Find first and last week days according to locale根据区域设置查找第一周和最后一周
【发布时间】:2016-11-30 16:39:45
【问题描述】:

我正在尝试根据区域设置查找第一周和最后一周。

在美国,一周通常从星期日开始,但在其他国家/地区可能会在另一天开始 - 例如周一甚至周六。

setlocale(LC_ALL, "en_US.UTF-8");
date_default_timezone_set("America/New_York");

$start_week = (new DateTimeImmutable());
$start_week = $start_week->modify('this week');
$end_week = $start_week->modify('this week +6 days');

$interval = new DateInterval('P1D');
$week_range = new DatePeriod($start_week, $interval, $end_week);

foreach($week_range as $week_day) {
  // $week_day starts with Monday, supposed to be Sunday
}

【问题讨论】:

  • 日历上的“一周开始”通常是用户在文化默认设置之上的偏好。即使您居住在美国,您也可能希望您的日历显示从星期一开始几周。
  • @Leith:我的 Windows、Outlook、iPhone 日历都从星期日开始。那些日历的开发者没有这样的借口。
  • 但您的 Google 日历会让您选择。我并不是说基于语言环境设置默认值不是一个好主意 - 我只是说你不一定想一成不变。

标签: php datetime localization


【解决方案1】:

一种方法是使用IntlCalendar 类。它有一个方法getFirstDayofWeek(),返回一个整数,对应IntlCalendar中的DOW_常量:

常量整数 DOW_SUNDAY = 1 ;
常量整数 DOW_MONDAY = 2 ;
常量整数 DOW_TUESDAY = 3 ;
常量整数 DOW_WEDNESDAY = 4 ;
常量整数 DOW_THURSDAY = 5 ;
常量整数 DOW_FRIDAY = 6 ;
常量整数 DOW_SATURDAY = 7 ;

在为开始日调用DateTimeImmutable::modify() 时,使用它来为开始日添加天数。在this phpfiddle 中使用三个语言环境(即en_USes_ESsw_KE)查看它。

$locale = 'es_ES'; //Spain Spanish locale
$cal1 = IntlCalendar::createInstance(NULL, $locale);
$firstDayOfWeek = $cal1->getFirstDayOfWeek();
$daysToAdd = $firstDayOfWeek - 2; //difference from US M-Sunday 
echo 'locale: '.$local.' first day of week: '.$cal1->getFirstDayOfWeek().' days to add: '.$daysToAdd.'<br />';
$start_week = new DateTimeImmutable();
$start_week = $start_week->modify('this week +'.$daysToAdd.' days');
$end_week = $start_week->modify('+6 days');
$interval = new DateInterval('P1D');
$week_range = new DatePeriod($start_week, $interval, $end_week);

foreach($week_range as $week_day) {
    echo 'week day: '.$week_day->format('l m/d/Y').'<br />';
}

【讨论】:

  • 我认为这是在 PHP 中唯一的原生方式:IntlCalendar 使用ICU,而后者又使用强大的CLDR database。另一方面,DateTime 使用 Olson zoneinfo database,它不包含周开始信息。
  • 很好的解决方案。但是如何避免使用像'this week' 这样的相对时间。稍后我需要使用我的$start_week 对象。换句话说,我希望能够在对象的任何日期确定一周的第一天(即$start_week = $start_week-&gt;setTimestamp($my_ts))。
  • 嗯,这是否意味着 $my_ts 会有不同的日期(例如 07/04/1776),我们需要知道星期几?那么我们是否需要找出一周中的那一天与一周中的本地第一天之间的差异?你能概括一个场景吗?
  • 基本上我只需要一个对象来操作...$intl_cal = IntlCalendar::createInstance(NULL, $locale); $days_to_add = $intl_cal-&gt;getFirstDayOfWeek() - 2; $first_day_of_week = (new DateTimeImmutable())-&gt;setTime(00,00,00)-&gt;modify('this week +' . $days_to_add . ' days')-&gt;format('l'); // Sunday。谢谢。
猜你喜欢
  • 2014-03-08
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 2018-06-02
  • 2021-07-21
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
相关资源
最近更新 更多