Bir tarihin belirli bir aralıkta olup olmadığı nasıl kontrol edilir?


86

Eğer bir varsa $start_dateve $end_datekullanıcı tarafından verilen bir tarih bu aralık içinde yer alıp almadığının, nasıl kontrol edebilirim?

Örneğin

$start_date = '2009-06-17';

$end_date = '2009-09-05';

$date_from_user = '2009-08-28'; 

Şu anda tarihler dizge, onları zaman damgası tamsayılarına dönüştürmek yardımcı olur mu?


Yardımcı olabilirdi, o zaman var olan herhangi bir tarih işleme işlevine erişebilirsin.
ChrisF

3
Unix zaman damgaları 1 Ocak 1970 (1970-01-01) döneminde başladığından, zaman damgası sınırlamasıyla
başladım

1
@Shadi NEGATİF sayılar diye bir şey olduğunu biliyorsun, değil mi?
Jeremy Logan

@fiXedd aynı temel sorun olsa da - negatif zaman damgalarına izin verilse bile, 32 bit zaman damgaları 1902'den önceki tarihleri ​​temsil edemez.
Frank Farmer

Yanıtlar:


123

Bunları zaman damgalarına dönüştürmek, strtotime kullanarak iyi gitmenin yoludur , ör.

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

1
Harika çalışıyor. Teşekkürler.
GeneCode

48

PHP 5.3+ kullanıyorsanız DateTime sınıfını kullanın. Kullanımı daha kolay, daha iyi işlevsellik.

DateTime, saat dilimlerini dahili olarak destekler, diğer çözümlerle bunu halletmek size kalmıştır.

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

Muhtemelen bunu üç parametre alan bir işleve dönüştürür ve bir boole döndürürsünüz. Test etmesi çok kolay olmalı mı?
oldwizard

2012-02-01Arasında olduğu için işlevin true döndürmesi gerektiğini söyleyebilirim 2012-02-01 ... 2014-04-30 23:59:59.
Salman A

2
Ben her zaman DateTimePHP'nin kullanıma hazır sunduğu kabataslak zaman işlevlerini tercih ederim . Bu çeke başlangıç ​​ve bitiş tarihini dahil etmek için, dönüş değerini basitçereturn $date >= $startDate && $date <= $endDate;
zanderwar

@zanderway> varsayılanın saniye karşılaştırması değil, "gün" karşılaştırması olduğunu mu söylüyorsunuz? $ startDate saniye belirtildi, bu yüzden "> =" gerçekten gerekli mi acaba?
PJ Brunet

46

Dizelerin 'YYYY-AA-GG' kurallı biçiminde tarihler olarak doğrulandığı göz önüne alındığında, karşılaştırmayı yapmak için zaman damgasına dönüştürmeye gerek yoktur.

Bu test çalışacak:

( ( $date_from_user >= $start_date ) && ( $date_from_user <= $end_date ) )

verilen:

$start_date     = '2009-06-17';
$end_date       = '2009-09-05';
$date_from_user = '2009-08-28';

NOT: Bunun gibi dizeleri karşılaştırmak, "geçersiz" tarihlere izin verir, örneğin (32 Aralık) "2009-13-32" ve garip biçimlendirilmiş dizeler için "2009/3/3", bir dize karşılaştırması ile eşdeğer OLMAYACAKTIR tarih veya zaman damgası karşılaştırması. Bu, YALNIZCA dizelerdeki tarih değerleri TUTARLI ve KANONİK formattaysa çalışır.

Bariz olanı detaylandırarak buraya bir not eklemek için DÜZENLE .

By TUTARLI ay hep gün her zaman iki karakter olmalıdır, iki karakter olmalı ve ayırıcı karakteri her zaman bir çizgi olmalıdır: Ben dizenin aynı biçimde olmalıdır kıyaslanan o örneğin demek. Dört karakter yılı, iki karakter ayı, iki karakter günü olmayan "dizgileri" güvenilir bir şekilde karşılaştıramıyoruz. Örneğin dizelerde bir karakter ve iki karakter aylarının karışımı olsaydı, '2009-9-30'ile karşılaştırdığımızda beklenmedik bir sonuç alırdık '2009-10-11'. Biz insanca "9" u "10" '2009-9'dan küçük görüyoruz, ancak bir dize karşılaştırması daha büyük olarak görecektir '2009-1'. Tire ayırıcı karakterlere sahip olmamıza gerek yok; dizeleri de güvenilir bir şekilde karşılaştırabilirdik'YYYYMMDD'biçim; bir ayırıcı karakter varsa, her zaman orada olmalı ve her zaman aynı olmalıdır.

By kanonik , ben tarih sırayla sıralanacaktır dizeleri neden olacağını bir format demek. Yani, dizge önce "yıl", ardından "ay", ardından "gün" temsiline sahip olacaktır. Dizgeleri 'MM-DD-YYYY'formatta güvenilir bir şekilde karşılaştıramayız çünkü bu kurallara uygun değildir. Dize karşılaştırması soldan sağa çalıştığından, dizge karşılaştırması karşılaştırmadan önceki MM(ayı) YYYY(yıl) karşılaştırır.) 'YYYY-AA-GG' dizge biçiminin büyük bir yararı, standart olmasıdır; bu formatta gösterilen tarihler, dizeler olarak güvenilir bir şekilde karşılaştırılabilir.

[EKLE]

Php zaman damgası dönüşümü için giderseniz, sınırlamaların farkında olun.

Bazı platformlarda php, 1970-01-01'den önceki ve / veya 2038-01-19'dan sonraki zaman damgası değerlerini desteklemez. (Unix zaman damgası 32-bit tamsayısının doğası budur.) Daha sonraki sürümler pf php (5.3?) 'Ün bunu ele alması beklenir.

Dizeden zaman damgasına ve zaman damgasından dizeye dönüştürme yaparken aynı saat dilimini kullanmaya dikkat etmezseniz saat dilimi de bir sorun olabilir.

HTH


1
Ancak, yayın yapmadan $ date_from_user veya $ start_date veya $ end_date değerleri tarih değilse sorunlarla karşılaşabilirsiniz .. yani $ end_date = 'Balh Blah' .. kesinlikle doğru çalışmayacaktır
Mike Dinescu

@ spencer7593, bu davranış için bazı referanslarınız var mı?
Ionuț G. Stan

2
Onaylamak için checkdate () kullanabilirsiniz
meleyal

Bu zamanla çalışıyor mu? Demek istediğim, HH: MM: SS formatında iki kez var ve bu ikisi arasında herhangi bir süre olup olmadığını bilmek istiyorum.
Andy Ibanez

1
@Sergio: evet, aynı dize karşılaştırması, dizeler standart bir kanonik biçimde olduğu sürece zaman değerleri için çalışır (ör. 24 saatlik saat, gece yarısı "00: 00: 00" olarak gösterilir, gece yarısından önceki son saniye " 23:59:59 '. Dize karşılaştırmasının "çalışacağından" emin olmak için, zaman değerinin dize gösterimlerinin garantili bir biçimde olmasını garanti etmeniz gerekir.
spencer7593

4
$startDatedt = strtotime($start_date)
$endDatedt = strtotime($end_date)
$usrDatedt = strtotime($date_from_user)

if( $usrDatedt >= $startDatedt && $usrDatedt <= $endDatedt)
{
   //..falls within range
}

Bu, başlangıç ​​tarihi veya bitiş tarihiyle tam eşleşmeleri içermeyecektir
TheTXI

OP kapsamlı maçlar istemedi.
Jeremy Logan

3

Her iki tarihi de zaman damgalarına dönüştürün, sonra yapın

sözde kod:

if date_from_user > start_date && date_from_user < end_date
    return true

Aralıkta başlangıç_tarihi ve bitiş_tarihini de içerecek şekilde düzenlemek isteyebilirsiniz. Şu anda, eğer date_from_user'a eşitse, sayılmayacaktır.
TheTXI

OP kapsayıcı veya özel aralıklar belirtmedi, bu yüzden hangi stratejinin kullanılacağını seçmek için işi onlara bırakacağım
Glen

3

Sağladığınız biçimde, kullanıcının size geçerli tarihler verecek kadar akıllı olduğunu varsayarsak, önce bir tarihe dönüştürmenize gerek yoktur, bunları dizeler olarak karşılaştırabilirsiniz.


1

3
$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";
}

2

Bunları tarihlere veya zaman damgası tam sayılarına dönüştürün ve ardından $ date_from_user <= $ end_date ve> = $ başlangıç_tarihi olup olmadığını kontrol edin


3
'Onları tarihe çevirme' konusunu açıklayabilir misiniz? Bunu nasıl yaptın? PHP'nin tarih türü olmadığını sanıyordum?
meleyal

2

Bunu deneyebilirsiniz:

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

1
sürüm notu: iterator_to_array()PHP 5.1'den beri mevcuttur
Raptor

0

Bu yöntemi en kolay buldum:

$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

  }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.