zbycz
3/4/2014 - 11:11 PM

PHP class DateTime - week support and more

PHP class DateTime - week support and more

<?php

namespace Clevispace;

/**
 * @author Pavel Zbytovský
 */
class DateTime extends \Nette\DateTime
{

	/**
	 * DateTime object factory from textual representation.
	 * @param string   $textual    when invalid, returns $default
	 * @param DateTime $default
	 * @return DateTime
	 */
	static public function fromString($textual, DateTime $default)
	{
		if (!$textual) {
			return $default;
		}

		try {
			$obj = new static($textual);
		} catch (\Exception $e) {
			return $default;
		}

		return $obj;
	}

	/**
	 * DateTime object factory.
	 * @param  string|int|\DateTime
	 * @return DateTime
	 */
	public static function from($time)
	{
		if ($time instanceof \DateTime) {
			return new self($time->format('Y-m-d H:i:s'), $time->getTimezone());

		} elseif (is_numeric($time)) {
			if ($time <= self::YEAR) {
				$time += time();
			}
			return new static(date('Y-m-d H:i:s', $time));

		} else { // textual or NULL
			return new static($time);
		}
	}

	/** @return DateTime month's first DateTime */
	static public function thisMonthsFirst()
	{
		return new static("FIRST DAY OF THIS MONTH 00:00:00");
	}

	/** @return DateTime month's last DateTime */
	static public function thisMonthsLast()
	{
		$d = new static("FIRST DAY OF NEXT MONTH 00:00:00");
		return $d->modify('-1 second');
	}

	// ------------------  non static ------------------

	/** @return string Y-m-d */
	public function getDate()
	{
		return $this->format('Y-m-d');
	}

	/** @return DateTime clone */
	public function getFirstDayOfMonth()
	{
		$dolly = clone $this;
		$dolly->setDate($this->format('Y'), $this->format('m'), 1);
		$dolly->setTime(0, 0);
		return $dolly;
	}

	/** @return DateTime clone */
	public function getLastDayOfMonth()
	{
		$dolly = clone $this;
		$dolly->setDate($this->format('Y'), $this->format('m')+1, 1); //works for month 13 as well
		$dolly->setTime(0, 0);
		$dolly->modify('-1 second');
		return $dolly;
	}

	/** @return DateTime clone */
	public function getFirstDayOfWeek()
	{
		$dolly = clone $this;
		$days = $dolly->format('N') ? $dolly->format('N') : 7;
		$dolly->setDate($this->format('Y'), $this->format('m'), $this->format('d') - $days + 1);
		return $dolly;
	}

	/** @return DateTime clone */
	public function getLastDayOfWeek()
	{
		$dolly = clone $this;
		$days = $dolly->format('N') ? $dolly->format('N') : 7;
		$dolly->setDate($this->format('Y'), $this->format('m'), $this->format('d') + 7 - $days);
		return $dolly;
	}

	/** @return string ex "7. - 13.12." */
	public function getWeekInterval()
	{
		$first = $this->firstDayOfWeek;
		$last = $this->lastDayOfWeek;
		$f = ($first->format('n') == $last->format('n')) ? 'j.' : 'j.n.';
		return $first->format($f) . " - " . $last->format('j.n.');
	}

	public function getYearWeek()
	{
		//o = ISO-8601 year number. This has the same value as Y, except that
		//if the ISO week number (W) belongs to the previous or next year,
		//that year is used instead. (added in PHP 5.1.0)
		return $this->firstDayOfWeek->format('oW');
	}

	public function isCurrentWeek(){
		$today = new DateTime;
		$today->setTime(0,0);
		return $this->firstDayOfWeek <= $today AND $today <= $this->lastDayOfWeek;
	}

	public function isFutureWeek()
	{
		$today = new DateTime;
		return $today < $this->firstDayOfWeek;
	}

	public function isPastWeek()
	{
		$today = new DateTime;
		return $this->lastDayOfWeek < $today;
	}


	/** Nette\Object like magic getter */
	public function __get($name)
	{
		$class = get_class($this);
		$methods = array_flip(get_class_methods($class));
		$uname = ucfirst($name);

		if (isset($methods[$m = 'get' . $uname]) || isset($methods[$m = 'is' . $uname])) { // property getter
			return $this->$m();
		} else { // strict class
			throw new \Nette\MemberAccessException("Cannot read property $class::\$$name.");
		}
	}

}