Permalink
Browse files

Implemented DefaultFormatter::formatDateTime(), does not support e or…

… T yet [#14]
  • Loading branch information...
1 parent 1766302 commit 0c96c30770469c80b2c636744fefa10b6669494f @jmalloc jmalloc committed Jan 23, 2013
@@ -3,6 +3,32 @@
class DefaultFormatterTypeCheck extends \Icecave\Chrono\TypeCheck\AbstractValidator
{
+ public function validateConstruct(array $arguments)
+ {
+ if (\count($arguments) > 0) {
+ throw new \Icecave\Chrono\TypeCheck\Exception\UnexpectedArgumentException(0, $arguments[0]);
+ }
+ }
+
+ public function escape(array $arguments)
+ {
+ $argumentCount = \count($arguments);
+ if ($argumentCount < 1) {
+ throw new \Icecave\Chrono\TypeCheck\Exception\MissingArgumentException('string', 0, 'string');
+ } elseif ($argumentCount > 1) {
+ throw new \Icecave\Chrono\TypeCheck\Exception\UnexpectedArgumentException(1, $arguments[1]);
+ }
+ $value = $arguments[0];
+ if (!\is_string($value)) {
+ throw new \Icecave\Chrono\TypeCheck\Exception\UnexpectedArgumentValueException(
+ 'string',
+ 0,
+ $arguments[0],
+ 'string'
+ );
+ }
+ }
+
public function formatDate(array $arguments)
{
$argumentCount = \count($arguments);
@@ -98,4 +124,35 @@ public function instance(array $arguments)
}
}
+ public function replace(array $arguments)
+ {
+ $argumentCount = \count($arguments);
+ if ($argumentCount < 2) {
+ if ($argumentCount < 1) {
+ throw new \Icecave\Chrono\TypeCheck\Exception\MissingArgumentException('formatSpecifier', 0, 'string');
+ }
+ throw new \Icecave\Chrono\TypeCheck\Exception\MissingArgumentException('callback', 1, 'callable');
+ } elseif ($argumentCount > 2) {
+ throw new \Icecave\Chrono\TypeCheck\Exception\UnexpectedArgumentException(2, $arguments[2]);
+ }
+ $value = $arguments[0];
+ if (!\is_string($value)) {
+ throw new \Icecave\Chrono\TypeCheck\Exception\UnexpectedArgumentValueException(
+ 'formatSpecifier',
+ 0,
+ $arguments[0],
+ 'string'
+ );
+ }
+ $value = $arguments[1];
+ if (!\is_callable($value)) {
+ throw new \Icecave\Chrono\TypeCheck\Exception\UnexpectedArgumentValueException(
+ 'callback',
+ 1,
+ $arguments[1],
+ 'callable'
+ );
+ }
+ }
+
}
@@ -5,12 +5,20 @@
use Icecave\Chrono\Time;
use Icecave\Chrono\DateTime;
use Icecave\Chrono\TimeZone;
+use Icecave\Chrono\TypeCheck\TypeCheck;
+use Icecave\Chrono\Support\Calendar;
+use Icecave\Chrono\Support\Ordinal;
/**
* A string formatter that accets {@see date()} compatible format specifiers.
*/
class DefaultFormatter implements FormatterInterface
{
+ public function __construct()
+ {
+ $this->typeCheck = TypeCheck::get(__CLASS__, func_get_args());
+ }
+
/**
* Escape any special characters in the string so that they are not substituted
* for date/time components when used as a format specifier.
@@ -21,7 +29,9 @@ class DefaultFormatter implements FormatterInterface
*/
public function escape($string)
{
- throw new \Exception('Not implemented.');
+ $this->typeCheck->escape(func_get_args());
+
+ return preg_replace(self::SPECIAL_CHARS, '\\\\$0', $string);
}
/**
@@ -32,7 +42,9 @@ public function escape($string)
*/
public function formatDate(Date $date, $formatSpecifier)
{
- throw new \Exception('Not implemented.');
+ $this->typeCheck->formatDate(func_get_args());
+
+ return '';
}
/**
@@ -43,7 +55,9 @@ public function formatDate(Date $date, $formatSpecifier)
*/
public function formatTime(Time $Time, $formatSpecifier)
{
- throw new \Exception('Not implemented.');
+ $this->typeCheck->formatTime(func_get_args());
+
+ return '';
}
/**
@@ -54,7 +68,100 @@ public function formatTime(Time $Time, $formatSpecifier)
*/
public function formatDateTime(DateTime $dateTime, $formatSpecifier)
{
- throw new \Exception('Not implemented.');
+ $this->typeCheck->formatDateTime(func_get_args());
+
+ $self = $this;
+
+ return $this->replace(
+ $formatSpecifier,
+ function ($character) use ($dateTime, $self) {
+ switch ($character) {
+ case 'd':
+ return sprintf('%02d', $dateTime->day());
+ case 'D':
+ return Calendar::dayAbbreviation(Calendar::dayOfWeek($dateTime->year(), $dateTime->month(), $dateTime->day()));
+ case 'j':
+ return $dateTime->day();
+ case 'l':
+ return Calendar::dayName(Calendar::dayOfWeek($dateTime->year(), $dateTime->month(), $dateTime->day()));
+ case 'N':
+ return Calendar::dayOfWeek($dateTime->year(), $dateTime->month(), $dateTime->day());
+ case 'S':
+ return Ordinal::suffix($dateTime->day());
+ case 'w':
+ return Calendar::dayOfWeek($dateTime->year(), $dateTime->month(), $dateTime->day(), false);
+ case 'z':
+ return Calendar::dayOfYear($dateTime->year(), $dateTime->month(), $dateTime->day());
+
+ case 'W':
+ return Calendar::isoWeekNumber($dateTime->year(), $dateTime->month(), $dateTime->day());
+
+ case 'F':
+ return Calendar::monthName($dateTime->month());
+ case 'm':
+ return sprintf('%02d', $dateTime->month());
+ case 'M':
+ return Calendar::monthAbbreviation($dateTime->month());
+ case 'n':
+ return $dateTime->month();
+ case 't':
+ return Calendar::daysInMonth($dateTime->year(), $dateTime->month());
+
+ case 'L':
+ return Calendar::isLeapYear($dateTime->year()) ? '1' : '0';
+ case 'o':
+ return Calendar::isoYearNumber($dateTime->year(), $dateTime->month(), $dateTime->day());
+ case 'Y':
+ return $dateTime->year();
+ case 'y':
+ return substr($dateTime->year(), -2);
+
+ case 'a':
+ return $dateTime->hours() < 12 ? 'am' : 'pm';
+ case 'A':
+ return $dateTime->hours() < 12 ? 'AM' : 'PM';
+ case 'B':
+ return sprintf('%03d', ($dateTime->time()->toTimeZone(new TimeZone(3600))->totalSeconds() / 86400) * 1000);
+
+ case 'g':
+ return $dateTime->hours() % 12;
+ case 'G':
+ return $dateTime->hours();
+ case 'h':
+ return sprintf('%02d', $dateTime->hours() % 12);
+ case 'H':
+ return sprintf('%02d', $dateTime->hours());
+ case 'i':
+ return sprintf('%02d', $dateTime->minutes());
+ case 's':
+ return sprintf('%02d', $dateTime->seconds());
+ case 'u':
+ return 0;
+
+ case 'e':
+ break;
+ case 'I':
+ return $dateTime->timeZone()->isDst() ? '1' : '0';
+ case 'O':
+ return str_replace(':', '', $dateTime->timeZone()->isoString());
+ case 'P':
+ return $dateTime->timeZone()->isoString();
+ case 'T':
+ break;
+ case 'Z':
+ return $dateTime->timeZone()->offset();
+
+ case 'c':
+ return $dateTime->isoString();
+ case 'r':
+ return $self->formatDateTime($dateTime, 'D, d M Y H:i:s O');
+ case 'U':
+ return $dateTime->unixTime();
+ }
+
+ return null;
+ }
+ );
}
/**
@@ -65,20 +172,53 @@ public function formatDateTime(DateTime $dateTime, $formatSpecifier)
*/
public function formatTimeZone(TimeZone $timeZone, $formatSpecifier)
{
- throw new \Exception('Not implemented.');
+ $this->typeCheck->formatTimeZone(func_get_args());
+
+ return '';
}
/**
* @return DefaultFormatter The global instance of the default formatter.
*/
public static function instance()
{
+ TypeCheck::get(__CLASS__)->instance(func_get_args());
+
if (null === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
+ /**
+ * @param string $formatSpecifier
+ * @param callable $callback
+ *
+ * @return string
+ */
+ protected function replace($formatSpecifier, $callback)
+ {
+ $this->typeCheck->replace(func_get_args());
+
+ $string = preg_replace_callback(
+ self::SPECIAL_CHARS,
+ function (array $match) use ($callback) {
+ $result = $callback($match[0]);
+ if (null === $result) {
+ return $match[0];
+ }
+ return $result;
+ },
+ $formatSpecifier
+ );
+
+ return preg_replace(self::ESCAPED_CHARS, '$1', $string);
+ }
+
+ const SPECIAL_CHARS = '/(?<!\\\\)[dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU]/';
+ const ESCAPED_CHARS = '/\\\\([dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU])/';
+
private static $instance;
+ private $typeCheck;
}
Oops, something went wrong.

0 comments on commit 0c96c30

Please sign in to comment.