Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从列表中省略少于31天的月份_Php_Date - Fatal编程技术网

Php 从列表中省略少于31天的月份

Php 从列表中省略少于31天的月份,php,date,Php,Date,考虑一下昨天运行良好的以下代码,但今天3月30日,它已停止工作 <form class="date"> <select name="date" onchange="this.form.submit()"> <?php for ($i = 0; $i <= 60; ++$i) { $time = strtotime(sprintf('+%d months', $i)); $value = date('Y-m', $time); $l

考虑一下昨天运行良好的以下代码,但今天3月30日,它已停止工作

<form class="date">
<select name="date" onchange="this.form.submit()">

<?php
  for ($i = 0; $i <= 60; ++$i) {
    $time = strtotime(sprintf('+%d months', $i));
    $value = date('Y-m', $time);
    $label = date('F Y', $time);
    $nowvalue = date('Y-m');
    $nowlabel = date('F Y');
        if(isset($_GET['date'])) {
          if(strcmp($value,$_GET['date']) == 0) {
             //If 0, $value and $_GET['date'] are the same: The option is selected
             printf('<option value="%s" selected>%s</option>', $value, $label);
          } else {
             printf('<option value="%s">%s</option>', $value, $label);
          }
        } else {
          if($value == $nowvalue) {
            printf('<option value="%s" selected>%s</option>', $value, $label);
          } else {
            printf('<option value="%s">%s</option>', $value, $label);  
          }
    }
  }
  ?>
</select>
</form>
这将输出一个未来月份的选择列表,一旦更改,将在URL中使用另一个查询重新加载页面,以便对该页面上的日历做出反应

如果我手动更新URL中的查询,它可以正常工作,但此选择列表正在重复日期,请查看下图

所有天数最短的月份都不见了,或者事实上被替换为与前一个月相同的名称,这不是巧合吗


有人知道为什么会发生这种情况吗?

这是因为当你在每月31日循环查看日期时,你会遇到少于30天的月份。PHP会自动将日期调整到每月的最后一天,但会转到月末,然后将剩余的天数添加到该日期中,并以这种方式获取下一个月的日期

所以如果你到了2月,大多数年份只有28天,那么到了28日,再加上3天,你就到了3月3日


要解决这个问题,您需要将日期设置为每月的第一天,然后迭代日期。

这是因为当您在每月31日循环日期时,您将遇到少于30天的月份。PHP会自动将日期调整到每月的最后一天,但会转到月末,然后将剩余的天数添加到该日期中,并以这种方式获取下一个月的日期

所以如果你到了2月,大多数年份只有28天,那么到了28日,再加上3天,你就到了3月3日


要解决这个问题,您需要将日期设置为每月的第一天,然后重复这些日期。

正如John Conde指出的,这是因为今天的日期31加一个月实际上是5月1日,而4月则被跳过

我做了以下操作,将日期设置为每月1日,然后再加上一个月

<?php
  for ($i = 0; $i <= 60; ++$i) {
    $firstofthismonth = '01-' . date('m-Y');
    $time = strtotime(sprintf($firstofthismonth . '+%d months', $i));
    $value = date('Y-m', $time);
    $label = date('F Y', $time);
    $nowvalue = date('Y-m');
    $nowlabel = date('F Y');
        if(isset($_GET['date'])) {
          if(strcmp($value,$_GET['date']) == 0) {
             //If 0, $value and $_GET['date'] are the same: The option is selected
             printf('<option value="%s" selected>%s</option>', $value, $label);
          } else {
             printf('<option value="%s">%s</option>', $value, $label);
          }
        } else {
          if($value == $nowvalue) {
            printf('<option value="%s" selected>%s</option>', $value, $label);
          } else {
            printf('<option value="%s">%s</option>', $value, $label);  
          }
    }
  }
  ?>

正如约翰·康德所指出的,这是因为今天的日期31加上一个月实际上是5月1日,而4月则被跳过

我做了以下操作,将日期设置为每月1日,然后再加上一个月

<?php
  for ($i = 0; $i <= 60; ++$i) {
    $firstofthismonth = '01-' . date('m-Y');
    $time = strtotime(sprintf($firstofthismonth . '+%d months', $i));
    $value = date('Y-m', $time);
    $label = date('F Y', $time);
    $nowvalue = date('Y-m');
    $nowlabel = date('F Y');
        if(isset($_GET['date'])) {
          if(strcmp($value,$_GET['date']) == 0) {
             //If 0, $value and $_GET['date'] are the same: The option is selected
             printf('<option value="%s" selected>%s</option>', $value, $label);
          } else {
             printf('<option value="%s">%s</option>', $value, $label);
          }
        } else {
          if($value == $nowvalue) {
            printf('<option value="%s" selected>%s</option>', $value, $label);
          } else {
            printf('<option value="%s">%s</option>', $value, $label);  
          }
    }
  }
  ?>

这只是供参考,因为我意识到你已经添加了自己的答案

如果需要,您可以使用来简化代码

所以你可能会得到这样的结果:

<select name="date" onchange="this.form.submit()">

    <?php

    $selected = DateTime::createFromFormat('Y-m-d', @$_GET['date'] . '-01') ?: new DateTime('first day of this month');

    for ($i = 0; $i <= 60; $i++) {

        $date = (new DateTime('first day of this month'))->modify("+$i months");

        $select = $date == $selected ? 'selected' : '';

        printf('<option value="%s" %s>%s</option>', $date->format('Y-m'), $select, $date->format('F-Y'));

    }
    ?>

</select>

希望这有帮助

这只是供参考,因为我意识到您已经添加了自己的答案

如果需要,您可以使用来简化代码

所以你可能会得到这样的结果:

<select name="date" onchange="this.form.submit()">

    <?php

    $selected = DateTime::createFromFormat('Y-m-d', @$_GET['date'] . '-01') ?: new DateTime('first day of this month');

    for ($i = 0; $i <= 60; $i++) {

        $date = (new DateTime('first day of this month'))->modify("+$i months");

        $select = $date == $selected ? 'selected' : '';

        printf('<option value="%s" %s>%s</option>', $date->format('Y-m'), $select, $date->format('F-Y'));

    }
    ?>

</select>

希望这有帮助

这些问题每31个月都会出现…这些问题每31个月都会出现…谢谢你的评论,我理解现在发生了什么,但是改变这一行没有帮助。我本以为$time=strottimesprintf'+%d个月',$I;是罪魁祸首,因为它从3月31日算起+1个月,如果30天是正确的话,那就是5月1日?我只是在看这个。不幸的是,您删除了有助于确定在何处进行更改的代码,但简而言之,只需将迭代的日期更改为每月的第一天。这将解决你的问题。谢谢,我现在已经弄明白了,我将发布一个单独的答案。谢谢你的评论,我理解现在发生了什么,但是改变这一行没有帮助。我本以为$time=strottimesprintf'+%d个月',$I;是罪魁祸首,因为它从3月31日算起+1个月,如果30天是正确的话,那就是5月1日?我只是在看这个。不幸的是,您删除了有助于确定在何处进行更改的代码,但简而言之,只需将迭代的日期更改为每月的第一天。这会解决你的问题。谢谢,我现在已经弄明白了,我会发布一个单独的答案。