2010-11-27 27 views
10

Ésta es la función que estoy tratando de escribir:agarrar todos los miércoles en un mes dado en PHP

function getWednesdays($month, $year) { 
    // Returns an array of DateTimes representing all Wednesdays this month. 
} 

¿Alguna idea? Gracias-

+0

si tiene disponible DateTime, es bastante fácil. Compruebe http://www.php.net/manual/en/class.datetime.php – hummingBird

Respuesta

26

Con 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") 
    ); 
} 

Uso:

foreach (getWednesdays(2010, 11) as $wednesday) { 
    echo $wednesday->format("l, Y-m-d\n"); 
} 

Salida:

Wednesday, 2010-11-03 
Wednesday, 2010-11-10 
Wednesday, 2010-11-17 
Wednesday, 2010-11-24 

Tenga en cuenta que esto excluye la fecha de finalización, por lo que si el último día de $y-$m pasa a ser una Miércoles, no estará en la lista. Debe agregar un día a la fecha de finalización para incluirlo. Incluirlo, cambiar el formato relativo en la fecha de finalización para

new DateTime("next month $y-$m-01") 

que se ajuste la fecha final del primer día del mes siguiente,


Con 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; 
} 

Uso:

foreach (getWednesdays(2010, 11) as $wednesday) { 
    echo date("l, Y-m-d\n", $wednesday); 
} 

Mismo resultado que el anterior (Run on Codepad).

Tenga en cuenta que esto does not work for any version prior to 5.3 debido a cambios en el analizador de formatos relativos. Si desea usar esto con PHP 5.3+, debe cambiar first Wednesday $y-$m-01 a first Wednesday of $y-$m-01 (tenga en cuenta "de"). Además, al igual que en la versión DateTime, la fecha de finalización no se incluirá.


Lectura adicional:

+1

Si regreso todos los viernes en enero de 2014, recibo 4 viernes que no incluye el último día del mes, que es un viernes. ¿Algunas ideas? –

+0

@LukeOliff excluye la fecha de finalización. Tendrá que agregarle un día para incluirlo. Ver actualización – Gordon

+0

Sí, gracias. Planteé una pregunta al respecto aquí: http://stackoverflow.com/questions/17891477/php-dateinterval-not-returning-last-day-of-the-month/17891550?noredirect=1#17891550 y solo necesito agregue un segundo, pero usó un minuto solo en el caso :) –

-2

Si no se proporciona DateTime, necesita saber el día de una fecha: inicio de la era de Unix, por ejemplo (1 de enero de 1970).

A partir de allí, simplemente busque el primer miércoles, y a partir de allí encuentre su mes. Tenga en cuenta los años bisiestos, y está bien.

Obviamente, no es el algoritmo más eficiente del mundo, pero haría el trabajo.

+0

Creo que está buscando todos los miércoles para el mes dado, especificado por los valores de mes y año. – Codemwnci

+0

lo sé :) ... la primera parte del algoritmo anterior está conectada al proceso de llegar al primer wed en el mes dado. si no se proporciona nada más, debe haber algún tipo de día de "ancla" para comenzar con – hummingBird

+0

@ playcat- No entendió la pregunta- vea otras respuestas – Yarin

2

Probablemente hay una manera más eficiente de hacerlo, pero esto funciona:

<?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; 
} 

Puede probar con esto:

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

4

Usted puede intentar algo como esto:

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; 
} 
+0

Una muy buena respuesta, gracias – Yarin

2
<?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)); 

?> 

Pero le recomiendo que se acostumbre a las funciones de fecha y hora de PHP 5.3 si puede usarlas. (Consulte la respuesta de Gordon.)

+0

Otra muy buena respuesta, pero tienes razón, Gordon está haciendo el mejor uso de las funciones existentes de PHP. – Yarin

1

Con PHP anterior a 5.3 esta solución no funciona. Parece que la marca de tiempo del primer día es mayor que la marca de hora del último día, que finalmente termina el ciclo en el primer intento.

Como PHP calcula las diferencias horarias a la medianoche, esta solución no funciona cuando el mes comienza en el día en cuestión. Y para algunos casos tampoco funciona el último día.

He resuelto estos problemas en el siguiente código. Y este código se puede usar para cualquier día de la semana.

La solución fue creado con la ayuda de código de Eli en esta pregunta: 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 ///// 

espero que ayude a alguien.

0

He escrito siguiente código para este propósito ... y su trabajo perfectamente para mí

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; } 

Podemos utilizarlo como:

$days = get_month_date($year, $month, 'Wednesday'); 

volverá conjunto de todas las fechas del miércoles en un mes y año dados

3

Utilice esta función para obtener el conteo total de cualquier día en un mes

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; 
} 

usa getTotalDays ('2014', '08', 'lunes');

es la salida 4

Pero si desea que todas las fechas de un mes en un día en particular, entonces utilizar esta función

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; 
} 

uso como esto getTotalDatesArray '2014', '08', 'Lunes (');

saldrá matriz ([0] => 2014-08-04 [1] => 2014-08-11 [2] => 2014-08-18 [3] => 2014-08-25)

1

he reescrito @ solución de Gordon para adaptarse a cualquier día

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") 
     ); 
} 

Ahora simplemente puede hacer get_dates_of_day('2015','08','wednesday') y utilizar el mismo para obtener las fechas para cualquier día en un mes determinado.

0

Aquí está la muestra

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); 
0

prueba este para obtener todos los miércoles en el mes en curso.

$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); 
Cuestiones relacionadas