Formun iki tarihi var:
Start Date: 2007-03-24
End Date: 2009-06-26
Şimdi bu ikisi arasındaki farkı aşağıdaki biçimde bulmam gerekiyor:
2 years, 3 months and 2 days
Bunu PHP'de nasıl yapabilirim?
Formun iki tarihi var:
Start Date: 2007-03-24
End Date: 2009-06-26
Şimdi bu ikisi arasındaki farkı aşağıdaki biçimde bulmam gerekiyor:
2 years, 3 months and 2 days
Bunu PHP'de nasıl yapabilirim?
Yanıtlar:
Eski kod için bunu kullanın (PHP <5.3). Güncel çözüm için jurka'nın cevabına bakınız.
İki tarihi unix zamanına dönüştürmek için strtotime () yöntemini kullanabilir ve aralarındaki saniye sayısını hesaplayabilirsiniz. Bundan farklı zaman aralıklarını hesaplamak oldukça kolaydır.
$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);
Düzenleme: Açıkçası bunu yapmanın tercih edilen yolu aşağıdaki jurka tarafından tarif gibi. Kodum genellikle yalnızca PHP 5.3 veya daha üst sürümünüz yoksa önerilir.
Yorumlarda yer alan birkaç kişi, yukarıdaki kodun sadece bir yaklaşım olduğuna dikkat çekti. Hala pek çok amaç için iyi olduğuna inanıyorum, çünkü bir aralığın kullanımı, hassasiyet sağlamaktan ziyade ne kadar zaman geçtiğini veya kaldığını anlamak için daha fazlasıdır - bunu yapmak istiyorsanız, sadece tarihi çıktılayın.
Tüm bunlara rağmen şikayetleri ele almaya karar verdim. Gerçekten tam bir aralığa ihtiyacınız varsa ancak PHP 5.3'e erişemiyorsanız, aşağıdaki kodu kullanın (PHP 4'te de çalışmalıdır). Bu, PHP'nin yaz saatlerini hesaplamak için dahili olarak kullandığı kodun doğrudan bağlantı noktasıdır, ancak gün ışığından yararlanma süresini dikkate almaz. Bu, en fazla bir saat kapalı olduğu anlamına gelir, ancak bunun dışında doğru olmalıdır.
<?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)));
&
imzalarınızı taşıyın .
DateTime ve DateInterval nesnelerini kullanmanızı öneririm.
$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 ";
daha fazla bilgi php DateTime :: diff manuel
Kılavuzdan:
PHP 5.2.2'den itibaren, DateTime nesneleri karşılaştırma işleçleri kullanılarak karşılaştırılabilir.
$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')
.
En iyi eylem yolu PHP'nin DateTime
(ve DateInterval
) nesnelerini kullanmaktır. Her tarih bir DateTime
nesnede kapsüllenir ve daha sonra ikisi arasında bir fark yapılabilir:
$first_date = new DateTime("2012-11-30 17:03:30");
$second_date = new DateTime("2012-12-21 00:00:00");
DateTime
Nesne herhangi bir biçimde kabul eder strtotime()
olur. Daha da özel bir tarih formatı gerekiyorsa, nesneyi DateTime::createFromFormat()
oluşturmak için kullanılabilir DateTime
.
Her iki nesne de somutlaştırıldıktan sonra, birini diğerinden soyutlayabilirsiniz DateTime::diff()
.
$difference = $first_date->diff($second_date);
$difference
artık DateInterval
fark bilgisine sahip bir nesne tutuyor . A var_dump()
şuna benzer:
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
Nesneyi biçimlendirmek için , her bir değeri kontrol etmemiz ve 0 ise hariç tutmamız gerekir:
/**
* 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;
}
Şimdi geriye kalan tek şey $difference
DateInterval
nesne üzerindeki fonksiyonumuzu çağırmaktır :
echo format_interval($difference);
Ve doğru sonucu alıyoruz:
20 gün 6 saat 56 dakika 30 saniye
Hedefe ulaşmak için kullanılan kodun tamamı:
/**
* 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()
bir işlev değil, bir nesne ve PHP 5.2'den beri orada. Sunucunuzun desteklediğinden emin olun.
Saat ve Dakika ve Saniye Göster ..
$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);
Aşağıdaki bağlantıya bir göz atın. Bu şimdiye kadar bulduğum en iyi cevap .. :)
function dateDiff ($d1, $d2) {
// Return the number of days between the two dates:
return round(abs(strtotime($d1) - strtotime($d2))/86400);
} // end function dateDiff
Tarih parametrelerini ilettiğinizde hangi tarihin daha erken veya daha sonra olduğu önemli değildir. İşlev, her iki tarih arasındaki gün sayısı olarak bir pozitif sayı döndürmek için PHP ABS () mutlak değerini kullanır.
İki tarih arasındaki gün sayısının her iki tarihi de içermediğini unutmayın. Dolayısıyla, girilen tarihler dahil olmak üzere tüm tarihlerle temsil edilen gün sayısını arıyorsanız, bu işlevin sonucuna bir (1) eklemeniz gerekir.
Örneğin, 2013-02-09 ve 2013-02-14 arasındaki fark (yukarıdaki işlevle döndürüldüğü gibi) 5'tir. Ancak 2013-02-09 - 2013-02- tarih aralığının temsil ettiği gün veya tarih sayısı 14, 6'dır.
Oy verdim Jurka 'ın cevabını bu benim favorim, ama önceden php.5.3 sürümüne sahip olarak ...
Kendimi benzer bir sorun üzerinde çalışırken buldum - bu soruya ilk başta böyle geldim - ama saatlerce bir farka ihtiyacım vardı. Ama benim fonksiyonum bunu oldukça güzel bir şekilde çözdü ve kaybolmayacağı ve unutulmayacağı yerde tutmak için kendi kütüphanemde hiçbir yerim yok, bu yüzden umarım bu birileri için yararlıdır.
/**
*
* @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;
}
Ve test:
$oDate = new DateTime();
$oDate->modify('+111402189 seconds');
var_dump($oDate);
var_dump(date_diff_array(new DateTime(), $oDate));
Ve sonuç:
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
Kullanımları için değiştirdiğim orijinal fikri buradan aldım (ve umarım modifikasyonum da bu sayfada gösterilecek).
Diziden kaldırarak $aIntervals
veya belki bir $aExclude
parametre ekleyerek istemediğiniz aralıkları ("hafta" diyelim) kolayca kaldırabilir veya dizeyi çıkardığınızda filtreleyebilirsiniz.
week
dizini silmeniz şartıyla $aIntervals
( DateDiff
asla kullanmaz).
<?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);
?>
Bir PHP çerçevesi kullanıp kullanmadığınızı bilmiyorum, ancak PHP çerçevelerinin birçoğu tekerleği yeniden keşfetmenize yardımcı olmak için tarih / saat kitaplıkları ve yardımcıları var.
Örneğin CodeIgniter bu timespan()
işleve sahiptir. İki Unix zaman damgasını girmeniz yeterlidir ve otomatik olarak böyle bir sonuç oluşturur:
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';
}
Bunun için bazı basit mantık var:
<?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;
?>
Kullanabilirsiniz
getdate()
Sağlanan tarih / saatin tüm öğelerini içeren bir dizi döndüren işlev:
$diff = abs($endDate - $startDate);
$my_t=getdate($diff);
print("$my_t[year] years, $my_t[month] months and $my_t[mday] days");
Başlangıç ve bitiş tarihleriniz dize biçimindeyse şunu kullanın:
$startDate = strtotime($startDateStr);
$endDate = strtotime($endDateStr);
yukarıdaki koddan önce
$my_t["year"] -= 1970
Doğru sayıda yıl almak için bir yapmanız gerektiğini anlamanız önemlidir . Ayrıca çıkarmak gerekir senin sağ saat almak için GMT saat farkı. Ay ve tarihten 1 çıkartmanız gerekir.
// 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;
}
Bu benim fonksiyonum. Gerekli PHP> = 5.3.4. DateTime sınıfını kullanır. Çok hızlı, hızlı ve iki tarih arasındaki farkı veya hatta "o zamandan beri" denebilir.
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;
}
}
Ben kullanımına tercih ediyorum date_create
ve date_diff
nesneler.
Kod:
$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;
Çıktı:
2 years, 3 months and 2 days
Daha fazla bilgi için PHP kılavuzunu okuyundate_diff
El kitabına göre
date_diff
bir takma ) (DateTime :: fark
Bu, bir zaman damgasının verilip verilmediğini tespit etmeye çalışır ve gelecekteki tarihleri / saatleri negatif değerler olarak döndürür:
<?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;
}
Örnek kullanım:
<?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
Veya:
<?php
$christmas_2020 = 'December 25, 2020';
$countdown = time_diff($christmas_2020);
print_r($countdown);
"Eğer" tarih MySQL'de saklanırsa, fark hesaplamasını veritabanı düzeyinde yapmayı daha kolay buluyorum ... Daha sonra Gün, Saat, Min, Saniye çıktı, ayrıştırma ve sonuçları uygun şekilde görüntüleme ...
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)
Makalenizi PHP tarih ve saat hesaplamaları için bir dizi referans içeren bir sonraki sayfada buldum .
PHP kullanarak iki Tarih (ve saat) arasındaki farkı hesaplayın. Aşağıdaki sayfa, iki tarih arasındaki zaman (saat, mühimmat), gün, ay veya yıl farkını belirlemek için PHP kullanarak tarih / saat hesaplamaları yapmak için bir dizi farklı yöntem (toplam 7) sunmaktadır.
Bkz. PHP Tarih Saati - 7 Tarih Arasındaki Farkı Hesaplamak için 7 Yöntem .
Ayrıca, $ date1 = $ duedate tarihine kadar yuvarlak kesirlere göre tarih farkı döndürmek için aşağıdaki kodu da kullanabilirsiniz; // bitiş tarihini ata echo $ date2 = tarih ("Ymd"); // geçerli tarih $ ts1 = strtotime ($ date1); $ ts2 = strtotime ($ date2); $ seconds_diff = $ ts1 - $ ts2; echo $ tarihliiff = tavan (($ seconds_diff / 3600) / 24); // gün içinde geri dönüş
Tavan yerine php'nin zemin yöntemini kullanırsanız, yuvarlak kesri geri döndürür. Lütfen buradaki farkı kontrol edin, bazı durumlarda hazırlama sunucularınızın saat dilimi canlı site saat diliminden farklıysa, bu durumda farklı sonuçlar alabilirsiniz, bu nedenle koşulları uygun şekilde değiştirin.
her zaman yaşı yıl ve ay cinsinden döndürebilen aşağıdaki işlevi kullanabilirsiniz (örn. 1 Yıl 4 Ay)
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;
}
veya yaşın geçerli tarihte hesaplanmasını istiyorsanız,
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 sürümü için> = 5.3: İki tarih nesnesi oluşturun ve sonra date_diff()
işlevini kullanın . Php DateInterval nesnesini döndürür . belgelere bakın
$date1=date_create("2007-03-24");
$date2=date_create("2009-06-26");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");
PHP 5.2 ile aynı sorunu yaşadım ve MySQL ile çözdüm. Tam olarak aradığınız şey olmayabilir, ancak bu hile yapacak ve gün sayısını döndürecektir:
$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;
Daha fazla bilgi için http://dev.mysql.com/doc/refman/5.5/tr/date-and-time-functions.html#function_datediff
Herkes kod örnekleri gönderdiğinden, burada başka bir sürüm var.
Bir fonksiyonun saniye ile yıl arasındaki farkları göstermesini istedim (sadece bir birim). 1 günden uzun süreler için gece yarısında rollover olmasını istedim (Çarşamba günleri saat 9'dan itibaren 10: 00'da 1 gün değil, 2 gün önce). Ve bir aydan uzun süreler için, rollover'ın ayın aynı gününde olmasını istedim (30/31 gün ayları ve artık yıllar dahil).
Ben geldi budur:
/**
* 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';
}
Bir süre önce , tarihinizi nasıl istediğinize dair birçok seçenekformat_date
sunduğu için bir işlev yazdım :
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);
}
Çok basit:
<?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>";
?>
Ayrıntılar için lütfen aşağıdaki bağlantıyı kontrol edin:
PHP 5.3.0 veya üstü için olduğunu unutmayın.
Kolay fonksiyon
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);
}
Gibi kullanın
echo time_difference ($time_1, $time_2, "day");
Gibi dönecektir 2 years 8 months 2 days
Date_diff () kullanarak bu çok basit yanıtı deneyin , bu test edilmiştir.
$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;
çıktı:
1 years 1 months 2 days
PHP 5.3 (sırasıyla date_diff ()) mevcut olmadığında yazdığım aşağıdaki işlevi kullanıyorum:
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
harika ama birkaç uyarı var:
Bunun üstesinden gelmek için aşağıdakileri kodladım ( @enobrev yanıtından geliştirildi ):
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;
}
İki döngü çalıştırır; birincisi kaba kuvvetleme yoluyla göreli aralıkları (yıl ve aylar) ele alır ve ikincisi ek mutlak aralıkları basit aritmetik ile hesaplar (böylece daha hızlıdır):
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);
}