Jeśli masz $start_date
i $end_date
, jak możesz sprawdzić, czy data podana przez użytkownika mieści się w tym zakresie?
na przykład
$start_date = '2009-06-17';
$end_date = '2009-09-05';
$date_from_user = '2009-08-28';
Czy w tej chwili daty są łańcuchami, czy warto byłoby je przekonwertować na liczby całkowite ze znacznikiem czasu?
php
date
date-range
meleyal
źródło
źródło
Odpowiedzi:
Konwersja ich na znaczniki czasu jest dobrym sposobem, używając strtotime , np
$start_date = '2009-06-17'; $end_date = '2009-09-05'; $date_from_user = '2009-08-28'; check_in_range($start_date, $end_date, $date_from_user); function check_in_range($start_date, $end_date, $date_from_user) { // Convert to timestamp $start_ts = strtotime($start_date); $end_ts = strtotime($end_date); $user_ts = strtotime($date_from_user); // Check that user date is between start & end return (($user_ts >= $start_ts) && ($user_ts <= $end_ts)); }
źródło
Użyj klasy DateTime, jeśli masz PHP 5.3+. Łatwiejszy w użyciu, lepsza funkcjonalność.
DateTime wewnętrznie obsługuje strefy czasowe, a inne rozwiązania należy do Ciebie.
<?php /** * @param DateTime $date Date that is to be checked if it falls between $startDate and $endDate * @param DateTime $startDate Date should be after this date to return true * @param DateTime $endDate Date should be before this date to return true * return bool */ function isDateBetweenDates(DateTime $date, DateTime $startDate, DateTime $endDate) { return $date > $startDate && $date < $endDate; } $fromUser = new DateTime("2012-03-01"); $startDate = new DateTime("2012-02-01 00:00:00"); $endDate = new DateTime("2012-04-30 23:59:59"); echo isDateBetweenDates($fromUser, $startDate, $endDate);
źródło
2012-02-01
is between2012-02-01 ... 2014-04-30 23:59:59
.DateTime
od pobieżnych funkcji czasu, które PHP oferuje zaraz po wyjęciu z pudełka. Aby uwzględnić datę rozpoczęcia i zakończenia w tym czeku, po prostu zmień wartość zwracaną nareturn $date >= $startDate && $date <= $endDate;
Konwersja do znacznika czasu w celu porównania nie jest konieczna, biorąc pod uwagę, że ciągi są sprawdzane jako daty w formacie kanonicznym „RRRR-MM-DD”.
Ten test zadziała:
dany:
$start_date = '2009-06-17'; $end_date = '2009-09-05'; $date_from_user = '2009-08-28';
UWAGA: Porównywanie ciągów w ten sposób pozwala na „niepoprawne” daty, np. (32 grudnia) „2009-13-32” i na dziwnie sformatowane ciągi „2009/3/3”, tak że porównanie ciągów NIE będzie równoważne porównanie daty lub znacznika czasu. Działa to TYLKO wtedy, gdy wartości dat w łańcuchach są w formacie CONSISTENT i CANONICAL .
EDYTUJ, aby dodać tutaj notatkę, omawiając oczywiste.
Przez CONSISTENT rozumiem na przykład, że porównywane ciągi muszą mieć identyczny format: miesiąc musi zawsze składać się z dwóch znaków, dzień musi mieć zawsze dwa znaki, a znak separatora zawsze musi być myślnikiem. Nie możemy wiarygodnie porównywać „łańcuchów”, które nie są czteroznakowe rok, dwa znaki w miesiącu, dwa znaki na dzień. Gdybyśmy mieli na przykład kombinację jednego znaku i dwóch znaków miesięcy w łańcuchach, otrzymalibyśmy nieoczekiwany wynik podczas porównania
'2009-9-30'
z'2009-10-11'
. Po ludzku postrzegamy liczbę „9” jako mniejszą niż „10”, ale porównanie ciągów będzie'2009-9'
większe niż'2009-1'
. Nie musimy koniecznie mieć znaków rozdzielających myślniki; moglibyśmy równie rzetelnie porównać ciągi znaków w'YYYYMMDD'
format; jeśli istnieje znak separatora, musi on zawsze tam być i zawsze być taki sam.Przez CANONICAL rozumiem format, który będzie skutkował ciągami znaków, które będą sortowane według dat. Oznacza to, że ciąg będzie zawierał najpierw „rok”, potem „miesiąc”, a następnie „dzień”. Nie możemy wiarygodnie porównywać ciągów w
'MM-DD-YYYY'
formacie, ponieważ nie jest to kanoniczne. Porównanie ciągów pozwoliłoby porównaćMM
(miesiąc) przed porównaniemYYYY
(rok), ponieważ porównanie ciągów działa od lewej do prawej). Dużą zaletą formatu ciągu „RRRR-MM-DD” jest to, że jest on kanoniczny; daty przedstawione w tym formacie można wiarygodnie porównać jako ciągi.[UZUPEŁNIENIE]
Jeśli zdecydujesz się na konwersję sygnatury czasowej php, pamiętaj o ograniczeniach.
Na niektórych platformach php nie obsługuje wartości znaczników czasu wcześniejszych niż 1970-01-01 i / lub późniejszych niż 2038-01-19. (Taka jest natura 32-bitowej liczby całkowitej uniksowego znacznika czasu.) Późniejsze wersje pf php (5.3?) Mają to rozwiązać.
Strefa czasowa może również stanowić problem, jeśli nie będziesz ostrożnie używać tej samej strefy czasowej podczas konwersji z ciągu znaków na znacznik czasu iz powrotem ze znacznika czasu na ciąg.
HTH
źródło
$startDatedt = strtotime($start_date) $endDatedt = strtotime($end_date) $usrDatedt = strtotime($date_from_user) if( $usrDatedt >= $startDatedt && $usrDatedt <= $endDatedt) { //..falls within range }
źródło
Następnie przekonwertuj obie daty na znaczniki czasu
pseudo kod:
if date_from_user > start_date && date_from_user < end_date return true
źródło
W podanym formacie, zakładając, że użytkownik jest wystarczająco inteligentny, aby podać prawidłowe daty, nie musisz najpierw konwertować na datę, możesz je porównać jako ciągi.
źródło
$start_date="17/02/2012"; $end_date="21/02/2012"; $date_from_user="19/02/2012"; function geraTimestamp($data) { $partes = explode('/', $data); return mktime(0, 0, 0, $partes[1], $partes[0], $partes[2]); } $startDatedt = geraTimestamp($start_date); $endDatedt = geraTimestamp($end_date); $usrDatedt = geraTimestamp($date_from_user); if (($usrDatedt >= $startDatedt) && ($usrDatedt <= $endDatedt)) { echo "Dentro"; } else { echo "Fora"; }
źródło
Zamień je na daty lub liczby całkowite znacznika czasu, a następnie sprawdź, czy $ date_from_user to <= $ end_date i> = $ start_date
źródło
Możesz spróbować tego:
//custom date for example $d1 = new DateTime("2012-07-08"); $d2 = new DateTime("2012-07-11"); $d3 = new DateTime("2012-07-08"); $d4 = new DateTime("2012-07-15"); //create a date period object $interval = new DateInterval('P1D'); $daterange = iterator_to_array(new DatePeriod($d1, $interval, $d2)); $daterange1 = iterator_to_array(new DatePeriod($d3, $interval, $d4)); array_map(function($v) use ($daterange1) { if(in_array($v, $daterange1)) print "Bingo!";}, $daterange);
źródło
iterator_to_array()
jest dostępna od PHP 5.1Ta metoda jest dla mnie najłatwiejsza:
$start_date = '2009-06-17'; $end_date = '2009-09-05'; $date_from_user = '2009-08-28'; $start_date = date_create($start_date); $date_from_user = date_create($date_from_user); $end_date = date_create($end_date); $interval1 = date_diff($start_date, $date_from_user); $interval2 = date_diff($end_date, $date_from_user); if($interval1->invert == 0){ if($interval2->invert == 1){ // if it lies between start date and end date execute this code } }
źródło