Grab all Wednesdays in a given month in PHP
This is the function I'm trying to write:
function getWednesdays($month, $year) {
// Returns an array of DateTimes representing all Wednesdays thi开发者_如何学编程s month.
}
Any ideas? Thanks-
With PHP5.3
function getWednesdays($y, $m)
{
return new DatePeriod(
new DateTime("first wednesday of $y-$m"),
DateInterval::createFromDateString('next wednesday'),
new DateTime("last day of $y-$m")
);
}
Usage:
foreach (getWednesdays(2010, 11) as $wednesday) {
echo $wednesday->format("l, Y-m-d\n");
}
Output:
Wednesday, 2010-11-03
Wednesday, 2010-11-10
Wednesday, 2010-11-17
Wednesday, 2010-11-24
Note that this will exclude the end date, so if the last day of $y-$m
happens to be a Wednesday, it won't be in the list. You have to add a day to the end date, to include it. To include it, change the relative format in the end date to
new DateTime("next month $y-$m-01")
which will then set the end date to the first day of the next month,
With PHP < 5.3
function getWednesdays($y, $m)
{
$ts = strtotime("first wednesday $y-$m-01");
$end = strtotime("last wednesday $y-$m");
$wednesdays = array();
while($ts <= $end) {
$wednesdays[] = $ts;
$ts = strtotime('next wednesday', $ts);
}
return $wednesdays;
}
Usage:
foreach (getWednesdays(2010, 11) as $wednesday) {
echo date("l, Y-m-d\n", $wednesday);
}
Same output as above (Run on Codepad).
Note that this does not work for any version prior to 5.3 due to changes in the relative formats parser. If you want to use this with PHP 5.3+ you have to change first Wednesday $y-$m-01
to first Wednesday of $y-$m-01
(mind the "of"). Also, just like in the DateTime version, the end date will not be included.
Further reading:
- DateTime in PHP Manual
- Relative DateTime Formats
- Derick Rethans: Advanced Date/Time Handling (ZendCon 10)
- Relative item in date strings (mirror)
You can try something like this:
function getWednesdays($month, $year) {
$base_date = strtotime($year . '-' . $month . '-01');
$wed = strtotime('first wed of ' . date('F Y', $base_date));
$wednesdays = array();
do {
$wednesdays[] = new DateTime(date('r', $wed));
$wed = strtotime('+7 days', $wed);
} while (date('m', $wed) == $month);
return $wednesdays;
}
Use this function to get any days total count in a month
function getTotalDays($year, $month, $day){
$from = $year."-".$month."-01";
$t=date("t",strtotime($from));
for($i=1; $i<$t; $i++){
if( strtolower(date("l",strtotime($year."-".$month."-".$i)))== $day){
$count++;
}
}
return $count;
}
use like this getTotalDays('2014', '08','monday');
will output 4
But if you want all dates in a month on a particular day then use this function
function getTotalDatesArray($year, $month, $day){
$date_ar=array();
$from = $year."-".$month."-01";
$t=date("t",strtotime($from));
for($i=1; $i<$t; $i++){
if( strtolower(date("l",strtotime($year."-".$month."-".$i)))== $day){
$j= $i>9 ? $i: "0".$i;
$date_ar[]=$year."-".$month."-".$j;
}
}
return $date_ar;
}
use like this getTotalDatesArray('2014', '08','monday');
will output Array ( [0] => 2014-08-04 [1] => 2014-08-11 [2] => 2014-08-18 [3] => 2014-08-25 )
There's probably a more efficient way to do it, but this works:
<?php
function isWednesday($day, $month, $year)
{
if (date('w', $date = mktime(0,0,0,$month,$day,$year)) == 3) {
return $date;
}
return false;
}
function getWednesdays($month, $year)
{
for ($day=1; $day<=7; $day++) {
if ($date = isWednesday($day, $month, $year)) {
break;
}
}
$wednesdays = array();
while (date('m',$date) == $month) {
$wednesdays[] = $date;
$day += 7;
$date = isWednesday($day, $month, $year);
}
return $wednesdays;
}
You can test with this:
foreach (getWednesdays($argv[1], $argv[2]) as $date) {
echo date("Y-m-d\n", $date);
}
$ php wednesdays.php 11 2010
2010-11-03
2010-11-10
2010-11-17
2010-11-24
$ php wednesdays.php 12 2010
2010-12-01
2010-12-08
2010-12-15
2010-12-22
2010-12-29
$ php wednesdays.php 2 2012
2012-02-01
2012-02-08
2012-02-15
2012-02-22
2012-02-29
S
<?php
function wednesdays($month, $year)
{
list($n,$d) = explode('-', date('t-d', strtotime("Wednesday, $year-$month")));
$days = array();
while ($d <= $n)
{
$days[] = sprintf("%04d-%02d-%02d", $year, $month, $d);
$d += 7;
}
return $days;
}
var_dump(wednesdays(11, 2010));
?>
But I highly recommend getting used to PHP 5.3's date and time functions if you can use them. (See Gordon's answer.)
With PHP earlier than 5.3 this solution doesn't work. Seems, First Day Time stamp is greater than the last day time stamp, which eventually terminate the loop in first go.
As PHP calculates time differences at midnight, this solution does not work when the month starts on the day in question. And for some cases does not work for the last day either.
I've sorted out these problems in following code. And this code can be used for any day of week.
The solution was created with the help of Eli's code in this question: Get the First or Last Friday in a Month
///// code starts here /////
function getWeekDates($year, $month, $day){
$tsInMonth = strtotime("$year-$month");
$monthNumber = (int)date("m",$tsInMonth);
$Names = array( 1=>"Sun", 2=>"Mon", 3=>"Tue", 4=>"Wed", 5=>"Thu", 6=>"Fri", 7=>"Sat" );
$ThisMonthTS = strtotime( date("Y-m-01", $tsInMonth ) );
$NextMonthTS = strtotime( date("Y-m-01", strtotime("next month", $tsInMonth) ) );
$weekDates = array();
for($Ord=1;$Ord<=5;$Ord++){
$DateOfInterest = (-1 == $Ord)
? strtotime( "last ".$Names[$day], $NextMonthTS )
: strtotime( $Names[$day]." + ".($Ord-1)." weeks", $ThisMonthTS );
($Ord==5 && (int)date("m",$DateOfInterest)==(int)date("m",$NextMonthTS))
? false
: $weekDates [] = $DateOfInterest;
}
return $weekDates;
}
///// Usage /////
foreach (getWeekDates("2010", "2", "2") as $day) {
echo "<br>" . date("l, Y-m-d", $day);
}
///// End of code /////
I hope it helps someone.
I have re-written @Gordon's solution to suit for any day
function get_dates_of_day($y, $m, $day_name)
{
return new DatePeriod(
new DateTime("first $day_name of $y-$m"),
DateInterval::createFromDateString("next $day_name"),
new DateTime("next month $y-$m-01")
);
}
Now you can simply do get_dates_of_day('2015','08','wednesday')
and use the same to get dates for any day in a given month.
I have written following code for this purpose ... and its working perfectly for me
function get_month_date($year, $month, $day) {
$monthdays = date('t', mktime(0, 0, 0, $month, 1, $year));
$dates = array();
for($i = 0; $i <= $monthdays; $i++ ) {
if($day == date('l', mktime(0, 0, 0, $month, 1+$i, $year)) && $month == date('n', mktime(0, 0, 0, $month, 1+$i, $year))) {
$dates[] = date('Y-m-d', mktime(0, 0, 0, $month, 1+$i, $year));
}
}
return $dates; }
We can use it as :
$days = get_month_date($year, $month, 'Wednesday');
It will return array of all dates of Wednesday in given month and year
Here is the sample
function getSundays($y,$m){
$date = "$y-$m-01";
$first_day = date('N',strtotime($date));
$first_day = 7 - $first_day + 1;
$last_day = date('t',strtotime($date));
$days = array();
for($i=$first_day; $i<=$last_day; $i=$i+7 ){
$days[] = $i;
}
return $days;
}
$days = getSundays(2016,04);
print_r($days);
Try This one to get all Wednesdays in current month.
$month = date('m');
$year = date('Y');
function getDays($year,$month){
$days = cal_days_in_month(CAL_GREGORIAN, $month,$year);
$wed = array();
for($i = 1; $i<= $days; $i++){
$day = date('Y-m-'.$i);
$result = date("D", strtotime($day));
if($result == "Wed"){
$wed[] = date("Y-m-d", strtotime($day)). " ".$result."<br>";
}
}
return $wed;
}
$wed = getDays($year,$month);
print_r($wed);
If DateTime is not given, you need to know the day for one date - start of unix era for example (1st Jan 1970).
Going from there, you simply locate the first wednesday, and from there find your month. Keep in mind the leap years, and you're good.
Obviously, it isn't the most efficient algorithm in the world, but it would do the job.
精彩评论