[英]PHP DateTime() class, change first day of the week to Monday
只要您所在国家/地区一周的第一天是星期日,PHP (5.3+) 中的 DateTime 类就可以很好地工作。 在荷兰,一周的第一天是星期一,这只会让课程无法构建具有周视图和计算的日历。
我似乎无法在 Stackoverflow 或互联网的其余部分找到关于如何让 DateTime 表现得好像一周的第一天是星期一的答案。
我在 Stackoverflow 上找到了这篇文章,但它并没有解决你遇到麻烦的所有方式,也不是一个优雅的解决方案。
$dateTime = new DateTime('2012-05-14');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
有没有办法改变这个或扩展日期时间? 无法想象这不是一个环境,因为大多数欧洲国家从周一开始他们的一周。
补充:发布完整的日历和功能代码不会让事情变得更清楚。 但这里是一行一行的例子。 我经常需要检查一周的第一天是什么,或者计算从一周的第一天到该周的不同日期和时间。 我的代码充满了这些:
$startOfWeek = $date->modify(('Sunday' == $date->format('l')) ? 'Monday last week' : 'Monday this week')->modify('+3 hours')->format(DATETIME);
尝试获取月份或年份的第一个完整周时,我也得到了一个不需要的结果。 因为我的 $date 对象并不总是包含相同的日期,所以我必须继续以这种方式检查它,从而使代码难以阅读。 在这个日历上有更多的编程要做,我无法预见它会再次出现错误。
编辑虽然有一些不一致之处。 出于某种奇怪的原因,DateTime 确实得到了下一个正确的结果:
$test = new DateTime('2012-10-29'); // Monday
echo $test->modify('Sunday this week')->format('Y-m-d'); // 2012-11-04
// But...
$test = new DateTime('2012-11-04'); // Sunday
echo $test->modify('Monday this week')->format('Y-m-d'); // 2012-11-05 instead of 2012-10-29
但我想我可以让问题更清楚: Can the DateTime() class be used with monday as the first day of the week. 如果没有,是否可以将课程扩展为使用星期一作为一周的第一天。
更新:好的,我想我正在取得进展......我不是编码课程的专业人士......但这几周似乎都有效。 但它仍然需要第一天、第二天的规则……以及星期日本身的日期名称。 我不认为这是万无一失的。 我将不胜感激任何修复它的帮助。
class EuroDateTime extends DateTime {
// Fields
private $weekModifiers = array (
'this week',
'next week',
'previous week',
'last week'
);
// Override "modify()"
public function modify($string) {
// Search pattern
$pattern = '/'.implode('|', $this->weekModifiers).'/';
// Change the modifier string if needed
if ( $this->format('N') == 7 ) { // It's Sunday
$matches = array();
if ( preg_match( $pattern, $string, $matches )) {
$string = str_replace($matches[0], '-7 days '.$matches[0], $string);
}
}
return parent::modify($string);
}
}
// This works
$test = new EuroDateTime('2012-11-04');
echo $test->modify('Monday this week')->format('Y-m-d');
// And I can still concatenate calls like the DateTime class was intended
echo $test->modify('Monday this week')->modify('+3 days')->format('Y-m-d');
我发现这是可行的,但 PHP 的 DateTime 类中存在一些不一致之处。
如果出发日期是星期日,则前一个星期一不被视为同一周(由此类确定)。 但是从星期一开始,下一个星期日被视为同一周。 如果他们将来解决这个问题,这个课程将需要一些补充。
class EuroDateTime extends DateTime {
// Override "modify()"
public function modify($string) {
// Change the modifier string if needed
if ( $this->format('N') == 7 ) { // It's Sunday and we're calculating a day using relative weeks
$matches = array();
$pattern = '/this week|next week|previous week|last week/i';
if ( preg_match( $pattern, $string, $matches )) {
$string = str_replace($matches[0], '-7 days '.$matches[0], $string);
}
}
return parent::modify($string);
}
}
没有什么可以阻止您手动修改日期以获得一周的“第一天”,具体取决于您对“第一天”的定义。 例如:
$firstDayOfWeek = 1; // Monday
$dateTime = new DateTime('2012-05-16'); // Wednesday
// calculate how many days to remove to get back to the "first" day
$difference = ($firstDayOfWeek - $dateTime->format('N'));
if ($difference > 0) { $difference -= 7; }
$dateTime->modify("$difference days");
var_dump($dateTime->format('r')); // "Mon, 14 May 2012 00:00:00 +0000"
请注意输出如何随$firstDayOfWeek
的变化而变化; 如果将其更改为上面的4
(星期四),则它会将Thu, 10 May 2012
视为“第一天”。
编辑:这是一个相当基本的例子。 执行此操作的正确方法是使用用户/系统的区域设置为您提供“第一”天,并从那里开始计算。 有关详细信息,请参阅此问题。
也可以通过setISODate获取一周的开始和结束,最后一个参数是一周中的ISO-daynumber,周一是1,周日是7
$firstday = new \DateTime();
$lastday = clone($firstday);
$firstday->setISODate($firstday->format("Y"),$firstday->format("W"),1);
$lastday->setISODate($firstday->format("Y"),$firstday->format("W"),7);
正确答案:
$week_start_day; // 0 - Sunday, 1 - Monday
$date_time_from = new DateTime('now');
$date_time_to = clone $date_time_from;
$this_week_first_day = $date_time_from->setISODate($date_time_from->format("Y"), $date_time_from->format("W"), $week_start_day);
$this_week_last_day = $date_time_to->setISODate($date_time_to->format("Y"), $date_time_to->format("W"), (6 + $week_start_day));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.