TimeMashine класс работы со временем


Начинающие и продолжающие разработчики, порой ленятся писать функции, которые делают интерфейсы более дружественными. В этот раз мы разработаем класс работы со временем.

Цель: написать класс, который позволит удобно и быстро работать с со временем и преобразовывать его в разные форматы, с многоязычной поддержкой.

Input: Стандартная дата со временем, формируемая полем DATATIME в MySQL, формата гггг-мм-дд чч: мм: сс, паттерн.

Реализация под катом

Output:
1. Возвращение по паттерну:
Y — год в формате гггг(1987)
y — год в формате гг(87)
Mi — месяц в цифрах(06)
MM — месяц словом целиком(Июня)
Mm — месяц коротко(первые три буквы)(Июн)
H — час в формате чч(24 часа)(15)
h — час в формате чч(12 часов)(3pm)
m — минуты в формате мм (45)
s — секунды в формате сс (36)
В конце каждого обозначения ставится точка с запятой, для большей однозначности.

2. г лет м месяцев д дней ч часов м минут назад (1 день 1 час 1 минуту назад)(автоматическое изменение окончаний числительных). До 100 дней, если запись старше ста дней, то выводится дата с использованием пулевого паттерна.

Вариации: Можно предопределить неограниченное количество паттернов, для удобства использования.

Предопределенные объекты:
1. defPat — массив предопределенных паттернов
2. local — массив со словами

Вход в метод:
timeGet(timestamp, [string\integer\bool pattern]);
timestamp — таймстамп из базы
pattern — или паттерн строка. Или номер паттерна. Или true меряет разницу от таймстампа.

Обработка ошибок:
Если не указан паттерн, то берется нулевой предопределенный паттерн.
Если паттерн не предопределен, то возвращается оригинальный тайстамп.
Если не указан таймстамп, то возвращается текст(!) «false».

Методы:
timeSplitter() Разбивает таймстамп на массив со специфичными названиями. Возвращает ассоциативный массив.
timeReplaser() Заменяет паттерн, на значения.

Сторонние методы:
utf8_substr — возвращает часть строки в кодировке utf-8.
connum — меняет окончания числительных.

Реализация
И так, с целями и параметрами мы определились, можно начинать работу.
Начнем со сплиттера, самое удобное считаю разбить таймстамп обычной регуляркой, немного громоздкой, но вполне сносно работающей. После регулярки все будет класться в массив и возвращается. Так же если таймстамп не соответствует регулярке, то в таймЭррор кладется текст ошибки и ретурн фэлс.
function timeSplitter($timestamp="")
{
	if($timestamp == "") $timestamp = $this->timestamp;
	if(ereg("([0-9]{2,4}).([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2}).([0-9]{1,2})", $timestamp, $debris))
	{//Если дата соответствует формату 0000-00-00 00:00:00
		$this->times = array("year" => (int)$debris['1'], "month" => (int)$debris['2'], "day" => (int)$debris['3'],
					   "hour" => (int)$debris['4'], "minute" => (int)$debris['5'], "second" => (int)$debris['6'],
					   "original" => $debris['0']);
	}else{
		$this->timeError .= "timestamp не соответствует формату гггг-мм-дд чч:мм:сс
\n";
		return false;
	}
}


Далле timeReplaser, он просто заменяет через substr нужные подстроки в паттерне.
Можно было бы просто через цикл сделать замену, но к сожалению заменяющие строки у нас различаются по местоположению.
function timeReplaser()
{
	$this->timeSplitter();
	$month = $this->times['month'];
	if($month<10) $month="0".$month;
	if($this->times['hour'] < 12) $hour = $this->times['hour']."am";
	else $hour = $this->times['hour'] - 12 . "pm";
	$this->timeReturn = str_replace("Y;", $this->times['year'], $this->timeReturn);
	$this->timeReturn = str_replace("y;", substr($this->times['year'], 2, 2), $this->timeReturn);
	$this->timeReturn = str_replace("Mi;", $this->times['month'], $this->timeReturn);
	$this->timeReturn = str_replace("MM;", $this->local['month1'][$month], $this->timeReturn);
	$this->timeReturn = str_replace("Mm;", utf8_substr($this->local['month1'][$month], 0, 3), $this->timeReturn);
	$this->timeReturn = str_replace("H;", $this->times['hour'], $this->timeReturn);
	$this->timeReturn = str_replace("m;", $this->times['minute'], $this->timeReturn);
	$this->timeReturn = str_replace("h;", $hour, $this->timeReturn);
	$this->timeReturn = str_replace("s;", $this->times['second'], $this->timeReturn);
}


И timeGet. Самый большой метод в этом классе. Здесь выполняется проверка того, что надо делать и подсчет «времени от».
function timeGet($timestamp="", $pattern=0)
{
	if($timestamp == "") return "false";
	$this->timestamp = $timestamp;
	if(gettype($pattern) == "integer")
	{
		if(isset($this->patterns) && gettype($this->patterns[$pattern]) == "string")
		{
			$this->timeReturn = $this->patterns[$pattern];
			$this->timeReplaser();
		}else{
			$this->timeReturn = $timestamp;
		}
		return $this->timeReturn;
	}
	if(gettype($pattern) == "string")
	{
		$this->timestamp = $timestamp;
		$this->timeReturn = $pattern;
		$this->timeReplaser();
		return $this->timeReturn;
	}
	if(gettype($pattern) == "boolean")
	{
		if($pattern == true)
		{
			$this->timeSplitter();
			$century = mktime(	$this->times['hour'], 
								$this->times['minute'],
								$this->times['second'],
								$this->times['month'],
								$this->times['day'], 
								$this->times['year']); 
			$today = time(); 
			$difference = $today - $century; 
		if($difference > 8640000) return timeGet($timestamp);
		if($difference > 86400)
		{
				$r = floor($difference/86400);
				$ost = $difference-($r*86400);
				$back = " ".$this->connum($r, $this->local['con']['day']);
			}
			if(isset($r) || $difference > 3600)
			{
				if(isset($r)) $t = $ost;
				else $t = $difference;
				$s = floor($t/3600);
				$ost = $t-($s*3600);
				$back .= " ".$this->connum($s, $this->local['con']['hour']);
			}
			if(isset($s) || $difference > 60)
			{
				if(isset($s)) $t = $ost;
				else $t = $difference;
				$s = floor($t/60);
				$ost = $t-($s*60);
				$back .= " ".$this->connum($s, $this->local['con']['minute']);
			}
			if(isset($s) || $difference < 60)
			{
				if(isset($s)) $t = $ost;
				else $t = $difference;
				$s = $t;
				$ost = $t-$s;
				$back .= " ".$this->connum($s, $this->local['con']['second']);
			}
			echo $back;
			
			return $this->timeReturn;
		}
	}
}


FAQ
Где взять сам класс?
Скачать отсюда
  • 0
  • 26 сентября 2009, 03:02
  • haZe

Комментарии (2)

RSS свернуть / развернуть
+
0
Эх, надо еще поправку на часовой пояс добавить…
avatar

haZe

  • 26 сентября 2009, 20:09
+
0
помоему и так весело))
avatar

proXy

  • 27 сентября 2009, 15:14

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.