【问题标题】:Determine Monday and Friday code stopped working确定周一和周五代码停止工作
【发布时间】:2018-02-06 20:58:01
【问题描述】:

我有一个数据库中的条目,我想按它们发生的星期对其进行分组。我要做的是确定条目发生在一年中的哪一周,然后显示该周以及该周的星期一和星期五。此页面http://princeave.com/bo/test.php 显示了我得到的输出。请注意,星期一和星期五对于 2017 年发生的事件是正确的,但对于 2018 年发生的事件则不正确。代码如下。我错过了什么?

<?php //Gets list of weeks that I can bill
    try {
        $stmt2 = $db->prepare("SELECT DISTINCT YEAR(transaction_date) AS YR, WEEK(bo_hourly_charges.transaction_date) as wk FROM bo_hourly_charges WHERE billed_by='AfterCare' ORDER BY transaction_date DESC");
        $stmt2->execute();
         // set the resulting array to associative
         $result2 = $stmt2->setFetchMode(PDO::FETCH_ASSOC); 
        $count = $stmt2->rowCount();
    }
    catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
    }
?>
<div align='center'>

<br>
        <?php 
            foreach (($stmt2) as $row) { 
                $fix = $row['YR']."W".$row['wk'];
                $monday=date('M d',strtotime($fix));
                $friday=date('M d',strtotime($fix.'5'));
                print $fix." ".$row['wk']." ".$monday."-".$friday."<br>";
                ++$i;
             }
        ?>

【问题讨论】:

  • 可能是strtotime($fix),因为我无法在此处提交对 yyyyWnn 格式的任何引用:php.net/manual/en/datetime.formats.date.php 但这只是一个疯狂的猜测。哦,停下,我找到了! :-) 它是一种复合格式。它建议在星期五的 5 点之前使用-(破折号),也许是这样?当它必须是 15 和 1-5 时,我可能无法区分 15 和 15。显然我不知道......对不起。

标签: php mysql date


【解决方案1】:

有趣的问题,我不知道 PHP 允许这种格式。我不相信这是记录在案的行为。因此,依赖它可能并不明智。

Running your code with the full range of weeks in 2017 快速显示该问题与 2018 年无关:

<?php

$dates = [];
for ($i = 1; $i <= 52; $i++) {
    $dates[] = ['YR' => 2017, 'wk' => $i];
}

foreach ($dates as $row) { 
    $fix = $row['YR']."W".$row['wk'];
    $monday=date('M d',strtotime($fix));
    $friday=date('M d',strtotime($fix.'5'));
    print $fix." ".$row['wk']." ".$monday."-".$friday."\n";
    ++$i;
}

产量:

(...)
2017W5 5 Dec 31-Dec 31
2017W6 6 Dec 31-Dec 31
2017W7 7 Dec 31-Dec 31
2017W8 8 Dec 31-Dec 31
2017W9 9 Dec 31-Dec 31
2017W10 10 Mar 06-Mar 10
2017W11 11 Mar 13-Mar 17
2017W12 12 Mar 20-Mar 24
2017W13 13 Mar 27-Mar 31
2017W14 14 Apr 03-Apr 07
(...)

相反,2017 年的前九周似乎存在类似问题。从第 10 周开始,问题似乎已解决。

第 1 周到第 9 周与第 10 周及以后的差异与格式密切相关。

Padding the weeks with a zero似乎解决了问题:

<?php

$dates = [];
for ($i = 1; $i <= 52; $i++) {
    $dates[] = ['YR' => 2017, 'wk' => $i];
}

foreach ($dates as $row) { 
    $fix = $row['YR']."W".str_pad($row['wk'], 2, '0', STR_PAD_LEFT);
    $monday=date('M d',strtotime($fix));
    $friday=date('M d',strtotime($fix.'5'));
    print $fix." ".$row['wk']." ".$monday."-".$friday."\n";
    ++$i;
}

然而,更明智的选择是使用更常见的日期格式。

【讨论】:

  • 请内联发布您的代码,这样我们就不需要点击链接了。
  • 感谢您的帮助。我是新手,向你学习!
【解决方案2】:

根据official documentationISO year with ISO week and day 的正确复合日期定义如下:

YY "-"? "W" W "-"? [0-7]

其中破折号 (-) 是可选的(这是紧随其后的问号 ? 的含义)。因此,您的格式没有任何问题......但是您的代码发生的情况是,例如,2018W4(2018 年第 4 周)变为2018-W45(2018 年第 45 周),一切都变得一团糟。为避免格式不明确,请确保您的周数始终包含 two digits(从 0153)并通过零填充:

$fix = $row['YR'].'W'.sprintf('%02d',$row['wk']);

附带说明,如果您想使用准备好的 SQL 语句,您应该避免在查询中手动插入参数。否则,您将徒劳无功地利用这种方法的主要目的之一:安全。

$stmt2 = $db->prepare("SELECT DISTINCT YEAR(transaction_date) AS YR, WEEK(bo_hourly_charges.transaction_date) as wk FROM bo_hourly_charges WHERE billed_by=? ORDER BY transaction_date DESC");
$stmt2->bind_param('s','AfterCare'); 

【讨论】:

  • 问题只是W 必须始终为两位数("0"[1-9] | [1-4][0-9] | "5"[0-3])。 - 没关系。
猜你喜欢
  • 2018-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-03
  • 1970-01-01
  • 2015-09-24
相关资源
最近更新 更多