开发者

PHP: Is there a function that converts a date string in a human readable format?

I want to convert a date string like "19.11.2009 14:00" into the age of i开发者_StackOverflowt now like "for 2 minutes" or "for 1 week" or "for 2 days"

Is there some code around?


$dateString = strtotime('19.11.2009 14.00');
$now = time();

$time = $dateString - $now;

if($time > 60 && $time < 3600) echo $time/60.' minutes remaining';
else if($time > 3600 && $time < 86400) echo $time/3600.' hours remaining';
else if($time > 86400 && $time < 604800) echo $time/86400.' days remaining';
else if($time > 604800 && $time < 18144000) echo $time/604800.' weeks remaining';
else if($time > 18144000 && $time < 217728000) echo $time/18144000.' months remaining';
else if($time > 217728000) echo $time/217728000.' years remaining';


Something like this

define('MINUTE',60);
define('HOUR',60*MINUTE);
define('DAY',24*HOUR);
define('WEEK',7*DAY);
define('MONTH',30*DAY);

$pastDate=strtotime($dateString);
$seconds=time()-$pastDate;
if ($seconds>MONTH)
  return $seconds/MONTH . " months";
if ($seconds>WEEK)
  return $seconds/WEEK . " weeks";
if ($seconds>DAY)
  return $seconds/DAY . " days";
if ($seconds>HOUR)
  return $seconds/HOUR . " hours";
if ($seconds>MINUTE)
  return $seconds/MINUTE . " minutes";
return $seconds . " seconds";


If you're in PHP 5.3 you could also use DateTime:diff.

$start = new DateTime('now');
$time_span = $start->diff(new DateTime($dateString));
var_dump($time_span);


This may not be 100% what you want obviously -- others have given you great answers -- but something like this may be a good alternative to a "human readable" date format.

I dug this up from some code I used quite a while ago. I haven't tested this in a while, but last I remember it worked great. I wanted to replicate something like what Facebook uses, like "5 seconds ago", but it also works for the future, using "in ..." instead of "... ago". You can probably modify this to get as much or as little detail as you want.

/**
 * Returns the amount of time that has passed from the current date
 * or the amount of time from the current date until the specified date
 *
 * Returns in the form of a partial sentence. Some examples:
 *
 * In 25 days
 * Tomorrow
 * Yesterday
 * 4 months ago
 * Next month
 * Last month
 * (etc)
 *
 * @param string $date
 * @return string
 */
public static function calculateHowLong($date) {
  // start by converting to unix time
  $when = date("U", strtotime($date));
  $isPast = ($when < time());

  $how_long = abs(time() - $when);
  if ($how_long < 60) {
    $return =  "{$how_long} seconds";
    if ($isPast) $return .= " ago"; else $return = "In {$return}";

  } elseif ($how_long < 60 * 60) {
    $return =  (int) ($how_long / 60) . " minutes";
    if ($isPast) $return .= " ago"; else $return = "In {$return}";

  } elseif ($how_long < 60 * 60 * 24) {
    $return =  (int) ($how_long / (60 * 60)) . " hours";
    if ($isPast) $return .= " ago"; else $return = "In {$return}";

  } elseif ($how_long < 60 * 60 * 24 * 2) {
    if ($isPast) $return = "Yesterday"; else $return = "Tomorrow";

  } elseif ($how_long < 60 * 60 * 24 * 7) {
    $return =  (int) ($how_long / (60 * 60 * 24)) . " days";
    if ($isPast) $return .= " ago"; else $return = "In {$return}";

  } elseif ($how_long < 60 * 60 * 24 * 13) {
    if ($isPast) $return = "Last week"; else $return = "Next week";

  } elseif ($how_long < 60 * 60 * 24 * 7 * 4) {
    $return =  (int) ($how_long / (60 * 60 * 24 * 7)) . " weeks";
    if ($isPast) $return .= " ago"; else $return = "In {$return}";

  } elseif ($how_long < 60 * 60 * 24 * 30 * 2) {
    if ($isPast) $return = "Last month"; else $return = "Next month";

  } elseif ($how_long < 60 * 60 * 24 * 30 * 12) {
    $return =  (int) ($how_long / (60 * 60 * 24 * 30)) . " months";
    if ($isPast) $return .= " ago"; else $return = "In {$return}";

  } else {
    if ($isPast) $return = "More than 1 year ago"; else $return = "In more than 1 year";
  }

  return $return;
}

It's probably a little sloppy, but feel free to make it better.


I see earlier answers offering long-winded, "Write Everything Twice" (WET) instead of "Don't Repeat Yourself" (DRY) code. Worse, they are not leveraging the modern might of PHP's DateTime class. All of the obscurity and verbosity of performing mathematical calculations on unix time can be avoided. @Sergi hints in the right direction, but neglects to offer a complete solution.

Because the scope of this question states that incoming dates will be in the past and they are to be compared to the current date/time, I'll offer the following snippet to provide generalized English expressions as described in the question.

To cover cases where a number of weeks is desired, a condition needs to be implemented because the DateTime diff object does not provide a property for w (weeks). This is the only part of the snippet that requires a mathematical calculation.

Code: (Demo)

$date = '10.11.2021 14:00';
$diff = (new DateTime($date))->diff(new DateTime());

$lookup = [
    'y' => 'year',
    'm' => 'month',
    'd' => 'day',
    'h' => 'hour',
    'i' => 'minute',
];

foreach ($lookup as $property => $word) {
    if ($diff->$property) {
        if ($property === 'd' && $diff->$property >= 7) {
            $diff->w = (int)($diff->$property / 7);
            $property = 'w';
            $word = 'week';
        }
        $output = "for {$diff->$property} $word" . ($diff->$property !== 1 ? 's' : '');
        break;
    }
}
echo $output ?? 'for mere seconds';

Output (as table using 03.12.2021 13:00 as static current datetime):

input output
03.12.2021 13:00 for mere seconds
03.12.2021 12:59 for 1 minute
03.12.2021 12:32 for 28 minutes
03.12.2021 11:21 for 1 hour
03.12.2021 09:12 for 3 hours
02.12.2021 02:03 for 1 day
27.11.2021 11:11 for 6 days
25.11.2021 13:11 for 1 week
04.11.2021 15:15 for 4 weeks
10.10.2021 17:59 for 1 month
27.04.2021 01:35 for 7 months
27.04.2020 01:35 for 1 year
27.04.2009 01:35 for 12 years
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜