日付が特定の範囲内にあるかどうかを確認するにはどうすればよいですか?


86

あなたが持っている場合$start_date$end_date、ユーザによって指定された日付がその範囲内であれば、どのように確認できますか?

例えば

$start_date = '2009-06-17';

$end_date = '2009-09-05';

$date_from_user = '2009-08-28'; 

現時点では、日付は文字列ですが、タイムスタンプ整数に変換するのに役立ちますか?


それは助けになるでしょう、そしてあなたはそこにあるどんな日付操作機能にもアクセスできるでしょう。
ChrisF

3
Unixタイムスタンプは1970年1月1日(1970-01-01)のエポックで始まるため、タイムスタンプの制限に注意してください。1970
。– Shadi Almosri 2009年

1
@Shadiあなたは負の数のようなものがあることを知っていますよね?
ジェレミーローガン

@fiXedd同じ基本的な問題が存在するが-でも、負のタイムスタンプは、32ビットのタイムスタンプが1902より前の日付を表すことができない可能
フランク・ファーマーを

回答:


122

タイムスタンプにそれらを変換すると、使用して、無事に移動するための方法であるのstrtotimeを、例えば

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

よく働く。ありがとう。
GeneCode

47

PHP 5.3以降を使用している場合は、DateTimeクラスを使用してください。使いやすく、機能性に優れています。

DateTimeは内部的にタイムゾーンをサポートしていますが、他のソリューションはそれを処理するのはあなた次第です。

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

これを3つのパラメーターを受け取る関数に変換し、ブール値を返す可能性があります。テストは非常に簡単なはずですか?
oldwizard 2015

関数がtrueを返す必要2012-02-01があるのは、の間2012-02-01 ... 2014-04-30 23:59:59です。
サルマンA

2
私はDateTime、PHPがすぐに提供する大ざっぱな時間関数よりも常に好んで使用しています。このチェックに開始日と終了日を含めるには、戻り値をreturn $date >= $startDate && $date <= $endDate;
zanderwar 2016

@zanderwayは、デフォルトで秒の比較ではなく「日」の比較になっていると言っていますか?$ startDateには秒が指定されているので、 "> ="が本当に必要かどうか疑問に思いますか?
PJBrunet19年

46

文字列は「YYYY-MM-DD」正規形式の日付として検証されるため、比較を行うためにタイムスタンプに変換する必要はありません。

このテストは機能します:

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

与えられた:

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

注:このように文字列を比較すると、(12月32日)「2009-13-32」などの「無効な」日付と、文字列の比較が同等ではないような奇妙な形式の文字列「2009/3/3」が可能になります。日付またはタイムスタンプの比較。これは、文字列の日付値がCONSISTENTおよびCANONICAL形式である場合にのみ機能します。

ここにメモを追加するために編集し、明白なことを詳しく説明します。

CONSISTENT月はいつも日が必ず2つの文字にする必要があり、2つの文字である必要があり、区切り文字は常にダッシュでなければなりません、私は、文字列が同一形式である必要があり、比較されていることを例えば意味します。4文字の年、2文字の月、2文字の日ではない「文字列」を確実に比較することはできません。たとえば、文字列に1文字と2文字の月が混在している場合、と比較すると予期しない結果が得'2009-9-30'られ'2009-10-11'ます。人間的には「9」は「10」よりも小さいと見なされますが、文字列の比較では「'2009-9'よりも大きい」と見なされます'2009-1'。必ずしもダッシュ区切り文字は必要ありません。文字列を同じように確実に比較できます'YYYYMMDD'フォーマット; 区切り文字がある場合は、常にそこにあり、常に同じである必要があります。

CANONICAL、私は日付順にソートされます文字列になりますその形式を意味します。つまり、文字列には、最初に「年」、次に「月」、次に「日」の表現が含まれます。'MM-DD-YYYY'正規ではないため、フォーマット内の文字列を確実に比較することはできません。文字列の比較は左から右に機能するため、文字列の比較では、比較するMM前の(月)YYYY(年)を比較します。)「YYYY-MM-DD」文字列形式の大きな利点は、正規であるということです。この形式で表される日付は、文字列として確実に比較できます。

[補遺]

PHPタイムスタンプ変換を行う場合は、制限に注意してください。

一部のプラットフォームでは、phpは1970-01-01より前および/または2038-01-19より後のタイムスタンプ値をサポートしていません。(これがUNIXタイムスタンプの32ビット整数の性質です。)それ以降のバージョンのpf php(5.3?)は、これに対処することになっています。

文字列からタイムスタンプへ、およびタイムスタンプから文字列への変換時に同じタイムゾーンを使用するように注意しないと、タイムゾーンも問題になる可能性があります。

HTH


1
これは面白いです。
Ionuț G. Stan

1
キャストしないと、$ date_from_user、$ start_date、または$ end_dateの値が日付でない場合に問題が発生する可能性があります。つまり、$ end_date = 'Balh Blah' ..は間違いなく正しく機能しません
Mike Dinescu

@ spencer7593、この動作に関する参考資料はありますか?
Ionuț G. Stan

2
checkdate()を使用して検証できます
meleyal 2009年

1
@Sergio:はい、文字列が標準の正規形式である限り、同じ文字列比較が時間値に対して機能します(つまり、24時間制、真夜中は「00:00:00」として表され、真夜中の最後の1秒は「 23時59'分59秒文字列の比較は、 『仕事』でしょう、あなたは時間値の文字列表現を保証形式であることを保証する必要があることが保証されるように。。
spencer7593

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

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

これには、開始日または終了日と完全に一致するものは含まれません
TheTXI 2009年

OPは包括的一致を要求しませんでした。
ジェレミーローガン

3

両方の日付をタイムスタンプに変換してから、

擬似コード:

if date_from_user > start_date && date_from_user < end_date
    return true

範囲にstart_dateとend_dateも含めるように編集することをお勧めします。現在、date_from_userがどちらかに等しい場合、カウントされません。
TheTXI 2009年

OPは包括的または排他的な範囲を指定しなかったので、使用する戦略を選択するのは彼らに任せます
Glen

3

指定した形式では、ユーザーが有効な日付を提供するのに十分賢い場合、最初に日付に変換する必要はなく、文字列として比較できます。


1
コードのこの時点で、日付はすでに検証されています
meleyal 2009年

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

それらを日付またはタイムスタンプの整数に変換してから、$ date_from_userが<= $ end_dateおよび> = $ start_dateであることを確認します。


3
「日付に変換する」を明確にできますか?どうしますか?PHPには日付型がないと思いましたか?
meleyal 2009年

2

あなたはこれを試すことができます:

//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
バージョンノート:iterator_to_array()PHP 5.1以降で利用可能
Raptor

0

私はこの方法が最も簡単だと思いました:

$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

  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.