formato - obtener fecha actual php
PHP: producción de fecha/hora relativa a las marcas de tiempo (8)
Básicamente estoy tratando de convertir una marca de tiempo Unix (la función de tiempo ()) a una fecha / hora relativa que sea compatible con la fecha pasada y futura. Entonces los productos pueden ser:
hace 2 semanas
Hace 1 hora y 60 minutos
Hace 15 minutos y 54 segundos
después de 10 minutos y 15 segundos
Primero traté de codificar esto, pero hice una gran función inmanejable, y luego busqué en internet por un par de horas, sin embargo, todo lo que puedo encontrar son scripts que producen solo una parte del tiempo (eh: "1 hora atrás" sin los minutos).
¿Tienes un script que ya hace esto?
¿Por qué no estafar la forma en que drupal lo hace? Http://api.drupal.org/api/drupal/includes%21common.inc/function/format_interval/7
<?php
function format_interval($interval, $granularity = 2, $langcode = NULL) {
$units = array(
''1 year|@count years'' => 31536000,
''1 month|@count months'' => 2592000,
''1 week|@count weeks'' => 604800,
''1 day|@count days'' => 86400,
''1 hour|@count hours'' => 3600,
''1 min|@count min'' => 60,
''1 sec|@count sec'' => 1,
);
$output = '''';
foreach ($units as $key => $value) {
$key = explode(''|'', $key);
if ($interval >= $value) {
$output .= ($output ? '' '' : '''') . format_plural(floor($interval / $value), $key[0], $key[1], array(), array(''langcode'' => $langcode));
$interval %= $value;
$granularity--;
}
if ($granularity == 0) {
break;
}
}
return $output ? $output : t(''0 sec'', array(), array(''langcode'' => $langcode));
}
?>
Probablemente no necesite un reemplazo para t () y podría hacer lo suyo con format_plural con bastante facilidad ya que (probablemente) no tenga que admitir varios idiomas. http://api.drupal.org/api/drupal/includes%21common.inc/function/format_plural/7
Esta función le da "1 hora atrás" o "mañana" como resultados entre "ahora" y "marca de tiempo específica".
function time2str($ts)
{
if(!ctype_digit($ts))
$ts = strtotime($ts);
$diff = time() - $ts;
if($diff == 0)
return ''now'';
elseif($diff > 0)
{
$day_diff = floor($diff / 86400);
if($day_diff == 0)
{
if($diff < 60) return ''just now'';
if($diff < 120) return ''1 minute ago'';
if($diff < 3600) return floor($diff / 60) . '' minutes ago'';
if($diff < 7200) return ''1 hour ago'';
if($diff < 86400) return floor($diff / 3600) . '' hours ago'';
}
if($day_diff == 1) return ''Yesterday'';
if($day_diff < 7) return $day_diff . '' days ago'';
if($day_diff < 31) return ceil($day_diff / 7) . '' weeks ago'';
if($day_diff < 60) return ''last month'';
return date(''F Y'', $ts);
}
else
{
$diff = abs($diff);
$day_diff = floor($diff / 86400);
if($day_diff == 0)
{
if($diff < 120) return ''in a minute'';
if($diff < 3600) return ''in '' . floor($diff / 60) . '' minutes'';
if($diff < 7200) return ''in an hour'';
if($diff < 86400) return ''in '' . floor($diff / 3600) . '' hours'';
}
if($day_diff == 1) return ''Tomorrow'';
if($day_diff < 4) return date(''l'', $ts);
if($day_diff < 7 + (7 - date(''w''))) return ''next week'';
if(ceil($day_diff / 7) < 4) return ''in '' . ceil($day_diff / 7) . '' weeks'';
if(date(''n'', $ts) == date(''n'') + 1) return ''next month'';
return date(''F Y'', $ts);
}
}
Esto es lo que he escrito. Muestra una fecha pasada relativa a la fecha de hoy.
/**
* @param $date integer of unixtimestamp format, not actual date type
* @return string
*/
function zdateRelative($date)
{
$now = time();
$diff = $now - $date;
if ($diff < 60){
return sprintf($diff > 1 ? ''%s seconds ago'' : ''a second ago'', $diff);
}
$diff = floor($diff/60);
if ($diff < 60){
return sprintf($diff > 1 ? ''%s minutes ago'' : ''one minute ago'', $diff);
}
$diff = floor($diff/60);
if ($diff < 24){
return sprintf($diff > 1 ? ''%s hours ago'' : ''an hour ago'', $diff);
}
$diff = floor($diff/24);
if ($diff < 7){
return sprintf($diff > 1 ? ''%s days ago'' : ''yesterday'', $diff);
}
if ($diff < 30)
{
$diff = floor($diff / 7);
return sprintf($diff > 1 ? ''%s weeks ago'' : ''one week ago'', $diff);
}
$diff = floor($diff/30);
if ($diff < 12){
return sprintf($diff > 1 ? ''%s months ago'' : ''last month'', $diff);
}
$diff = date(''Y'', $now) - date(''Y'', $date);
return sprintf($diff > 1 ? ''%s years ago'' : ''last year'', $diff);
}
Esto es lo que uso en los últimos tiempos:
function zdateRelative($date)
{
$diff = time() - $date;
$periods[] = [60, 1, ''%s seconds ago'', ''a second ago''];
$periods[] = [60*100, 60, ''%s minutes ago'', ''one minute ago''];
$periods[] = [3600*70, 3600, ''%s hours ago'', ''an hour ago''];
$periods[] = [3600*24*10, 3600*24, ''%s days ago'', ''yesterday''];
$periods[] = [3600*24*30, 3600*24*7, ''%s weeks ago'', ''one week ago''];
$periods[] = [3600*24*30*30, 3600*24*30, ''%s months ago'', ''last month''];
$periods[] = [INF, 3600*24*265, ''%s years ago'', ''last year''];
foreach ($periods as $period) {
if ($diff > $period[0]) continue;
$diff = floor($diff / $period[1]);
return sprintf($diff > 1 ? $period[2] : $period[3], $diff);
}
}
Me encanta la función relativeTime de xdebug . El problema es que necesitaba que tuviera cierta granularidad.
En otras palabras, detente en segundos o minutos si así lo decido. Y ahora,
echo fTime(strtotime(''-23 hours 5 minutes 55 seconds''),0);
mostraría,
Hace 23 horas, 5 minutos
En lugar de
Hace 23 horas, 5 minutos, 55 segundos
También quería que NO bajara más en la matriz si alcanzaba una de las cantidades de mayor tiempo. Entonces, si muestra años, solo quiero mostrar años y meses. Y ahora,
echo fTime(strtotime(''-1 year 2 months 3 weeks 4 days 16 hours 15 minutes 22 seconds''),0);
Mostraría
1 año, 2 meses atrás
En lugar de
1 año, 2 meses, 3 semanas, 4 días, 16 horas, 15 minutos, 22 segundos atrás
El siguiente cambio de código hizo lo que necesitaba. Los apoyos van a xdebug primero, por supuesto. Con suerte, alguien más podría encontrarlo útil:
function fTime($time, $gran=-1) {
$d[0] = array(1,"second");
$d[1] = array(60,"minute");
$d[2] = array(3600,"hour");
$d[3] = array(86400,"day");
$d[4] = array(604800,"week");
$d[5] = array(2592000,"month");
$d[6] = array(31104000,"year");
$w = array();
$return = "";
$now = time();
$diff = ($now-$time);
$secondsLeft = $diff;
$stopat = 0;
for($i=6;$i>$gran;$i--)
{
$w[$i] = intval($secondsLeft/$d[$i][0]);
$secondsLeft -= ($w[$i]*$d[$i][0]);
if($w[$i]!=0)
{
$return.= abs($w[$i]) . " " . $d[$i][1] . (($w[$i]>1)?''s'':'''') ." ";
switch ($i) {
case 6: // shows years and months
if ($stopat==0) { $stopat=5; }
break;
case 5: // shows months and weeks
if ($stopat==0) { $stopat=4; }
break;
case 4: // shows weeks and days
if ($stopat==0) { $stopat=3; }
break;
case 3: // shows days and hours
if ($stopat==0) { $stopat=2; }
break;
case 2: // shows hours and minutes
if ($stopat==0) { $stopat=1; }
break;
case 1: // shows minutes and seconds if granularity is not set higher
break;
}
if ($i===$stopat) { break 0; }
}
}
$return .= ($diff>0)?"ago":"left";
return $return;
}
Marcus
Necesitaba uno para darme resultados como a continuación, así que escribí el mío. Con suerte, esto ayudará a alguien.
Ejemplo de uso:
$datetime = "2014-08-13 12:52:48";
echo getRelativeTime($datetime); //10 hours ago
echo getRelativeTime($datetime, 1); //10 hours ago
echo getRelativeTime($datetime, 2); //10 hours and 50 minutes ago
echo getRelativeTime($datetime, 3); //10 hours, 50 minutes and 50 seconds ago
echo getRelativeTime($datetime, 4); //10 hours, 50 minutes and 50 seconds ago
Código:
public function getRelativeTime($datetime, $depth=1) {
$units = array(
"year"=>31104000,
"month"=>2592000,
"week"=>604800,
"day"=>86400,
"hour"=>3600,
"minute"=>60,
"second"=>1
);
$plural = "s";
$conjugator = " and ";
$separator = ", ";
$suffix1 = " ago";
$suffix2 = " left";
$now = "now";
$empty = "";
# DO NOT EDIT BELOW
$timediff = time()-strtotime($datetime);
if ($timediff == 0) return $now;
if ($depth < 1) return $empty;
$max_depth = count($units);
$remainder = abs($timediff);
$output = "";
$count_depth = 0;
$fix_depth = true;
foreach ($units as $unit=>$value) {
if ($remainder>$value && $depth-->0) {
if ($fix_depth) {
$max_depth -= ++$count_depth;
if ($depth>=$max_depth) $depth=$max_depth;
$fix_depth = false;
}
$u = (int)($remainder/$value);
$remainder %= $value;
$pluralise = $u>1?$plural:$empty;
$separate = $remainder==0||$depth==0?$empty:
($depth==1?$conjugator:$separator);
$output .= "{$u} {$unit}{$pluralise}{$separate}";
}
$count_depth++;
}
return $output.($timediff<0?$suffix2:$suffix1);
}
Puedes usar Carbon a través de packagist, simplemente increíble :) https://github.com/briannesbitt/Carbon#api-humandiff
function relativeTime($time) {
$d[0] = array(1,"second");
$d[1] = array(60,"minute");
$d[2] = array(3600,"hour");
$d[3] = array(86400,"day");
$d[4] = array(604800,"week");
$d[5] = array(2592000,"month");
$d[6] = array(31104000,"year");
$w = array();
$return = "";
$now = time();
$diff = ($now-$time);
$secondsLeft = $diff;
for($i=6;$i>-1;$i--)
{
$w[$i] = intval($secondsLeft/$d[$i][0]);
$secondsLeft -= ($w[$i]*$d[$i][0]);
if($w[$i]!=0)
{
$return.= abs($w[$i]) . " " . $d[$i][1] . (($w[$i]>1)?''s'':'''') ." ";
}
}
$return .= ($diff>0)?"ago":"left";
return $return;
}
Uso:
echo relativeTime((time()-256));
4 minutes 16 seconds ago