Skip to content

Commit

Permalink
Support for empty dates
Browse files Browse the repository at this point in the history
  • Loading branch information
Olivier Laviale committed Mar 7, 2013
1 parent 1cd71ba commit 204f9a7
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 1 deletion.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ $time->hour += 72;
echo "Rendez-vous in 72 hours: $time"; // Rendez-vous in 72 hours: 2013-02-07T05:03:45+0900
```

Empty dates are also supported:

```php
<?php

$time = new DateTime('0000-00-00', 'utc');
// or
$time = DateTime::none();
echo $time; // -0001-11-30T00:00:00Z
echo $time->is_empty; // true
echo $time->as_date; // 0000-00-00
echo $time->as_db; // 0000-00-00 00:00:00
```




Expand Down
54 changes: 54 additions & 0 deletions lib/datetime.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@
* echo "Rendez-vous in 72 hours: $time"; // Rendez-vous in 72 hours: 2013-02-07T05:03:45+0900
* </pre>
*
* Empty dates are also supported:
*
* <pre>
* <?php
*
* $time = new DateTime('0000-00-00', 'utc');
* // or
* $time = DateTime::none();
* echo $time; // -0001-11-30T00:00:00Z
* echo $time->is_empty; // true
* echo $time->as_date; // 0000-00-00
* echo $time->as_db; // 0000-00-00 00:00:00
*
* </pre>
*
* @property int $timestamp Unix timestamp.
* @property int $day Day of the month.
* @property int $hour Hour of the day.
Expand All @@ -94,6 +109,7 @@
* @property-read bool $is_today `true` if the instance is today.
* @property-read bool $is_past `true` if the instance lies in the past.
* @property-read bool $is_future `true` if the instance lies in the future.
* @property-read bool $is_empty `true` if the instance represents an empty date such as "0000-00-00" or "0000-00-00 00:00:00".
* @property-read DateTime $tomorrow A new instance representing the next day. Time is reseted to 00:00:00.
* @property-read DateTime $yesterday A new instance representing the previous day. Time is reseted to 00:00:00.
* @property-read DateTime $monday A new instance representing Monday of the week. Time is reseted to 00:00:00.
Expand Down Expand Up @@ -199,6 +215,18 @@ static public function now()
return new static();
}

/**
* Returns an instance representing an empty date ("0000-00-00").
*
* The instance is created in the "UTC" time zone.
*
* @return \ICanBoogie\DateTime
*/
static public function none()
{
return new static('0000-00-00', 'utc');
}

/**
* If the time zone is specified as a string a {@link \DateTimeZone} instance is created and
* used instead.
Expand Down Expand Up @@ -274,6 +302,8 @@ public function __get($property)
return $this < new static('now', $this->zone);
case 'is_future':
return $this > new static('now', $this->zone);
case 'is_empty':
return $this->year == -1 && $this->month == 11 && $this->day == 30;
case 'tomorrow':
$time = clone $this;
$time->modify('+1 day');
Expand Down Expand Up @@ -522,4 +552,28 @@ public function change(array $options, $cascade=false)

return $this;
}

/**
* If the instance represents an empty date and the format is {@link DATE} or {@link DB},
* an empty date is returned, respectively "0000-00-00" and "0000-00-00 00:00:00". Note that
* the time information is discarted for {@link DB}. This only apply to {@link DATE} and
* {@link DB} formats. For instance {@link RSS} will return the following string:
* "Wed, 30 Nov -0001 00:00:00 +0000".
*/
public function format($format)
{
if (($format == self::DATE || $format == self::DB) && $this->is_empty)
{
if ($format == self::DATE)
{
return '0000-00-00';
}
else
{
return '0000-00-00 00:00:00';
}
}

return parent::format($format);
}
}
62 changes: 61 additions & 1 deletion tests/DateTimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,28 @@ public function setUp()
date_default_timezone_set('Europe/Paris');
}

public function test_now()
{
$d = DateTime::now();
$now = new \DateTime('now');
$this->assertEquals(date_default_timezone_get(), $d->zone->name);
$this->assertEquals($d->year, $now->format('Y'));
$this->assertEquals($d->month, $now->format('m'));
$this->assertEquals($d->day, $now->format('d'));
$this->assertEquals($d->hour, $now->format('H'));
$this->assertEquals($d->minute, $now->format('i'));
$this->assertEquals($d->second, $now->format('s'));
}

public function test_none()
{
$d = DateTime::none();
$this->assertEquals('UTC', $d->zone->name);
$this->assertEquals(-1, $d->year);
$this->assertEquals(11, $d->month);
$this->assertEquals(30, $d->day);
}

public function test_change()
{
$d = new DateTime('2001-01-01 01:01:01');
Expand Down Expand Up @@ -466,6 +488,28 @@ public function test_set_is_future()
$d->is_future = true;
}

public function test_get_is_empty()
{
$d = DateTime::none();
$this->assertTrue($d->is_empty);
$d = new DateTime('0000-00-00 00:00:00');
$this->assertTrue($d->is_empty);
$d = new DateTime('0000-00-00');
$this->assertTrue($d->is_empty);
$d = new DateTime('now');
$this->assertFalse($d->is_empty);
$d = new DateTime('@0');
$this->assertFalse($d->is_empty);
}

/**
* @expectedException ICanBoogie\PropertyNotWritable
*/
public function test_set_is_empty()
{
DateTime::now()->is_empty = true;
}

public function test_get_tomorrow()
{
$d = new DateTime('2013-02-10 21:21:21', 'utc');
Expand Down Expand Up @@ -637,6 +681,14 @@ public function test_set_is_dst()
$d->is_dst = true;
}

public function test_format()
{
$empty = DateTime::none();
$this->assertEquals('0000-00-00', $empty->format(DateTime::DATE));
$this->assertEquals('0000-00-00 00:00:00', $empty->format(DateTime::DB));
$this->assertEquals('Wed, 30 Nov -0001 00:00:00 +0000', $empty->format(DateTime::RSS));
}

/*
* Predefined formats
*/
Expand Down Expand Up @@ -912,12 +964,16 @@ public function test_format_as_db()
{
$now = DateTime::now();
$this->assertEquals($now->format(DateTime::DB), $now->format_as_db());
$empty = DateTime::none();
$this->assertEquals('0000-00-00 00:00:00', $empty->format_as_db());
}

public function test_get_as_db()
{
$now = DateTime::now();
$this->assertEquals($now->format(DateTime::DB), $now->as_db);
$empty = DateTime::none();
$this->assertEquals('0000-00-00 00:00:00', $empty->as_db);
}

/**
Expand Down Expand Up @@ -954,12 +1010,16 @@ public function test_format_as_date()
{
$now = DateTime::now();
$this->assertEquals($now->format(DateTime::DATE), $now->format_as_date());
$empty = DateTime::none();
$this->assertEquals('0000-00-00', $empty->format_as_date());
}

public function test_get_as_date()
{
$now = DateTime::now();
$this->assertEquals($now->format(DateTime::DATE), $now->as_date);
$empty = DateTime::none();
$this->assertEquals('0000-00-00', $empty->as_date);
}

/**
Expand Down Expand Up @@ -991,4 +1051,4 @@ public function test_set_as_time()
$d = DateTime::now();
$d->as_time = true;
}
}
}

0 comments on commit 204f9a7

Please sign in to comment.