2009-05-29 2 views
10

Ich versuche, eine Kalenderfunktion wie dieseden ersten oder letzten Freitag Erhalten Sie in einem Monat

function get_date($month, $year, $week, $day, $direction) 
{ 
    .... 
} 

$week zu schreiben, ist ein eine ganze Zahl (1, 2, 3 ...), $ day a Tag (So, Mo, ...) oder Nummer, je nachdem, was einfacher ist. Die Richtung ist ein wenig verwirrend, weil es eine andere Berechnung macht.

Ein Beispiel der

get_date(5, 2009, 1, 'Sun', 'forward');

Es nutzt den Standard und bekommt den ersten Sonntag im Mai also 2009-05-03 nennen lassen. Wenn wir

get_date(5, 2009, 2, 'Sun', 'backward');

aufrufen, gibt es die zweite letzten Sonntag im Mai, dh 2009-05-24.

+0

Nur um der Neugier willen .. Wofür verwenden Sie es ?! Es ist nicht so einfach, kann aber trotzdem gemacht werden. – MartinodF

+0

Ich schreibe einen Job-Scheduler. Einige der Positionen sind monatlich, und ich muss in der Lage sein zu bestimmen, welche Daten im Kalender angezeigt werden. – Zahymaka

+0

schrieb es für Sie, hoffe, es funktioniert so, wie Sie es erwartet haben! – MartinodF

Antwort

12

Vielleicht kann es schneller gemacht werden ...
Dies war sehr interessant zu programmieren. Bitte

beachten Sie, dass $direction 1 für Vorwärts- und -1 für die Rückwärts Dinge auch :)
nachzulassen beginnt $day mit einem Wert von 1 für Montag und endet am 7 für Sonntag.

function get_date($month, $year, $week, $day, $direction) { 
    if($direction > 0) 
    $startday = 1; 
    else 
    $startday = date('t', mktime(0, 0, 0, $month, 1, $year)); 

    $start = mktime(0, 0, 0, $month, $startday, $year); 
    $weekday = date('N', $start); 

    if($direction * $day >= $direction * $weekday) 
    $offset = -$direction * 7; 
    else 
    $offset = 0; 

    $offset += $direction * ($week * 7) + ($day - $weekday); 
    return mktime(0, 0, 0, $month, $startday + $offset, $year); 
} 

ich es mit einigen Beispielen getestet haben und scheint immer zu arbeiten, sollten Sie es allerdings nochmals überprüfen;)

+0

Oh und auch, dass Montag = 1, Sonntag = 7 – MartinodF

2

Sie können mktime verwenden, um den Unix-Zeitstempel des ersten Tages im Monat abgerufen werden:

$firstOfMonth = mktime(0, 0, 0, $month, 1, $year); 

Wenn Sie das Datum des ersten Tages von einem bestimmten Monat ist es einfach haben den Wochentag für dieses Datum abrufen date mit:

$weekday = date("N", $firstOfMonth); 

Von dort ist es ziemlich einfach Schritt nur den Zeitpunkt sind Sie nach zu bekommen.

20

Die sprachunabhängig Version:

Um den ersten bestimmten Tag des Monats zu erhalten, beginnt mit dem ersten Tag des Monats: yyyy-mm-01. Verwenden Sie die verfügbare Funktion, um eine Nummer zu vergeben, die dem Wochentag entspricht. Subtrahiere diese Zahl von dem Tag, an dem du suchst; Wenn der erste Tag des Monats beispielsweise Mittwoch (2) ist und Sie nach Freitag (4) suchen, ziehen Sie 2 von 4 ab und 2. Wenn die Antwort negativ ist, fügen Sie 7 hinzu der Monat; für mein Beispiel wäre der erste Freitag der 3..

Um den letzten Freitag des Monats zu finden, finden Sie den ersten Freitag des nächsten Monats und subtrahieren Sie 7 Tage.

0

Finden Sie einfach heraus, was der erste und der letzte Tag des betreffenden Monats ist (dh 1. Mai 2009 ist ein Freitag und 31. Mai 2009 ist ein Sonntag) Ich glaube, die meisten PHP-Funktionen verwenden Montag = 0, Sonntag = 6 , also Freitag = 4, also weißt du, dass Sonntag (6) - Freitag (4) = 2, dann 31-2 = 29, was bedeutet, dass der letzte Freitag dieses Monats am 29. ist. Für den ersten Freitag, wenn die Zahl negativ ist, addiere 7, wenn die Zahl 0 ist, beginnt der Monat am Freitag.

8

strtotime() Ihnen helfen können. z.B.

<?php 
$tsFirst = strtotime('2009-04-00 next friday'); 
$tsLast = strtotime('2009-05-01 last friday'); 
echo date(DATE_RFC850, $tsFirst), " | ", date(DATE_RFC850, $tsLast);
druckt
Friday, 03-Apr-09 00:00:00 CEST | Friday, 24-Apr-09 00:00:00 CEST

+0

Ich bereits überprüft, es unterstützt nicht "vorletzte" oder ähnliches, und es ist viel langsamer. – MartinodF

6

Keine Notwendigkeit für Berechnungen oder Schleifen - das ist sehr einfach, mit strtotime zu tun():

Finden Sie die den N-ten oder letzten Auftreten eines bestimmten Tag eines bestimmten Monat:

///////////////////////////////////////////////////////////////// 
// Quick Code 
///////////////////////////////////////////////////////////////// 

// Convenience mapping. 
$Names = array(0=>"Sun", 1=>"Mon", 2=>"Tue", 3=>"Wed", 4=>"Thu", 5=>"Fri", 6=>"Sat"); 

// Specify what we want 
// In this example, the Second Monday of Next March 
$tsInMonth = strtotime('March'); 
$Day = 1; 
$Ord = 2; 

// The actual calculations 
$ThisMonthTS = strtotime(date("Y-m-01", $tsInMonth)); 
$NextMonthTS = strtotime(date("Y-m-01", strtotime("next month", $tsInMonth))); 
$DateOfInterest = (-1 == $Ord) 
    ? strtotime("last ".$Names[$Day], $NextMonthTS) 
    : strtotime($Names[$Day]." + ".($Ord-1)." weeks", $ThisMonthTS); 


///////////////////////////////////////////////////////////////// 
// Explanation 
///////////////////////////////////////////////////////////////// 

// Specify the month of which we are interested. 
// You can use any timestamp inside that month, I'm using strtotime for convenience. 
$tsInMonth = strtotime('March'); 

// The day of interest, ie: Friday. 
// It can be 0=Sunday through 6=Saturday (Like 'w' from date()). 
$Day = 5; 

// The occurrence of this day in which we are interested. 
// It can be 1, 2, 3, 4 for the first, second, third, and fourth occurrence of the day in question in the month in question. 
// You can also use -1 to fine the LAST occurrence. That will return the fifth occurrence if there is one, else the 4th. 
$Ord = 3; 

//////////////////////////////////////////////////////////////// 
// We now have all the specific values we need. 
// The example values above specify the 3rd friday of next march 
//////////////////////////////////////////////////////////////// 

// We need the day name that corresponds with our day number to pass to strtotime(). 
// This isn't really necessary = we could just specify the string in the first place, but for date calcs, you are more likely to have the day number than the string itself, so this is convenient. 
$Names = array(0=>"Sun", 1=>"Mon", 2=>"Tue", 3=>"Wed", 4=>"Thu", 5=>"Fri", 6=>"Sat"); 

// Calculate the timestamp at midnight of the first of the month in question. 
// Remember $tsInMonth is any date in that month. 
$ThisMonthTS = strtotime(date("Y-m-01", $tsInMonth)); 

// Calculate the timestamp at midnight of the first of the FOLLOWING month. 
// This will be used if we specify -1 for last occurrence. 
$NextMonthTS = strtotime(date("Y-m-01", strtotime("next month", $tsInMonth))); 

// Now we just format the values a bit and pass them to strtotime(). 
// To find the 1,2,3,4th occurrence, we work from the first of the month forward. 
// For the last (-1) occurence,work we work back from the first occurrence of the following month. 
$DateOfInterest = (-1 == $Ord) ? 
    strtotime("last ".$Names[$Day], $NextMonthTS) : // The last occurrence of the day in this month. Calculated as "last dayname" from the first of next month, which will be the last one in this month. 
    strtotime($Names[$Day]." + ".($Ord-1)." weeks", $ThisMonthTS); // From the first of this month, move to "next dayname" which will be the first occurrence, and then move ahead a week for as many additional occurrences as you need. 
+0

Vielen Dank – beardedlinuxgeek

+0

@beardedlinuxgeek - Mein Vergnügen. – Eli

1
function get_date($month, $year, $week, $day) { 
    # $month, $year: current month to search in 
    # $week: 0=1st, 1=2nd, 2=3rd, 3=4th, -1=last 
    # $day: 0=mon, 1=tue, ..., 6=sun 

    $startday=1; $delta=0; 
    if ($week < 0) { 
     $startday = date('t', mktime(0, 0, 0, $month, 1, $year)); # 28..31 
     $delta=1; 
    } 
    $start = mktime(0, 0, 0, $month, $startday, $year); 
    $dstart = date('w', $start)-1; # last of the month falls on 0=mon,6=sun 
    $offset=$day-$dstart; if ($offset<$delta){$offset+=7;} 
    $newday=$startday+$offset+($week*7); 
    return mktime(0, 0, 0, $month, $newday, $year); 
} 

Dies funktioniert für mich, und auf der Grundlage der sprachunabhängig Version :-) Nur zu schade, ich das Delta-Sache zu tun benötigt (denn wenn der letzte Tag der Monat ist der gewünschte Wochentag, wir müssen nicht subtrahieren 7)

5

PHP eingebaute Zeitfunktionen machen dies einfach.

http://php.net/manual/en/function.strtotime.php

// Get first Friday of next month. 
$timestamp = strtotime('first fri of next month'); 

// Get second to last Friday of the current month. 
$timestamp = strtotime('last fri of this month -7 days'); 

// Format a timestamp as a human-meaningful string. 
$formattedDate = date('F j, Y', strtotime('first wed of last month')); 

Beachten Sie, dass wir immer sicherstellen möchten, dass wir die richtige Zeitzone für die Verwendung mit strtotime so definiert haben, dass PHP ein Verständnis hat, wo die relativen den Zeitstempel zu berechnen, in welche Zeitzone die Maschine denkt, es ist in.

date_default_timezone_set('America/New_York'); 
$formattedDate = date('F j, Y', strtotime('first wed of last month +1 week')); 
4
echo date('Y-m-d',strtotime('last friday')); 
0

das gleiche die DateTime-Klasse sehr elegant erreicht werden kann.

$time_zone = new DateTimeZone('Europe/Ljubljana'); 

$first_friday_of_this_month = new DateTime('first Friday of this month', $time_zone); 
$last_friday_of_this_month = new DateTime('last Friday of this month', $time_zone); 

echo $first_friday_of_this_month->format('Y-m-d'); # 2015-11-06 
echo $last_friday_of_this_month->format('Y-m-d'); # 2015-11-27 
0

Dies scheint jedes Mal perfekt zu funktionieren; Es dauert ein beliebiges Datum und gibt das Datum des letzten Freitags des Monats zurück, auch im Falle von 5 Freitag im Monat.

function get_last_friday_of_month($inDate) { 
    $inDate = date('Y-m-24', strtotime($inDate)); 
    $last_friday = date('Y-m-d',strtotime($inDate.' next friday')); 
    $next_friday = date('Y-m-d',strtotime($inDate.' next friday')); 

    if(date('m', strtotime($last_friday)) === date('m', strtotime($next_friday))){ 
     $last_friday = $next_friday; 
    }else{ 
     // 
    } 
    return $last_friday; 
} 
0

Unten ist die schnellste Lösung und Sie können unter allen Bedingungen verwenden. Sie können auch eine Reihe von ganzen Tag der Woche bekommen, wenn Sie es ein wenig zwicken.

function findDate($date, $week, $weekday){ 
    # $date is the date we are using to get the month and year which should be a datetime object 
    # $week can be: 0 for first, 1 for second, 2 for third, 3 for fourth and -1 for last 
    # $weekday can be: 1 for Monday, 2 for Tuesday, 3 for Wednesday, 4 for Thursday, 5 for Friday, 6 for Saturday and 7 for Sunday 

    $start = clone $date; 
    $finish = clone $date; 

    $start->modify('first day of this month'); 
    $finish->modify('last day of this month'); 
    $finish->modify('+1 day'); 

    $interval = DateInterval::createFromDateString('1 day'); 
    $period = new DatePeriod($start, $interval, $finish); 

    foreach($period AS $date){ 
     $result[$date->format('N')][] = $date; 
    } 

    if($week == -1) 
     return end($result[$weekday]); 
    else 
     return $result[$weekday][$week]; 
} 


$date = DateTime::createFromFormat('d/m/Y', '25/12/2016'); 

# find the third Wednesday in December 2016 
$result = findDate($date, 2, 3); 
echo $result->format('d/m/Y'); 

Ich hoffe, das hilft.

Lassen Sie mich wissen, wenn Sie weitere Informationen benötigen.