public function format($dateTime, $format = null, $timezone = null)
	{
		// Do string replacements for date format options that can be translated.
		$format = preg_replace('/(^|[^\\\])D/', "\\1" . self::DAY_ABBR, $format);
		$format = preg_replace('/(^|[^\\\])l/', "\\1" . self::DAY_NAME, $format);
		$format = preg_replace('/(^|[^\\\])M/', "\\1" . self::MONTH_ABBR, $format);
		$format = preg_replace('/(^|[^\\\])F/', "\\1" . self::MONTH_NAME, $format);


		// Clone to allow timezone operations
		if ($dateTime instanceof \DateTime)
		{
			$dateTimeInZone = clone $dateTime;
		}
		// Or create from string
		else
		{
			$dateTimeInZone = new \DateTime($dateTime);
		}

		// Set timezone string argument
		if ($timezone instanceof \DateTimeZone)
		{
			$dateTimeInZone->setTimeZone($timezone);
		}
		// Set timezone DateTimeZone argument
		else if (is_string($timezone))
		{
			$dateTimeInZone->setTimeZone(new \DateTimeZone($timezone));
		}
		// Or global class option
		else
		{
			$dateTimeInZone->setTimeZone($this->timezone);
		}


		// Format to string
		$return = $dateTimeInZone->format($format ?: $this->format);


		// Manually modify the month and day strings in the formatted time.
		if (strpos($return, self::DAY_ABBR) !== false)
		{
			$return = str_replace(self::DAY_ABBR, $this->dayToString($dateTimeInZone->format('w'), true), $return);
		}

		if (strpos($return, self::DAY_NAME) !== false)
		{
			$return = str_replace(self::DAY_NAME, $this->dayToString($dateTimeInZone->format('w')), $return);
		}

		if (strpos($return, self::MONTH_ABBR) !== false)
		{
			$return = str_replace(self::MONTH_ABBR, $this->monthToString($dateTimeInZone->format('n'), true), $return);
		}

		if (strpos($return, self::MONTH_NAME) !== false)
		{
			$return = str_replace(self::MONTH_NAME, $this->monthToString($dateTimeInZone->format('n')), $return);
		}


		return $return;
	}