2012-10-29 33 views
5

只要您所在国家/地区的一周中的第一天是星期天,PHP中的DateTime类(5.3+)就会很有用。在荷兰,星期一的第一天是星期一,这让班级无法用周历和计算来制作日历。PHP DateTime()类,将星期几的第一天更改为星期一

我似乎无法在Stackoverflow或其他互联网上找到关于如何使DateTime的行为,就好像一周的第一天是星期一一样的答案。

我在Stackoverflow上找到了这篇文章,但它并不能解决所有可能导致问题的方法,也不是一个优雅的解决方案。

$dateTime = new DateTime('2012-05-14'); 
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week'); 

有没有办法改变这个或范围DateTime?无法想象这不是一个设置,因为大部分欧洲在周一开始他们的周。

加: 发布完整的日历和功能代码不会让事情更清晰。但是,例如这里只有一行。 我经常需要检查一周中的第一天是什么,或者从一周的第一天计算到当周的不同日期和时间。我的代码越来越充满了这些:

$startOfWeek = $date->modify(('Sunday' == $date->format('l')) ? 'Monday last week' : 'Monday this week')->modify('+3 hours')->format(DATETIME); 

我也得到一个不想要的结果试图得到一个月或一年的第一整周。由于我的$ date对象并不总是包含相同的日期,所以我必须继续以这种方式进行检查,从而使代码难以阅读。在这个日历上有更多的编程工作,我不能预见它会再次出现问题。

编辑虽然有一些不一致之处。由于一些奇怪的原因,日期时间不会得到这个下一个正确的:

$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 

但我想我可以使问题更加清晰: 能的日期时间()类与周一作为一周的第一天。如果不是的话,这个班级可以延长到星期一作为一周的第一天。

UPDATE: 好吧,我想我找到感觉了...我不是在编码classes..but这似乎对周工作亲。但是它仍然需要第一天,第二天......以及星期日本身的日期。我不认为这是万无一失的。我将不胜感激任何帮助解决它。

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'); 
+2

你到底面临的问题是什么? – Jon

+2

听起来像一个XY问题。星期日映射为0的事实不应阻止您使用其他技术来确定每周的开始时间。 – cmbuckley

+0

你的问题是抽象的。提供用于创建日历的代码。至于现在没有你的问题的答案 – BeRocket

回答

5

我发现这个工作,但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); 

} 

} 
2

没有什么能阻止你手动修改的日期,以获得一周的“第一次”天,这取决于你的“第一次”的定义。例如:

$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视为“第一天”。

编辑:这是一个相当基本的例子。正确的做法是通过使用用户/系统的区域设置为您提供“第一个”日期,并从那里进行计算。有关更多信息,请参见this question

+0

感谢cbuckley,这是否意味着DateTime类本身不能设置为使用星期一作为本地的第一个工作日? – Edward

+0

对于更聪明的东西,正确的方法是使用语言环境。我已经添加了该效果的更新。 – cmbuckley

+0

cbuckly,我不认为语言环境更新通过。我正在尝试根据您的示例撰写一堂课,该课程将拦截“下周”,“本周”,“上周”等任何内容并对其进行更改。不知道如果我只是浪费我的时间.. – Edward

0

我也感到困惑的是什么问题,因为DateTime有从周一开始的一周中的概念:在N format给你一周从周一计数至周日,周一是1和周日的天此外,W格式是获得周数的唯一方式,也是周一开始的一周。 (我似乎记得荷兰的周数与ISO周数不完全一样,但这是一个不同的故事)。那么你错过了哪些功能?

编辑所以问题是(只?)是,relative datetime formats,如“本周一”给出错误的结果时,基准日是星期天。从文档听起来像DateTime只是推迟strtotime,这应该是地区依赖。所以如果你有你的语言环境设置正确,这是行不通的,这听起来像一个错误(为什么值得)。

+1

试试这个:$ test = new DateTime('2012-11-04'); echo $ test-> modify('Monday Monday week') - > format('Y-m-d'); // 2012-11-05 //我预计会得到2012-10-29 – Edward

+1

我明白了;所以相对偏移量的英文规范不会出现在星期一的第一个变体中。 – alexis

+0

确切地说......对于周一考虑星期一第一天的所有国家来说都很糟糕。我刚刚发现PHP DateTime扩展名是由荷兰人编写的。#WayToGoDerickRethans – Edward

相关问题