【问题标题】:Invalid year/week combination in PHP on first days of the year在一年的第一天,PHP 中的年/周组合无效
【发布时间】:2017-04-26 07:23:48
【问题描述】:

为什么会发生这种情况(可能是因为Carbon 扩展了DateTime 和这个http://php.net/manual/es/datetime.format.php#114366)以及如何在更改时区时从Carbon 实例中获取正确的星期?

use Carbon\Carbon;

$wet = Carbon::parse( '2017-01-02 00:47:21', 'WET' );
$cet = Carbon::parse( '2017-01-02 00:47:21', 'CET' );

$new = $cet->copy()->tz( 'WET' );

print_r( [

    'cet->format(ATOM)' => $cet->format( Carbon::ATOM ),    //prints: 2017-01-02T00:47:21+01:00
    'cet->format(Y  W)' => $cet->format( 'Y  W' ),          //prints: 2017  01

    'wet->format(ATOM)' => $wet->format( Carbon::ATOM ),    //prints: 2017-01-02T00:47:21+00:00
    'wet->format(Y  W)' => $wet->format( 'Y  W' ),          //prints: 2017  01

    'new->format(ATOM)' => $new->format( Carbon::ATOM ),    //prints: 2017-01-01T23:47:21+00:00
    'new->format(Y  W)' => $new->format( 'Y  W' ),          //prints: 2017  52

] );

一个更简单的案例:

print_r( [
    Carbon::create( 2017, 1, 1, 0, 0, 1 )->format( 'Y  W' ),        //prints: 2017  52
    Carbon::create( 2016, 12, 31, 23, 59, 59 )->format( 'Y  W' ),   //prints: 2016  52
] );

【问题讨论】:

  • 嗯,那些当地时间有 1 小时的偏移量。从 00:47 切换到 前一天的 23:47。你期待什么结果?
  • 原来问题出在日期,而不是时区本身。当日期更改为当年第一个星期一的前一天时,weekOfYear 字段会更改,但实际的year 不会更改。我已经发布了答案。

标签: php datetime timezone php-carbon


【解决方案1】:

当这一天在一年中的第一周之前时,(例如:2017 年 1 月 1 日) 它返回 52,但不会更改实际年份(返回 2017 年而不是 2016 年),所以我将实例强制到上一年的最后一秒以获得正确的一周

if (50 < $new->weekOfYear && 2 > $new->month)
{
    $new->year( $new->year - 1 )->endOfYear();
}

echo $new->format( 'Y  W' ); //prints: 2016  52

【讨论】:

  • 正如docs 解释的那样,W 是 ISO-8601 年的周数。这不是挂历中的行号,我怀疑这是你所期望的。
  • 我原以为正确的 W 是 52,我没想到这一年仍然是 2017 年...当仅使用“W”进行格式化时,您看不出问题,但是当将“Y W”组合为1 月 1 日,它变成了“2017 52”——这是我没想到的。我需要它是“2016 52”。
  • 感谢您的意见,我已更改标题以免误导他人。
  • 如果您从 2017 年 1 月 2 日开始并切换到另一个时区,则您需要 25 小时的偏移量才能在 2016 年 12 月 31 日结束。DST 可能在技术上使这成为可能,但不是现在欧洲。
  • 我不需要时间戳是正确的,这就是我在实例上使用copy() 的原因。我只需要格式化字符串'Y W'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 2016-11-29
  • 2010-10-24
相关资源
最近更新 更多