使用 PHP 获取过去 12 个月的信息
这是我今天学到的一个有趣的问题。
我需要从上个月开始,用过去 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。有人有解决方案吗?
So here is an interesting problem I learned today.
I need to populate an array with the last 12 months, starting with the past month. So in August 2011, the last 12 months will be Sep 2010 - July 2011. To do this, I am using:
for ($i = 1; $i <= 12; $i++)
$months[] = date("Y-m%", strtotime("-$i months"));
The code above works just fine on August 30. I get the last 12 months:
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)
But when I run this on Aug 31, I get:
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)
I have tried both Windows and Unix. Does anyone have a solution for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我确信有人有更优雅的解决方案,但您可以从本月 1 日开始倒数。
I'm sure someone has a more elegant solution, but you could start counting backwards from the 1st of this month.
我想提出一个使用
DatePeriod
的替代解决方案。这里有许多注意事项需要注意。首先,您不希望时区信息或日期/时间信息等信息妨碍您。您只对月份感兴趣。因此,我们可以对其中一些信息进行标准化,以防止溢出和夏令时并发症等并发症……因为仅在这些罕见事件发生的特定日期/时间,您可能很容易陷入这个陷阱。
输出:
I'd like to propose an alternative solution using
DatePeriod
instead.There are a number of caveats to watch out for here. For one, you don't want things like Timezone information, or day/time information to get in your way. You're only interested in the month. So we can normalize some of this information to prevent complications like overflows and daylight savings complications, etc... Since you could easily fall into this trap only on specific dates/times when these rare events occur.
Output:
因为并不是每个月都有 31 号。因此
strtotime()
会提前到下个月。即 4/31 = 5/1。为此,您最好使用
mktime()
,因为它比strtotime()
更笨。更新
要利用
strtotime()
等智能函数并避免跟踪mktime()
的年份,以下是我的建议:调整逻辑并根据您认为合适的方式进行优化。
It's because not every month has a 31st. So
strtotime()
is advancing to the next month. i.e. 4/31 = 5/1.You'd be better off using
mktime()
for this as it's dumber thanstrtotime()
.UPDATE
To take advantage of a smart function like
strtotime()
and avoid tracking the year formktime()
, the following is my suggestion:Adjust logic and optimize as you see fit.
我认为这会起作用:
数据类型有点松散,但这可以完成工作。这样做的好处是它只调用当前月份和年份的 date() 函数一次。其余的逻辑只是简单的数学。无需担心每个月的长度。
然后您可以使用 $months_array 数组来构建您需要的任何内容。
I think this will work:
The data types are a little loose, but this gets the job done. The nice thing about this is that it only calls the date() function for the current month and year, once. The rest of the logic is just simple math. No need to worry about the length of each month.
Then you can use the $months_array array to build whatever you need.
不同月份长度的乐趣。 strtotime 是字面上的意思,并尝试将“Aug 31”改为“Sep 31”,而“Sep 31”并不存在。所以你最终会得到 10 月 1 日之类的东西。更安全的方法是:
strtotime 有时很神奇,但它不可靠,而且肯定不“快”。
The joys of different month lengths. strtotime is being literally, and taking 'Aug 31' and tryinn to make "Sep 31", which doesn't exist. So you end up with Oct 1 or something. A safer approach is this:
strtotime is magical sometimes, but it's not reliable and certainly not "fast".