ฉันมีสองวันของแบบฟอร์ม:
Start Date: 2007-03-24
End Date: 2009-06-26
ตอนนี้ฉันต้องการค้นหาความแตกต่างระหว่างสองสิ่งนี้ในรูปแบบต่อไปนี้:
2 years, 3 months and 2 days
ฉันจะทำสิ่งนี้ใน PHP ได้อย่างไร
ฉันมีสองวันของแบบฟอร์ม:
Start Date: 2007-03-24
End Date: 2009-06-26
ตอนนี้ฉันต้องการค้นหาความแตกต่างระหว่างสองสิ่งนี้ในรูปแบบต่อไปนี้:
2 years, 3 months and 2 days
ฉันจะทำสิ่งนี้ใน PHP ได้อย่างไร
คำตอบ:
ใช้สิ่งนี้สำหรับรหัสดั้งเดิม (PHP <5.3) สำหรับวิธีการแก้ปัญหาล่าสุดดูคำตอบของ jurka ด้านล่าง
คุณสามารถใช้ strtotime () เพื่อแปลงวันที่สองวันเป็นเวลา unix จากนั้นคำนวณจำนวนวินาทีระหว่างพวกเขา จากนี้การคำนวณระยะเวลาต่างๆค่อนข้างง่าย
$date1 = "2007-03-24";
$date2 = "2009-06-26";
$diff = abs(strtotime($date2) - strtotime($date1));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
printf("%d years, %d months, %d days\n", $years, $months, $days);
แก้ไข:เห็นได้ชัดว่าวิธีที่ต้องการในการทำเช่นนี้อธิบายโดย jurka ด้านล่าง โดยทั่วไปฉันจะแนะนำให้ใช้รหัสของฉันหากคุณไม่มี PHP 5.3 ขึ้นไป
หลายคนในความคิดเห็นได้ชี้ให้เห็นว่ารหัสข้างต้นเป็นเพียงการประมาณ ฉันยังเชื่อว่าเพื่อจุดประสงค์ส่วนใหญ่ก็ดีเนื่องจากการใช้ช่วงนั้นให้ความรู้สึกว่าเวลาผ่านไปหรือยังคงมากกว่าที่จะให้ความแม่นยำ - หากคุณต้องการทำเช่นนั้นเพียงแค่ส่งออกวันที่
ฉันตัดสินใจที่จะจัดการกับข้อร้องเรียน หากคุณต้องการช่วงที่แน่นอน แต่ไม่สามารถเข้าถึง PHP 5.3 ได้ให้ใช้รหัสด้านล่าง (ควรใช้กับ PHP 4 ด้วย) นี่เป็นพอร์ตโดยตรงของรหัสที่ PHP ใช้ภายในเพื่อคำนวณช่วงด้วยข้อยกเว้นว่าจะไม่คำนึงถึงการประหยัดเวลากลางวัน ซึ่งหมายความว่าจะปิดประมาณหนึ่งชั่วโมงโดยส่วนใหญ่ แต่ยกเว้นว่าควรจะถูกต้อง
<?php
/**
* Calculate differences between two dates with precise semantics. Based on PHPs DateTime::diff()
* implementation by Derick Rethans. Ported to PHP by Emil H, 2011-05-02. No rights reserved.
*
* See here for original code:
* http://svn.php.net/viewvc/php/php-src/trunk/ext/date/lib/tm2unixtime.c?revision=302890&view=markup
* http://svn.php.net/viewvc/php/php-src/trunk/ext/date/lib/interval.c?revision=298973&view=markup
*/
function _date_range_limit($start, $end, $adj, $a, $b, $result)
{
if ($result[$a] < $start) {
$result[$b] -= intval(($start - $result[$a] - 1) / $adj) + 1;
$result[$a] += $adj * intval(($start - $result[$a] - 1) / $adj + 1);
}
if ($result[$a] >= $end) {
$result[$b] += intval($result[$a] / $adj);
$result[$a] -= $adj * intval($result[$a] / $adj);
}
return $result;
}
function _date_range_limit_days($base, $result)
{
$days_in_month_leap = array(31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
$days_in_month = array(31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
_date_range_limit(1, 13, 12, "m", "y", &$base);
$year = $base["y"];
$month = $base["m"];
if (!$result["invert"]) {
while ($result["d"] < 0) {
$month--;
if ($month < 1) {
$month += 12;
$year--;
}
$leapyear = $year % 400 == 0 || ($year % 100 != 0 && $year % 4 == 0);
$days = $leapyear ? $days_in_month_leap[$month] : $days_in_month[$month];
$result["d"] += $days;
$result["m"]--;
}
} else {
while ($result["d"] < 0) {
$leapyear = $year % 400 == 0 || ($year % 100 != 0 && $year % 4 == 0);
$days = $leapyear ? $days_in_month_leap[$month] : $days_in_month[$month];
$result["d"] += $days;
$result["m"]--;
$month++;
if ($month > 12) {
$month -= 12;
$year++;
}
}
}
return $result;
}
function _date_normalize($base, $result)
{
$result = _date_range_limit(0, 60, 60, "s", "i", $result);
$result = _date_range_limit(0, 60, 60, "i", "h", $result);
$result = _date_range_limit(0, 24, 24, "h", "d", $result);
$result = _date_range_limit(0, 12, 12, "m", "y", $result);
$result = _date_range_limit_days(&$base, &$result);
$result = _date_range_limit(0, 12, 12, "m", "y", $result);
return $result;
}
/**
* Accepts two unix timestamps.
*/
function _date_diff($one, $two)
{
$invert = false;
if ($one > $two) {
list($one, $two) = array($two, $one);
$invert = true;
}
$key = array("y", "m", "d", "h", "i", "s");
$a = array_combine($key, array_map("intval", explode(" ", date("Y m d H i s", $one))));
$b = array_combine($key, array_map("intval", explode(" ", date("Y m d H i s", $two))));
$result = array();
$result["y"] = $b["y"] - $a["y"];
$result["m"] = $b["m"] - $a["m"];
$result["d"] = $b["d"] - $a["d"];
$result["h"] = $b["h"] - $a["h"];
$result["i"] = $b["i"] - $a["i"];
$result["s"] = $b["s"] - $a["s"];
$result["invert"] = $invert ? 1 : 0;
$result["days"] = intval(abs(($one - $two)/86400));
if ($invert) {
_date_normalize(&$a, &$result);
} else {
_date_normalize(&$b, &$result);
}
return $result;
}
$date = "1986-11-10 19:37:22";
print_r(_date_diff(strtotime($date), time()));
print_r(_date_diff(time(), strtotime($date)));
&
ไปที่ลายเซ็น
ฉันแนะนำให้ใช้วัตถุ DateTime และ DateInterval
$date1 = new DateTime("2007-03-24");
$date2 = new DateTime("2009-06-26");
$interval = $date1->diff($date2);
echo "difference " . $interval->y . " years, " . $interval->m." months, ".$interval->d." days ";
// shows the total amount of days (not divided into years, months and days like above)
echo "difference " . $interval->days . " days ";
อ่านเพิ่มเติมphp DateTime :: diff manual
จากคู่มือ:
ในฐานะของ PHP 5.2.2 วัตถุ DateTime สามารถนำมาเปรียบเทียบโดยใช้ตัวดำเนินการเปรียบเทียบ
$date1 = new DateTime("now");
$date2 = new DateTime("tomorrow");
var_dump($date1 == $date2); // bool(false)
var_dump($date1 < $date2); // bool(true)
var_dump($date1 > $date2); // bool(false)
$date2->format('U') - $date1->format('U')
คุณอาจต้องการ
แนวทางปฏิบัติที่ดีที่สุดคือการใช้วัตถุDateTime
(และDateInterval
) ของ PHP แต่ละวันถูกห่อหุ้มในDateTime
วัตถุและจากนั้นสามารถสร้างความแตกต่างระหว่างสอง:
$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");
DateTime
วัตถุจะยอมรับรูปแบบใดstrtotime()
จะ หากต้องการรูปแบบวันที่ที่เฉพาะเจาะจงยิ่งขึ้นDateTime::createFromFormat()
สามารถใช้ในการสร้างDateTime
วัตถุได้
หลังจากวัตถุทั้งสองถูก instantiated คุณลบคุณหนึ่งจากที่อื่น ๆ DateTime::diff()
ด้วย
$difference = $first_date->diff($second_date);
$difference
ตอนนี้ถือDateInterval
วัตถุที่มีข้อมูลที่แตกต่าง A var_dump()
มีลักษณะเช่นนี้:
object(DateInterval)
public 'y' => int 0
public 'm' => int 0
public 'd' => int 20
public 'h' => int 6
public 'i' => int 56
public 's' => int 30
public 'invert' => int 0
public 'days' => int 20
ในการจัดรูปแบบDateInterval
วัตถุเราจะต้องตรวจสอบแต่ละค่าและแยกออกหากเป็น 0:
/**
* Format an interval to show all existing components.
* If the interval doesn't have a time component (years, months, etc)
* That component won't be displayed.
*
* @param DateInterval $interval The interval
*
* @return string Formatted interval string.
*/
function format_interval(DateInterval $interval) {
$result = "";
if ($interval->y) { $result .= $interval->format("%y years "); }
if ($interval->m) { $result .= $interval->format("%m months "); }
if ($interval->d) { $result .= $interval->format("%d days "); }
if ($interval->h) { $result .= $interval->format("%h hours "); }
if ($interval->i) { $result .= $interval->format("%i minutes "); }
if ($interval->s) { $result .= $interval->format("%s seconds "); }
return $result;
}
สิ่งที่เหลืออยู่ตอนนี้คือการเรียกฟังก์ชั่นของเราบน$difference
DateInterval
วัตถุ:
echo format_interval($difference);
และเราได้ผลลัพธ์ที่ถูกต้อง:
20 วัน 6 ชั่วโมง 56 นาที 30 วินาที
รหัสสมบูรณ์ที่ใช้เพื่อให้บรรลุเป้าหมาย:
/**
* Format an interval to show all existing components.
* If the interval doesn't have a time component (years, months, etc)
* That component won't be displayed.
*
* @param DateInterval $interval The interval
*
* @return string Formatted interval string.
*/
function format_interval(DateInterval $interval) {
$result = "";
if ($interval->y) { $result .= $interval->format("%y years "); }
if ($interval->m) { $result .= $interval->format("%m months "); }
if ($interval->d) { $result .= $interval->format("%d days "); }
if ($interval->h) { $result .= $interval->format("%h hours "); }
if ($interval->i) { $result .= $interval->format("%i minutes "); }
if ($interval->s) { $result .= $interval->format("%s seconds "); }
return $result;
}
$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");
$difference = $first_date->diff($second_date);
echo format_interval($difference);
DateTime()
ไม่ใช่ฟังก์ชั่นมันเป็นวัตถุและมีตั้งแต่ PHP 5.2 ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ของคุณรองรับ
ดูชั่วโมงและนาทีและวินาที ..
$date1 = "2008-11-01 22:45:00";
$date2 = "2009-12-04 13:44:01";
$diff = abs(strtotime($date2) - strtotime($date1));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
$hours = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24)/ (60*60));
$minuts = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24 - $hours*60*60)/ 60);
$seconds = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24 - $days*60*60*24 - $hours*60*60 - $minuts*60));
printf("%d years, %d months, %d days, %d hours, %d minuts\n, %d seconds\n", $years, $months, $days, $hours, $minuts, $seconds);
ลองดูที่ลิงค์ต่อไปนี้ นี่คือคำตอบที่ดีที่สุดที่ฉันเคยพบมา .. :)
function dateDiff ($d1, $d2) {
// Return the number of days between the two dates:
return round(abs(strtotime($d1) - strtotime($d2))/86400);
} // end function dateDiff
ไม่สำคัญว่าวันใดจะเร็วหรือช้ากว่าเมื่อคุณผ่านพารามิเตอร์วันที่ ฟังก์ชันใช้ค่าสัมบูรณ์ PHP ABS () เพื่อส่งคืนหมายเลข postive เป็นจำนวนวันระหว่างวันที่สองวันเสมอ
โปรดทราบว่าจำนวนวันระหว่างวันที่สองวันนั้นไม่รวมอยู่ในวันที่ทั้งสอง ดังนั้นหากคุณกำลังมองหาจำนวนวันที่แสดงโดยวันที่ทั้งหมดระหว่างและรวมถึงวันที่ที่ป้อนคุณจะต้องเพิ่มหนึ่ง (1) ลงในผลลัพธ์ของฟังก์ชันนี้
ตัวอย่างเช่นความแตกต่าง (ตามที่ส่งกลับโดยฟังก์ชันด้านบน) ระหว่าง 2013-02-09 และ 2013-02-14 คือ 5 แต่จำนวนวันหรือวันที่ที่แสดงโดยช่วงวันที่ 2013-02-09 - 2013-02- 14 คือ 6
ฉันโหวตให้คำตอบของjurkaเนื่องจากฉันชอบ แต่ฉันมีเวอร์ชั่น pre-php.5.3 ...
ฉันพบว่าตัวเองกำลังทำงานกับปัญหาที่คล้ายกัน - ซึ่งเป็นวิธีที่ฉันได้รับคำถามนี้ในตอนแรก - แต่เพียงต้องการความแตกต่างในชั่วโมง แต่ฟังก์ชั่นของฉันก็แก้ปัญหาอันนี้ได้ดีเช่นกันและฉันไม่มีที่ใดก็ได้ในห้องสมุดของฉันเพื่อเก็บไว้ในที่ที่มันจะไม่หลงทางและลืมดังนั้น ... หวังว่ามันจะมีประโยชน์กับใครบางคน
/**
*
* @param DateTime $oDate1
* @param DateTime $oDate2
* @return array
*/
function date_diff_array(DateTime $oDate1, DateTime $oDate2) {
$aIntervals = array(
'year' => 0,
'month' => 0,
'week' => 0,
'day' => 0,
'hour' => 0,
'minute' => 0,
'second' => 0,
);
foreach($aIntervals as $sInterval => &$iInterval) {
while($oDate1 <= $oDate2){
$oDate1->modify('+1 ' . $sInterval);
if ($oDate1 > $oDate2) {
$oDate1->modify('-1 ' . $sInterval);
break;
} else {
$iInterval++;
}
}
}
return $aIntervals;
}
และการทดสอบ:
$oDate = new DateTime();
$oDate->modify('+111402189 seconds');
var_dump($oDate);
var_dump(date_diff_array(new DateTime(), $oDate));
และผลลัพธ์:
object(DateTime)[2]
public 'date' => string '2014-04-29 18:52:51' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'America/New_York' (length=16)
array
'year' => int 3
'month' => int 6
'week' => int 1
'day' => int 4
'hour' => int 9
'minute' => int 3
'second' => int 8
ฉันได้รับแนวคิดดั้งเดิมจากที่นี่ซึ่งฉันแก้ไขเพื่อการใช้งานของฉัน (และฉันหวังว่าการแก้ไขของฉันจะแสดงในหน้านั้นด้วย)
คุณสามารถลบช่วงเวลาที่คุณไม่ต้องการได้อย่างง่ายดาย (พูดว่า "สัปดาห์") โดยการลบพวกเขาออกจาก$aIntervals
อาร์เรย์หรืออาจเพิ่ม$aExclude
พารามิเตอร์หรือเพียงแค่กรองพวกเขาออกเมื่อคุณส่งออกสตริง
week
ดัชนีใน$aIntervals
(เพราะDateDiff
ไม่เคยใช้)
<?php
$today = strtotime("2011-02-03 00:00:00");
$myBirthDate = strtotime("1964-10-30 00:00:00");
printf("Days since my birthday: ", ($today - $myBirthDate)/60/60/24);
?>
ฉันไม่รู้ว่าคุณกำลังใช้เฟรมเวิร์ก PHP หรือไม่ แต่เฟรมเวิร์ก PHP จำนวนมากมีไลบรารีวันที่ / เวลาและผู้ช่วยที่จะช่วยให้คุณไม่ต้องพลิกโฉมวงล้อ
ตัวอย่างเช่น CodeIgniter มีtimespan()
ฟังก์ชั่น เพียงใส่สองเวลา Unix และมันจะสร้างผลลัพธ์โดยอัตโนมัติดังนี้
1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes
echo time_diff_string('2013-05-01 00:22:35', 'now');
echo time_diff_string('2013-05-01 00:22:35', 'now', true);
4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago
function time_diff_string($from, $to, $full = false) {
$from = new DateTime($from);
$to = new DateTime($to);
$diff = $to->diff($from);
$diff->w = floor($diff->d / 7);
$diff->d -= $diff->w * 7;
$string = array(
'y' => 'year',
'm' => 'month',
'w' => 'week',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
);
foreach ($string as $k => &$v) {
if ($diff->$k) {
$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
} else {
unset($string[$k]);
}
}
if (!$full) $string = array_slice($string, 0, 1);
return $string ? implode(', ', $string) . ' ago' : 'just now';
}
ฉันมีตรรกะง่าย ๆ สำหรับที่:
<?php
per_days_diff('2011-12-12','2011-12-29')
function per_days_diff($start_date, $end_date) {
$per_days = 0;
$noOfWeek = 0;
$noOfWeekEnd = 0;
$highSeason=array("7", "8");
$current_date = strtotime($start_date);
$current_date += (24 * 3600);
$end_date = strtotime($end_date);
$seassion = (in_array(date('m', $current_date), $highSeason))?"2":"1";
$noOfdays = array('');
while ($current_date <= $end_date) {
if ($current_date <= $end_date) {
$date = date('N', $current_date);
array_push($noOfdays,$date);
$current_date = strtotime('+1 day', $current_date);
}
}
$finalDays = array_shift($noOfdays);
//print_r($noOfdays);
$weekFirst = array("week"=>array(),"weekEnd"=>array());
for($i = 0; $i < count($noOfdays); $i++)
{
if ($noOfdays[$i] == 1)
{
//echo "This is week";
//echo "<br/>";
if($noOfdays[$i+6]==7)
{
$noOfWeek++;
$i=$i+6;
}
else
{
$per_days++;
}
//array_push($weekFirst["week"],$day);
}
else if($noOfdays[$i]==5)
{
//echo "This is weekend";
//echo "<br/>";
if($noOfdays[$i+2] ==7)
{
$noOfWeekEnd++;
$i = $i+2;
}
else
{
$per_days++;
}
//echo "After weekend value:- ".$i;
//echo "<br/>";
}
else
{
$per_days++;
}
}
/*echo $noOfWeek;
echo "<br/>";
echo $noOfWeekEnd;
echo "<br/>";
print_r($per_days);
echo "<br/>";
print_r($weekFirst);
*/
$duration = array("weeks"=>$noOfWeek, "weekends"=>$noOfWeekEnd, "perDay"=>$per_days, "seassion"=>$seassion);
return $duration;
?>
คุณสามารถใช้
getdate()
ฟังก์ชั่นซึ่งส่งกลับอาร์เรย์ที่มีองค์ประกอบทั้งหมดของวันที่ / เวลาที่ให้มา:
$diff = abs($endDate - $startDate);
$my_t=getdate($diff);
print("$my_t[year] years, $my_t[month] months and $my_t[mday] days");
หากวันที่เริ่มต้นและวันที่สิ้นสุดของคุณอยู่ในรูปแบบสตริงให้ใช้
$startDate = strtotime($startDateStr);
$endDate = strtotime($endDateStr);
ก่อนรหัสข้างต้น
$my_t["year"] -= 1970
เพื่อให้ได้จำนวนปีที่ถูกต้อง คุณต้องลบความแตกต่างชั่วโมงของคุณจาก GMT เพื่อให้ได้ชั่วโมงที่ถูกต้อง คุณต้องลบ 1 จากเดือนและวันที่เช่นกัน
// If you just want to see the year difference then use this function.
// Using the logic I've created you may also create month and day difference
// which I did not provide here so you may have the efforts to use your brain.
// :)
$date1='2009-01-01';
$date2='2010-01-01';
echo getYearDifference ($date1,$date2);
function getYearDifference($date1=strtotime($date1),$date2=strtotime($date2)){
$year = 0;
while($date2 > $date1 = strtotime('+1 year', $date1)){
++$year;
}
return $year;
}
นี่คือฟังก์ชั่นของฉัน PHP ที่ต้องการ> = 5.3.4 มันใช้คลาส DateTime เร็วมากเร็วและสามารถสร้างความแตกต่างระหว่างวันที่สองวันหรือแม้กระทั่งช่วงเวลาที่เรียกว่า "นับตั้งแต่"
if(function_exists('grk_Datetime_Since') === FALSE){
function grk_Datetime_Since($From, $To='', $Prefix='', $Suffix=' ago', $Words=array()){
# Est-ce qu'on calcul jusqu'à un moment précis ? Probablement pas, on utilise maintenant
if(empty($To) === TRUE){
$To = time();
}
# On va s'assurer que $From est numérique
if(is_int($From) === FALSE){
$From = strtotime($From);
};
# On va s'assurer que $To est numérique
if(is_int($To) === FALSE){
$To = strtotime($To);
}
# On a une erreur ?
if($From === FALSE OR $From === -1 OR $To === FALSE OR $To === -1){
return FALSE;
}
# On va créer deux objets de date
$From = new DateTime(@date('Y-m-d H:i:s', $From), new DateTimeZone('GMT'));
$To = new DateTime(@date('Y-m-d H:i:s', $To), new DateTimeZone('GMT'));
# On va calculer la différence entre $From et $To
if(($Diff = $From->diff($To)) === FALSE){
return FALSE;
}
# On va merger le tableau des noms (par défaut, anglais)
$Words = array_merge(array(
'year' => 'year',
'years' => 'years',
'month' => 'month',
'months' => 'months',
'week' => 'week',
'weeks' => 'weeks',
'day' => 'day',
'days' => 'days',
'hour' => 'hour',
'hours' => 'hours',
'minute' => 'minute',
'minutes' => 'minutes',
'second' => 'second',
'seconds' => 'seconds'
), $Words);
# On va créer la chaîne maintenant
if($Diff->y > 1){
$Text = $Diff->y.' '.$Words['years'];
} elseif($Diff->y == 1){
$Text = '1 '.$Words['year'];
} elseif($Diff->m > 1){
$Text = $Diff->m.' '.$Words['months'];
} elseif($Diff->m == 1){
$Text = '1 '.$Words['month'];
} elseif($Diff->d > 7){
$Text = ceil($Diff->d/7).' '.$Words['weeks'];
} elseif($Diff->d == 7){
$Text = '1 '.$Words['week'];
} elseif($Diff->d > 1){
$Text = $Diff->d.' '.$Words['days'];
} elseif($Diff->d == 1){
$Text = '1 '.$Words['day'];
} elseif($Diff->h > 1){
$Text = $Diff->h.' '.$Words['hours'];
} elseif($Diff->h == 1){
$Text = '1 '.$Words['hour'];
} elseif($Diff->i > 1){
$Text = $Diff->i.' '.$Words['minutes'];
} elseif($Diff->i == 1){
$Text = '1 '.$Words['minute'];
} elseif($Diff->s > 1){
$Text = $Diff->s.' '.$Words['seconds'];
} else {
$Text = '1 '.$Words['second'];
}
return $Prefix.$Text.$Suffix;
}
}
ฉันต้องการใช้date_create
และdate_diff
วัตถุ
รหัส:
$date1 = date_create("2007-03-24");
$date2 = date_create("2009-06-26");
$dateDifference = date_diff($date1, $date2)->format('%y years, %m months and %d days');
echo $dateDifference;
เอาท์พุท:
2 years, 3 months and 2 days
สำหรับข้อมูลเพิ่มเติมอ่านคู่มือPHPdate_diff
ตามคู่มือ
date_diff
คือนามแฝงของ DateTime :: diff ()
วิธีนี้จะพยายามตรวจสอบว่าได้รับการประทับเวลาหรือไม่และจะส่งคืนวันที่ / เวลาในอนาคตด้วยค่าลบ:
<?php
function time_diff($start, $end = NULL, $convert_to_timestamp = FALSE) {
// If $convert_to_timestamp is not explicitly set to TRUE,
// check to see if it was accidental:
if ($convert_to_timestamp || !is_numeric($start)) {
// If $convert_to_timestamp is TRUE, convert to timestamp:
$timestamp_start = strtotime($start);
}
else {
// Otherwise, leave it as a timestamp:
$timestamp_start = $start;
}
// Same as above, but make sure $end has actually been overridden with a non-null,
// non-empty, non-numeric value:
if (!is_null($end) && (!empty($end) && !is_numeric($end))) {
$timestamp_end = strtotime($end);
}
else {
// If $end is NULL or empty and non-numeric value, assume the end time desired
// is the current time (useful for age, etc):
$timestamp_end = time();
}
// Regardless, set the start and end times to an integer:
$start_time = (int) $timestamp_start;
$end_time = (int) $timestamp_end;
// Assign these values as the params for $then and $now:
$start_time_var = 'start_time';
$end_time_var = 'end_time';
// Use this to determine if the output is positive (time passed) or negative (future):
$pos_neg = 1;
// If the end time is at a later time than the start time, do the opposite:
if ($end_time <= $start_time) {
$start_time_var = 'end_time';
$end_time_var = 'start_time';
$pos_neg = -1;
}
// Convert everything to the proper format, and do some math:
$then = new DateTime(date('Y-m-d H:i:s', $$start_time_var));
$now = new DateTime(date('Y-m-d H:i:s', $$end_time_var));
$years_then = $then->format('Y');
$years_now = $now->format('Y');
$years = $years_now - $years_then;
$months_then = $then->format('m');
$months_now = $now->format('m');
$months = $months_now - $months_then;
$days_then = $then->format('d');
$days_now = $now->format('d');
$days = $days_now - $days_then;
$hours_then = $then->format('H');
$hours_now = $now->format('H');
$hours = $hours_now - $hours_then;
$minutes_then = $then->format('i');
$minutes_now = $now->format('i');
$minutes = $minutes_now - $minutes_then;
$seconds_then = $then->format('s');
$seconds_now = $now->format('s');
$seconds = $seconds_now - $seconds_then;
if ($seconds < 0) {
$minutes -= 1;
$seconds += 60;
}
if ($minutes < 0) {
$hours -= 1;
$minutes += 60;
}
if ($hours < 0) {
$days -= 1;
$hours += 24;
}
$months_last = $months_now - 1;
if ($months_now == 1) {
$years_now -= 1;
$months_last = 12;
}
// "Thirty days hath September, April, June, and November" ;)
if ($months_last == 9 || $months_last == 4 || $months_last == 6 || $months_last == 11) {
$days_last_month = 30;
}
else if ($months_last == 2) {
// Factor in leap years:
if (($years_now % 4) == 0) {
$days_last_month = 29;
}
else {
$days_last_month = 28;
}
}
else {
$days_last_month = 31;
}
if ($days < 0) {
$months -= 1;
$days += $days_last_month;
}
if ($months < 0) {
$years -= 1;
$months += 12;
}
// Finally, multiply each value by either 1 (in which case it will stay the same),
// or by -1 (in which case it will become negative, for future dates).
// Note: 0 * 1 == 0 * -1 == 0
$out = new stdClass;
$out->years = (int) $years * $pos_neg;
$out->months = (int) $months * $pos_neg;
$out->days = (int) $days * $pos_neg;
$out->hours = (int) $hours * $pos_neg;
$out->minutes = (int) $minutes * $pos_neg;
$out->seconds = (int) $seconds * $pos_neg;
return $out;
}
ตัวอย่างการใช้งาน:
<?php
$birthday = 'June 2, 1971';
$check_age_for_this_date = 'June 3, 1999 8:53pm';
$age = time_diff($birthday, $check_age_for_this_date)->years;
print $age;// 28
หรือ:
<?php
$christmas_2020 = 'December 25, 2020';
$countdown = time_diff($christmas_2020);
print_r($countdown);
"ถ้า" วันที่จะถูกเก็บไว้ใน MySQL ฉันคิดว่ามันง่ายกว่าที่จะทำการคำนวณความแตกต่างที่ระดับฐานข้อมูล ... จากนั้นขึ้นอยู่กับวัน, ชั่วโมง, นาที, ผลลัพธ์วินาที, แยกวิเคราะห์และแสดงผลตามความเหมาะสม ...
mysql> select firstName, convert_tz(loginDate, '+00:00', '-04:00') as loginDate, TIMESTAMPDIFF(DAY, loginDate, now()) as 'Day', TIMESTAMPDIFF(HOUR, loginDate, now())+4 as 'Hour', TIMESTAMPDIFF(MINUTE, loginDate, now())+(60*4) as 'Min', TIMESTAMPDIFF(SECOND, loginDate, now())+(60*60*4) as 'Sec' from User_ where userId != '10158' AND userId != '10198' group by emailAddress order by loginDate desc;
+-----------+---------------------+------+------+------+--------+
| firstName | loginDate | Day | Hour | Min | Sec |
+-----------+---------------------+------+------+------+--------+
| Peter | 2014-03-30 18:54:40 | 0 | 4 | 244 | 14644 |
| Keith | 2014-03-30 18:54:11 | 0 | 4 | 244 | 14673 |
| Andres | 2014-03-28 09:20:10 | 2 | 61 | 3698 | 221914 |
| Nadeem | 2014-03-26 09:33:43 | 4 | 109 | 6565 | 393901 |
+-----------+---------------------+------+------+------+--------+
4 rows in set (0.00 sec)
ฉันพบบทความของคุณในหน้าต่อไปนี้ซึ่งมีจำนวนของการอ้างอิงสำหรับการคำนวณเวลาของPHP
คำนวณความแตกต่างระหว่างสองวัน (และเวลา) โดยใช้ PHP หน้าต่อไปนี้มีช่วงของวิธีการที่แตกต่างกัน (7 ทั้งหมด) สำหรับการคำนวณวันที่ / เวลาโดยใช้ PHP เพื่อกำหนดความแตกต่างของเวลา (ชั่วโมง, munites), วัน, เดือนหรือปีระหว่างวันที่สองวัน
นอกจากนี้คุณยังสามารถใช้รหัสต่อไปนี้เพื่อส่งคืนวันที่ที่แตกต่างกันตามเศษส่วนแบบวงกลมจนถึง $ date1 = $ duedate; // กำหนดวันที่ครบกำหนด echo $ date2 = date ("Ymd"); // วันที่ปัจจุบัน $ ts1 = strtotime ($ date1); $ ts2 = strtotime ($ date2); $ seconds_diff = $ ts1 - $ ts2; echo $ dateiff = ceil ($ seconds_diff / 3600) / 24); // คืนในไม่กี่วัน
ถ้าคุณใช้วิธีการตั้งพื้นของ php แทนที่จะเป็น ceil มันจะคืนค่าเศษส่วนลง โปรดตรวจสอบความแตกต่างที่นี่บางครั้งหากเขตเวลาเซิร์ฟเวอร์การแสดงละครของคุณแตกต่างจากโซนเวลาไซต์สดในกรณีนั้นคุณอาจได้รับผลลัพธ์ที่แตกต่างกันดังนั้นเปลี่ยนเงื่อนไขตามนั้น
$date1 = date_create('2007-03-24');
$date2 = date_create('2009-06-26');
$interval = date_diff($date1, $date2);
echo "difference : " . $interval->y . " years, " . $interval->m." months, ".$interval->d." days ";
คุณสามารถใช้ฟังก์ชั่นต่อไปนี้ที่สามารถคืนอายุในปีและเดือน (เช่น 1 ปี 4 เดือน)
function getAge($dob, $age_at_date)
{
$d1 = new DateTime($dob);
$d2 = new DateTime($age_at_date);
$age = $d2->diff($d1);
$years = $age->y;
$months = $age->m;
return $years.'.'.months;
}
หรือถ้าคุณต้องการคำนวณอายุ ณ วันที่ปัจจุบันคุณสามารถใช้
function getAge($dob)
{
$d1 = new DateTime($dob);
$d2 = new DateTime(date());
$age = $d2->diff($d1);
$years = $age->y;
$months = $age->m;
return $years.'.'.months;
}
สำหรับเวอร์ชัน php> = 5.3: สร้างวัตถุวันที่สองรายการจากนั้นใช้date_diff()
ฟังก์ชัน มันจะกลับ php DateIntervalวัตถุ ดูเอกสารประกอบ
$date1=date_create("2007-03-24");
$date2=date_create("2009-06-26");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");
นี่คือรหัสที่รันได้
$date1 = date_create('2007-03-24');
$date2 = date_create('2009-06-26');
$diff1 = date_diff($date1,$date2);
$daysdiff = $diff1->format("%R%a");
$daysdiff = abs($daysdiff);
ฉันมีปัญหาเดียวกันกับ PHP 5.2 และแก้ไขด้วย MySQL อาจไม่ใช่สิ่งที่คุณกำลังมองหา แต่สิ่งนี้จะทำเคล็ดลับและคืนจำนวนวัน:
$datediff_q = $dbh->prepare("SELECT DATEDIFF(:date2, :date1)");
$datediff_q->bindValue(':date1', '2007-03-24', PDO::PARAM_STR);
$datediff_q->bindValue(':date2', '2009-06-26', PDO::PARAM_STR);
$datediff = ($datediff_q->execute()) ? $datediff_q->fetchColumn(0) : false;
ข้อมูลเพิ่มเติมที่นี่http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_datediff
เนื่องจากทุกคนกำลังโพสต์ตัวอย่างโค้ดนี่คืออีกเวอร์ชันหนึ่ง
ฉันต้องการฟังก์ชั่นที่จะแสดงความแตกต่างจากไม่กี่วินาทีถึงเป็นปี (แค่หน่วยเดียว) สำหรับช่วงเวลามากกว่า 1 วันฉันต้องการให้โรลโอเวอร์ตอนเที่ยงคืน (10:00 ในวันจันทร์ที่เห็นจาก 9:00 พุธคือ 2 วันที่ผ่านมาไม่ใช่ 1) และสำหรับรอบระยะเวลาหนึ่งเดือนฉันต้องการให้โรลโอเวอร์ในวันเดียวกันของเดือน (รวมถึง 30/31 วันเดือนและปีอธิกสุรทิน)
นี่คือสิ่งที่ฉันมาด้วย:
/**
* Returns how long ago something happened in the past, showing it
* as n seconds / minutes / hours / days / weeks / months / years ago.
*
* For periods over a day, it rolls over at midnight (so doesn't depend
* on current time of day), and it correctly accounts for month-lengths
* and leap-years (months and years rollover on current day of month).
*
* $param string $timestamp in DateTime format
* $return string description of interval
*/
function ago($timestamp)
{
$then = date_create($timestamp);
// for anything over 1 day, make it rollover on midnight
$today = date_create('tomorrow'); // ie end of today
$diff = date_diff($then, $today);
if ($diff->y > 0) return $diff->y.' year'.($diff->y>1?'s':'').' ago';
if ($diff->m > 0) return $diff->m.' month'.($diff->m>1?'s':'').' ago';
$diffW = floor($diff->d / 7);
if ($diffW > 0) return $diffW.' week'.($diffW>1?'s':'').' ago';
if ($diff->d > 1) return $diff->d.' day'.($diff->d>1?'s':'').' ago';
// for anything less than 1 day, base it off 'now'
$now = date_create();
$diff = date_diff($then, $now);
if ($diff->d > 0) return 'yesterday';
if ($diff->h > 0) return $diff->h.' hour'.($diff->h>1?'s':'').' ago';
if ($diff->i > 0) return $diff->i.' minute'.($diff->i>1?'s':'').' ago';
return $diff->s.' second'.($diff->s==1?'':'s').' ago';
}
ก่อนหน้านี้ฉันได้เขียนformat_date
ฟังก์ชั่นเนื่องจากมันมีตัวเลือกมากมายเกี่ยวกับวิธีที่คุณต้องการเดทของคุณ :
function format_date($date, $type, $seperator="-")
{
if($date)
{
$day = date("j", strtotime($date));
$month = date("n", strtotime($date));
$year = date("Y", strtotime($date));
$hour = date("H", strtotime($date));
$min = date("i", strtotime($date));
$sec = date("s", strtotime($date));
switch($type)
{
case 0: $date = date("Y".$seperator."m".$seperator."d",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 1: $date = date("D, F j, Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 2: $date = date("d".$seperator."m".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 3: $date = date("d".$seperator."M".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 4: $date = date("d".$seperator."M".$seperator."Y h:i A",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 5: $date = date("m".$seperator."d".$seperator."Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 6: $date = date("M",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 7: $date = date("Y",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 8: $date = date("j",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 9: $date = date("n",mktime($hour, $min, $sec, $month, $day, $year)); break;
case 10:
$diff = abs(strtotime($date) - strtotime(date("Y-m-d h:i:s")));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
$date = $years . " years, " . $months . " months, " . $days . "days";
}
}
return($date);
}
ง่ายมาก:
<?php
$date1 = date_create("2007-03-24");
echo "Start date: ".$date1->format("Y-m-d")."<br>";
$date2 = date_create("2009-06-26");
echo "End date: ".$date2->format("Y-m-d")."<br>";
$diff = date_diff($date1,$date2);
echo "Difference between start date and end date: ".$diff->format("%y years, %m months and %d days")."<br>";
?>
กรุณาตรวจสอบลิงค์ต่อไปนี้เพื่อดูรายละเอียด:
โปรดทราบว่าสำหรับ PHP 5.3.0 หรือสูงกว่า
ฟังก์ชั่นที่ง่าย
function time_difference($time_1, $time_2, $limit = null)
{
$val_1 = new DateTime($time_1);
$val_2 = new DateTime($time_2);
$interval = $val_1->diff($val_2);
$output = array(
"year" => $interval->y,
"month" => $interval->m,
"day" => $interval->d,
"hour" => $interval->h,
"minute" => $interval->i,
"second" => $interval->s
);
$return = "";
foreach ($output AS $key => $value) {
if ($value == 1)
$return .= $value . " " . $key . " ";
elseif ($value >= 1)
$return .= $value . " " . $key . "s ";
if ($key == $limit)
return trim($return);
}
return trim($return);
}
ใช้เหมือน
echo time_difference ($time_1, $time_2, "day");
จะกลับมาเหมือนกัน 2 years 8 months 2 days
ลองคำตอบง่ายๆนี้โดยใช้date_diff ()ซึ่งผ่านการทดสอบแล้ว
$date1 = date_create("2017-11-27");
$date2 = date_create("2018-12-29");
$diff=date_diff($date1,$date2);
$months = $diff->format("%m months");
$years = $diff->format("%y years");
$days = $diff->format("%d days");
echo $years .' '.$months.' '.$days;
ผลลัพธ์คือ:
1 years 1 months 2 days
ฉันใช้ฟังก์ชั่นต่อไปนี้ซึ่งฉันเขียนเมื่อ PHP 5.3 (ตามลำดับ date_diff ()) ไม่สามารถใช้ได้:
function dateDifference($startDate, $endDate)
{
$startDate = strtotime($startDate);
$endDate = strtotime($endDate);
if ($startDate === false || $startDate < 0 || $endDate === false || $endDate < 0 || $startDate > $endDate)
return false;
$years = date('Y', $endDate) - date('Y', $startDate);
$endMonth = date('m', $endDate);
$startMonth = date('m', $startDate);
// Calculate months
$months = $endMonth - $startMonth;
if ($months <= 0) {
$months += 12;
$years--;
}
if ($years < 0)
return false;
// Calculate the days
$measure = ($months == 1) ? 'month' : 'months';
$days = $endDate - strtotime('+' . $months . ' ' . $measure, $startDate);
$days = date('z', $days);
return array($years, $months, $days);
}
DateInterval
ดี แต่มีข้อแม้อยู่สองสามข้อ:
เพื่อเอาชนะสิ่งนั้นฉันเขียนรหัสต่อไปนี้ (ปรับปรุงจาก@enobrevคำตอบ ):
function date_dif($since, $until, $keys = 'year|month|week|day|hour|minute|second')
{
$date = array_map('strtotime', array($since, $until));
if ((count($date = array_filter($date, 'is_int')) == 2) && (sort($date) === true))
{
$result = array_fill_keys(explode('|', $keys), 0);
foreach (preg_grep('~^(?:year|month)~i', $result) as $key => $value)
{
while ($date[1] >= strtotime(sprintf('+%u %s', $value + 1, $key), $date[0]))
{
++$value;
}
$date[0] = strtotime(sprintf('+%u %s', $result[$key] = $value, $key), $date[0]);
}
foreach (preg_grep('~^(?:year|month)~i', $result, PREG_GREP_INVERT) as $key => $value)
{
if (($value = intval(abs($date[0] - $date[1]) / strtotime(sprintf('%u %s', 1, $key), 0))) > 0)
{
$date[0] = strtotime(sprintf('+%u %s', $result[$key] = $value, $key), $date[0]);
}
}
return $result;
}
return false;
}
มันวิ่งสองลูป อันแรกเกี่ยวข้องกับช่วงเวลาสัมพัทธ์ (ปีและเดือน) ผ่านการบังคับให้เดรัจฉานและอันที่สองคำนวณช่วงเวลาสัมบูรณ์เพิ่มเติมด้วยการคำนวณทางคณิตศาสตร์อย่างง่าย (ดังนั้นจึงเร็วกว่า):
echo humanize(date_dif('2007-03-24', '2009-07-31', 'second')); // 74300400 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'minute|second')); // 1238400 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'hour|minute|second')); // 20640 hours, 0 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|day')); // 2 years, 129 days
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week')); // 2 years, 18 weeks
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week|day')); // 2 years, 18 weeks, 3 days
echo humanize(date_dif('2007-03-24', '2009-07-31')); // 2 years, 4 months, 1 week, 0 days, 0 hours, 0 minutes, 0 seconds
function humanize($array)
{
$result = array();
foreach ($array as $key => $value)
{
$result[$key] = $value . ' ' . $key;
if ($value != 1)
{
$result[$key] .= 's';
}
}
return implode(', ', $result);
}