所以这是我今天学到的一个有趣的问题。
我需要填充过去12个月的数组,从过去一个月开始。所以在2011年8月,过去12个月将是2010年9月 - 2011年7月。为此,我正在使用:
for ($i = 1; $i <= 12; $i++)
$months[] = date("Y-m%", strtotime("-$i months"));
上面的代码在8月30日运行正常。我过去12个月了:
array
0 => string '2011-07%' (length=8)
1 => string '2011-06%' (length=8)
2 => string '2011-05%' (length=8)
3 => string '2011-04%' (length=8)
4 => string '2011-03%' (length=8)
5 => string '2011-02%' (length=8)
6 => string '2011-01%' (length=8)
7 => string '2010-12%' (length=8)
8 => string '2010-11%' (length=8)
9 => string '2010-10%' (length=8)
10 => string '2010-09%' (length=8)
11 => string '2010-08%' (length=8)
但是当我在8月31日运行时,我得到了:
array
0 => string '2011-07%' (length=8)
1 => string '2011-07%' (length=8)
2 => string '2011-05%' (length=8)
3 => string '2011-05%' (length=8)
4 => string '2011-03%' (length=8)
5 => string '2011-03%' (length=8)
6 => string '2011-01%' (length=8)
7 => string '2010-12%' (length=8)
8 => string '2010-12%' (length=8)
9 => string '2010-10%' (length=8)
10 => string '2010-10%' (length=8)
11 => string '2010-08%' (length=8)
我尝试过Windows和Unix。有人有解决方案吗?
答案 0 :(得分:53)
我确信有人会有一个更优雅的解决方案,但你可以从本月1日起开始倒计时。
for ($i = 1; $i <= 12; $i++) {
$months[] = date("Y-m%", strtotime( date( 'Y-m-01' )." -$i months"));
}
答案 1 :(得分:1)
这是因为不是每个月都有31个。所以strtotime()
正在推进到下个月。即4/31 = 5/1。
你最好使用mktime()
,因为它是 dumber 而不是strtotime()
。
要利用strtotime()
之类的智能功能并避免跟踪mktime()
的年份,以下是我的建议:
$month = time();
for ($i = 1; $i <= 12; $i++) {
$month = strtotime('last month', $month);
$months[] = date("r", $month);
}
print_r($months);
根据需要调整逻辑并进行优化。
答案 2 :(得分:1)
我认为这会起作用:
$this_month = date("n", time());
$this_year = date("Y", time());
$months_array = array();
for ($i = $this_month - 1; $i > ($this_month - 13); $i--) {
echo "$i<br>";
if ($i < 1) {
$correct_month_number = $i + 12;
$months_array[] = array($correct_month_number, $this_year - 1);
}
else {
$months_array[] = array($i, $this_year);
}
}
echo "<pre>"; var_dump($months_array); echo "</pre>";
数据类型有些松散,但这可以完成工作。这样做的好处是,它只对当前月份和年份调用一次date()函数。其余逻辑只是简单的数学运算。不必担心每个月的时间。
然后,您可以使用$ months_array数组构建所需的任何内容。
答案 3 :(得分:1)
我想用DatePeriod
提出另一种解决方案。
这里有很多注意事项。一方面,您不希望遇到诸如时区信息或天 / 时间信息之类的问题。您只对月份感兴趣。因此,我们可以对其中一些信息进行规范化处理,以防止发生诸如溢出和夏令时并发症之类的并发症。由于您可以仅在发生这些罕见事件的特定日期/时间容易陷入该陷阱。 / p>
$start = new DateTime;
$start->setDate($start->format('Y'), $start->format('n'), 1); // Normalize the day to 1
$start->setTime(0, 0, 0); // Normalize time to midnight
$start->sub(new DateInterval('P12M'));
$interval = new DateInterval('P1M');
$recurrences = 12;
foreach (new DatePeriod($start, $interval, $recurrences, true) as $date) {
echo $date->format('F, Y'), "\n"; // attempting to make it more clear to read here
}
输出:
February, 2019 March, 2019 April, 2019 May, 2019 June, 2019 July, 2019 August, 2019 September, 2019 October, 2019 November, 2019 December, 2019 January, 2020
答案 4 :(得分:-3)
不同月份长度的乐趣。 strtotime正在逐字逐句,并采取“8月31日”和tryinn制作“9月31日”,这是不存在的。所以你最终得到10月1日或者其他什么。更安全的方法是:
for ($i = 1; $i <= 12; $i++) {
$months[] = date("Y-m%", mktime(0, 0, 0, $i, 1, 2011));
}
strtotime有时是神奇的,但它不可靠,当然也不“快”。
答案 5 :(得分:-3)
问题在于,就PHP而言,一个月总是有30天,因此8月31日减1个月仍然是8月。以下代码可能不是最有效或最出色的代码,但它可以完成这项工作:
<?php
$m = strftime('%m');
$y = strftime('%Y');
for($i=1; $i<12; $i++)
{
$m--;
if($m <= 0)
{
$y--;
$m = 12;
}
print "$y-$m\n";
}
?>