Zeitformatierung "vor 5 Minuten"

DarkRaver

Erfahrenes Mitglied
Hallo!
Ich möchte einen normalen Timestamp bestmöglich formatieren, wie z.B. "vor 5 Minuten" oder "vor 2 Stunden", oder für Tage "vor 3 Tagen". Gibt es hier bereits eine fertige PHP-Klasse oder wie sehe hier ein guter Lösungsansatz aus?

Mfg
 
[phpf]strtotime[/phpf] sollte funktionieren:
PHP:
<?php

strtotime('-5 minutes');
strtotime('-2 hours');
strtotime('-3 days');

?>
 
Das bringt mir ja lediglich die Timestamps für die jeweiligen Zeiten, mir geht es aber um eine ordentliche Formatierung, sprich ich gebe einen Timestamp und die Klasse generiert mir dann einen formatierten String wie eben "vor 5 Minuten" oder so.
 
Moin,

ich habe da ein script gebastelt, sicher rech leienhaft aber es funktioniert, schau mal was du draus machen kannst.


PHP:
		$change_time = $row['wann'];
				$timestamp = time();
				$jetzt = time();
				
				
				$tag = date("d",$timestamp);
				$mon = date("m",$timestamp);
				$jahr = date("Y",$timestamp);
			
				$timestamp = mktime(0,0,0,$mon,$tag,$jahr);
				$erster = mktime(0,0,0,$mon,1,$jahr);
				
				#echo $timestamp;
				
						if($jetzt - $change_time < 60) {
						$wann2 = $jetzt - $change_time ;			
						$wann = "vor ".$wann2." Sekunden.";
						}				
						if($jetzt - $change_time > 60) {
							
							$wann = "vor einer Minute.";
						}				
						if($jetzt - $change_time > 120) {
							$min_dif = $jetzt - $change_time;
							$min = date("i",$min_dif);
							$wann = "vor ". $min. " Minuten.";
						}				
						if($jetzt - $change_time > 3600) {
							$std_dif = $jetzt - $change_time;
							$std = date("G",$std_dif);
							$wann = "vor ". $std. " Stunden.";
						}
										
						if($change_time < $timestamp) {
							$wann = "gestern.";
						}
						
						
						if($change_time < $timestamp - 86400) {
							$tag_dif = $jetzt - $change_time;
							$tag = date("d",$tag_dif);
							$wann = "vor ". $tag. " Tagen.";
						}
						elseif($jetzt - $change_time > $erster) {
							$wann = " vor über einem Monat";
						}
 
Das hat mich auf die Idee gebracht, meine CustomDateTime-Klasse mal ein bisschen zu erweitern:

PHP:
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL|E_STRICT);
date_default_timezone_set('Europe/Berlin');

/**
 * Class for manipulating dates and times
 * 
 * @author saftmeister
 * @version 0.2
 */
class CustomDateTime extends DateTime
{
	/**
	 * This function calculates the due of days to now from an specific date 
	 * 
	 * @param DateTime $fromDate The date to calculate the days
	 * @return int The absolute value of days difference
	 */
	public function dueDays(DateTime $fromDate)
	{
		// Get the current time stamp		
		$nowTimestamp = $this->getTimestamp();
		// Get the time stamp of the date and time to calculate the due days
		$fromDateTimestamp = $fromDate->getTimestamp();
		
		// Get the first hour of the date now
		$todayZero = $nowTimestamp - ($nowTimestamp % 86400);
		// Get the first hour of the date to calculate the due days
		$fromDayZero = $fromDateTimestamp - ($fromDateTimestamp % 86400);
		
		// Calculate the difference in days
		$diffDays = ($todayZero - $fromDayZero) / 86400;
		
		return abs($diffDays);
	}
	
	/**
	 * This function displays the relative time of a specific 
	 * CustomDateTime object against the current (now) timestamp.
	 * 
	 * It prints the relative time or date in a very human readable manner.
	 * 
	 * @return string The relative time or date in human readable manner
	 */
	public function relative()
	{
		// Create the current timestamp
		$now = new CustomDateTime();
		
		// Calculate the difference against the current time
		$diff = $this->getTimestamp() - $now->getTimestamp();
		
		// Is difference between positive 1-60 secs?
		if($diff > 0 && $diff < 60)
		{
			return sprintf("in %d Sekunde%s", $diff, $diff > 1 ? 'n' : '');
		}
		// Is difference between positive 1-60 mins?
		elseif($diff > 0 && $diff < 60 * 60)
		{
			$min = (int)$diff / 60;
			return sprintf("in %d Minute%s", $min, $min > 1 ? 'n' : '');
		}
		// Is difference between positive 1-24 hours ?
		elseif($diff > 0 && $diff < 60 * 60 * 24)
		{
			$hours = (int)$diff / (60*60);
			return sprintf("in %d Stunde%s", $hours, $hours > 1 ? 'n' : '');
		}
		// Is difference between positive 1-31 days?
		elseif($diff > 0 && $diff < 60 * 60 * 24 * 31)
		{
			$days = (int)$diff / (60*60*24);
			return sprintf("in %d Tag%s", $days, $days > 1 ? 'en' : '' );
		}
		// Is difference anything else positive?
		elseif($diff > 0 && $diff > 0)
		{
			$months = (int)$diff / (60*60*24*31);
			return sprintf("in ca %d Monat%s", $months, $months > 1 ? 'en' : '' );
		}
		// Is difference between negative 1-60 secs?
		elseif($diff > -60)
		{
			$sec = abs($diff);
			return sprintf("vor %d Sekunde%s", $sec, $sec > 1 ? 'n' : '');
		}
		// Is difference between negative 1-60 mins?
		elseif($diff > -(60 * 60))
		{
			$min = abs((int)$diff / 60);
			return sprintf("vor %d Minute%s", $min, $min > 1 ? 'n' :'');
		}
		// Is difference between negative 1-24 hours?
		elseif($diff > -(60 * 60 * 24))
		{
			$hours = abs((int)$diff / (60*60) );
			return sprintf("vor %d Stunde%s", $hours, $hours > 1 ? 'n' :'' );
		}
		// Is difference between negative 1-31 days?
		elseif($diff > -(60 * 60 * 24 * 31))
		{
			$days = abs((int)$diff / (60*60*24) );
			return sprintf("vor %d Tag%s", $days, $days > 1 ? 'en' : '' );
		}
		// Is difference anything else negative?
		elseif($diff < 0)
		{
			$months = abs( (int)$diff / (60*60*24*31) );
			return sprintf("vor ca %d Monat%s", $months, $months > 1 ? 'en' : '' );
		}
		else
		{
			return "now";
		}
	}
}

Ein einfaches Test-Script:

PHP:
<?php
require_once 'CustomDateTime.php';

$now = new CustomDateTime();
$yesterday = new CustomDateTime('-1day');
$specificDate = new CustomDateTime('2011-12-06 17:30');
$tomorrow = new CustomDateTime('+1day');
$nextWeek = new CustomDateTime('+1week');

$inFiveMinutes = new CustomDateTime('+5 minutes');
$before43Minutes = new CustomDateTime('-43 minutes');

$in32Seconds = new CustomDateTime('+32 seconds');
$before17Seconds = new CustomDateTime('-17 seconds');

$in4Hours = new CustomDateTime('+4 hours');
$before13Hours = new CustomDateTime('-13 hours');


echo $now->dueDays($yesterday) . "<br/><br/>\n";
echo $now->dueDays($specificDate) . "<br/><br/>\n";
echo $now->dueDays($tomorrow) . "<br/><br/>\n";
echo $now->dueDays($nextWeek) . "<br/><br/>\n";

echo $yesterday->relative() . "<br/><br/>\n";
echo $specificDate->relative() . "<br/><br/>\n";
echo $tomorrow->relative() . "<br/><br/>\n";
echo $nextWeek->relative() . "<br/><br/>\n";

echo $inFiveMinutes->relative() . "<br/><br/>\n";
echo $before43Minutes->relative() . "<br/><br/>\n";
echo $in32Seconds->relative() . "<br/><br/>\n";
echo $before17Seconds->relative() . "<br/><br/>\n";
echo $in4Hours->relative() . "<br/><br/>\n";
echo $before13Hours->relative() . "<br/><br/>\n";

Und der PHP-Unittest:
PHP:
<?php
require_once 'PHPUnit/Framework.php';
require_once 'CustomDateTime.php';

class CustomDateTimeTest extends PHPUnit_Framework_TestCase
{
	public function testAll()
	{
		$now = new CustomDateTime();
		$yesterday = new CustomDateTime('-1day');
		$specificDate = new CustomDateTime('2011-12-06 17:30');
		$tomorrow = new CustomDateTime('+1day');
		$nextWeek = new CustomDateTime('+1week');

		$inFiveMinutes = new CustomDateTime('+5 minutes');
		$before43Minutes = new CustomDateTime('-43 minutes');

		$in32Seconds = new CustomDateTime('+32 seconds');
		$before17Seconds = new CustomDateTime('-17 seconds');

		$in4Hours = new CustomDateTime('+4 hours');
		$before13Hours = new CustomDateTime('-13 hours');

		$this->assertEquals($now->dueDays($yesterday), 1);
		//$this->assertEquals($now->dueDays($specificDate), 174); // TODO: to dynamic!
		$this->assertEquals($now->dueDays($tomorrow), 1);
		$this->assertEquals($now->dueDays($nextWeek), 7);

		$this->assertEquals( $yesterday->relative(), 'vor 1 Tag');
		//$this->assertEquals( $specificDate->relative(), 'vor ca 5 Monaten'); // TODO: to dynamic!
		$this->assertEquals( $tomorrow->relative(), 'in 1 Tag');
		$this->assertEquals( $nextWeek->relative(), 'in 7 Tagen');

		$this->assertEquals( $inFiveMinutes->relative(), 'in 5 Minuten');
		$this->assertEquals( $before43Minutes->relative(), 'vor 43 Minuten');
		$this->assertEquals( $in32Seconds->relative(), 'in 32 Sekunden');
		$this->assertEquals( $before17Seconds->relative(), 'vor 17 Sekunden');
		$this->assertEquals( $in4Hours->relative(), 'in 4 Stunden');
		$this->assertEquals( $before13Hours->relative(), 'vor 13 Stunden');
	}
}
 
Das hat mich wiedderum auf die Idee gebracht, wie ich das umsetzen kann ;)
Hab es jetzt umgesetzt und ist ein ganz schöner Block von If-Statements, aber es funktioniert, danke! :D
 
Zurück