Autodoc
  • Namespace
  • Class
  • Tree

Namespaces

  • BlueTihi
    • Context
  • Brickrouge
    • Element
      • Nodes
    • Renderer
    • Widget
  • ICanBoogie
    • ActiveRecord
    • AutoConfig
    • CLDR
    • Composer
    • Core
    • Event
    • Exception
    • HTTP
      • Dispatcher
      • Request
    • I18n
      • Translator
    • Mailer
    • Modules
      • Taxonomy
        • Support
      • Thumbnailer
        • Versions
    • Object
    • Operation
      • Dispatcher
    • Prototype
    • Routes
    • Routing
      • Dispatcher
    • Session
  • Icybee
    • ActiveRecord
      • Model
    • ConfigOperation
    • Document
    • EditBlock
    • Element
      • ActionbarContextual
      • ActionbarSearch
      • ActionbarToolbar
    • FormBlock
    • Installer
    • ManageBlock
    • Modules
      • Articles
      • Cache
        • Collection
        • ManageBlock
      • Comments
        • ManageBlock
      • Contents
        • ManageBlock
      • Dashboard
      • Editor
        • Collection
      • Files
        • File
        • ManageBlock
      • Forms
        • Form
        • ManageBlock
      • I18n
      • Images
        • ManageBlock
      • Members
      • Modules
        • ManageBlock
      • Nodes
        • ManageBlock
        • Module
      • Pages
        • BreadcrumbElement
        • LanguagesElement
        • ManageBlock
        • NavigationBranchElement
        • NavigationElement
        • Page
        • PageController
      • Registry
      • Search
      • Seo
      • Sites
        • ManageBlock
      • Taxonomy
        • Terms
          • ManageBlock
        • Vocabulary
          • ManageBlock
      • Users
        • ManageBlock
        • NonceLogin
        • Roles
      • Views
        • ActiveRecordProvider
        • Collection
        • View
    • Operation
      • ActiveRecord
      • Constructor
      • Module
      • Widget
    • Rendering
  • None
  • Patron
  • PHP

Classes

  • ActiveRecord
  • Cache
  • Configs
  • Core
  • DateTime
  • Debug
  • DeleteOperation
  • Errors
  • Event
  • EventHook
  • Events
  • FileCache
  • FormattedString
  • Helpers
  • I18n
  • Image
  • Inflections
  • Inflector
  • Models
  • Module
  • Modules
  • Object
  • Operation
  • PingOperation
  • Prototype
  • Route
  • Routes
  • SaveOperation
  • Session
  • TimeZone
  • TimeZoneLocation
  • Uploaded
  • Vars
  • VarsIterator

Interfaces

  • StorageInterface
  • ToArray
  • ToArrayRecursive

Traits

  • PrototypeTrait
  • ToArrayRecursiveTrait

Exceptions

  • AlreadyAuthenticated
  • AuthenticationRequired
  • Exception
  • ModuleConstructorMissing
  • ModuleIsDisabled
  • ModuleNotDefined
  • OffsetError
  • OffsetNotDefined
  • OffsetNotReadable
  • OffsetNotWritable
  • PermissionRequired
  • PropertyError
  • PropertyIsReserved
  • PropertyNotDefined
  • PropertyNotReadable
  • PropertyNotWritable
  • RouteNotDefined
  • SecurityException

Constants

  • TOKEN_ALPHA
  • TOKEN_ALPHA_UPCASE
  • TOKEN_NUMERIC
  • TOKEN_SYMBOL
  • TOKEN_SYMBOL_WIDE

Functions

  • array_flatten
  • array_insert
  • array_merge_recursive
  • camelize
  • capitalize
  • downcase
  • dump
  • escape
  • escape_all
  • exact_array_merge_recursive
  • excerpt
  • format
  • generate_token
  • generate_token_wide
  • generate_v4_uuid
  • get_autoconfig
  • humanize
  • hyphenate
  • log
  • log_error
  • log_info
  • log_success
  • log_time
  • normalize
  • normalize_namespace_part
  • normalize_url_path
  • pbkdf2
  • pluralize
  • remove_accents
  • shorten
  • singularize
  • sort_by_weight
  • stable_sort
  • strip_root
  • titleize
  • unaccent_compare
  • unaccent_compare_ci
  • underscore
  • upcase
  1 <?php
  2 
  3 /*
  4  * This file is part of the ICanBoogie package.
  5  *
  6  * (c) Olivier Laviale <olivier.laviale@gmail.com>
  7  *
  8  * For the full copyright and license information, please view the LICENSE
  9  * file that was distributed with this source code.
 10  */
 11 
 12 namespace ICanBoogie;
 13 
 14 /**
 15  * Representation of a date and time.
 16  *
 17  * <pre>
 18  * <?php
 19  *
 20  * // Let's say that _now_ is 2013-02-03 21:03:45 in Paris
 21  *
 22  * use ICanBoogie\DateTime;
 23  *
 24  * date_default_timezone_set('EST'); // set local time zone to Eastern Standard Time
 25  *
 26  * $time = new DateTime('now', 'Europe/Paris');
 27  *
 28  * echo $time;                             // 2013-02-03T21:03:45+0100
 29  * echo $time->utc;                        // 2013-02-03T20:03:45Z
 30  * echo $time->local;                      // 2013-02-03T15:03:45-0500
 31  * echo $time->utc->local;                 // 2013-02-03T15:03:45-0500
 32  * echo $time->utc->is_utc;                // true
 33  * echo $time->utc->is_local;              // false
 34  * echo $time->local->is_utc;              // false
 35  * echo $time->local->is_local;            // true
 36  * echo $time->is_dst;                     // false
 37  *
 38  * echo $time->as_rss;                     // Sun, 03 Feb 2013 21:03:45 +0100
 39  * echo $time->as_db;                      // 2013-02-03 21:03:45
 40  *
 41  * echo $time->as_time;                    // 21:03:45
 42  * echo $time->utc->as_time;               // 20:03:45
 43  * echo $time->local->as_time;             // 15:03:45
 44  * echo $time->utc->local->as_time;        // 15:03:45
 45  *
 46  * echo $time->quarter;                    // 1
 47  * echo $time->week;                       // 5
 48  * echo $time->day;                        // 3
 49  * echo $time->minute;                     // 3
 50  * echo $time->is_monday;                  // false
 51  * echo $time->is_saturday;                // true
 52  * echo $time->is_today;                   // true
 53  * echo $time->tomorrow;                   // 2013-02-04T00:00:00+0100
 54  * echo $time->tomorrow->is_future         // true
 55  * echo $time->yesterday;                  // 2013-02-02T00:00:00+0100
 56  * echo $time->yesterday->is_past          // true
 57  * echo $time->monday;                     // 2013-01-28T00:00:00+0100
 58  * echo $time->sunday;                     // 2013-02-03T00:00:00+0100
 59  *
 60  * echo $time->timestamp;                  // 1359921825
 61  * echo $time;                             // 2013-02-03T21:03:45+0100
 62  * $time->timestamp += 3600 * 4;
 63  * echo $time;                             // 2013-02-04T01:03:45+0100
 64  *
 65  * echo $time->zone;                       // Europe/Paris
 66  * echo $time->zone->offset;               // 3600
 67  * echo $time->zone->location;             // FR,48.86667,2.33333
 68  * echo $time->zone->location->latitude;   // 48.86667
 69  * $time->zone = 'Asia/Tokyo';
 70  * echo $time;                             // 2013-02-04T09:03:45+0900
 71  *
 72  * $time->hour += 72;
 73  * echo "Rendez-vous in 72 hours: $time";  // Rendez-vous in 72 hours: 2013-02-07T05:03:45+0900
 74  * </pre>
 75  *
 76  * Empty dates are also supported:
 77  *
 78  * <pre>
 79  * <?php
 80  *
 81  * $time = new DateTime('0000-00-00', 'utc');
 82  * // or
 83  * $time = DateTime::none();
 84  * echo $time;                             // -0001-11-30T00:00:00Z
 85  * echo $time->is_empty;                   // true
 86  * echo $time->as_date;                    // 0000-00-00
 87  * echo $time->as_db;                      // 0000-00-00 00:00:00
 88  *
 89  * </pre>
 90  *
 91  * @property int $timestamp Unix timestamp.
 92  * @property int $day Day of the month.
 93  * @property int $hour Hour of the day.
 94  * @property int $minute Minute of the hour.
 95  * @property int $month Month of the year.
 96  * @property-read int $quarter Quarter of the year.
 97  * @property int $second Second of the minute.
 98  * @property-read int $week Week of the year.
 99  * @property-read int $weekday Day of the week.
100  * @property int $year Year.
101  * @property-read int $year_day Day of the year.
102  * @property-read bool $is_monday `true` if the instance represents Monday.
103  * @property-read bool $is_tuesday `true` if the instance represents Tuesday.
104  * @property-read bool $is_wednesday `true` if the instance represents Wednesday.
105  * @property-read bool $is_thursday `true` if the instance represents Thursday.
106  * @property-read bool $is_friday `true` if the instance represents Friday.
107  * @property-read bool $is_saturday `true` if the instance represents Satruday.
108  * @property-read bool $is_sunday `true` if the instance represents Sunday.
109  * @property-read bool $is_today `true` if the instance is today.
110  * @property-read bool $is_past `true` if the instance lies in the past.
111  * @property-read bool $is_future `true` if the instance lies in the future.
112  * @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".
113  * @property-read DateTime $tomorrow A new instance representing the next day. Time is reseted to 00:00:00.
114  * @property-read DateTime $yesterday A new instance representing the previous day. Time is reseted to 00:00:00.
115  * @property-read DateTime $monday A new instance representing Monday of the week. Time is reseted to 00:00:00.
116  * @property-read DateTime $tuesday A new instance representing Tuesday of the week. Time is reseted to 00:00:00.
117  * @property-read DateTime $wednesday A new instance representing Wednesday of the week. Time is reseted to 00:00:00.
118  * @property-read DateTime $thursday A new instance representing Thursday of the week. Time is reseted to 00:00:00.
119  * @property-read DateTime $friday A new instance representing Friday of the week. Time is reseted to 00:00:00.
120  * @property-read DateTime $saturday A new instance representing Saturday of the week. Time is reseted to 00:00:00.
121  * @property-read DateTime $sunday A new instance representing Sunday of the week. Time is reseted to 00:00:00.
122  *
123  * @property-read string $as_atom The instance formatted according to {@link ATOM}.
124  * @property-read string $as_cookie The instance formatted according to {@link COOKIE}.
125  * @property-read string $as_iso8601 The instance formatted according to {@link ISO8601}.
126  * @property-read string $as_rfc822 The instance formatted according to {@link RFC822}.
127  * @property-read string $as_rfc850 The instance formatted according to {@link RFC850}.
128  * @property-read string $as_rfc1036 The instance formatted according to {@link RFC1036}.
129  * @property-read string $as_rfc1123 The instance formatted according to {@link RFC1123}.
130  * @property-read string $as_rfc2822 The instance formatted according to {@link RFC2822}.
131  * @property-read string $as_rfc3339 The instance formatted according to {@link RFC3339}.
132  * @property-read string $as_rss The instance formatted according to {@link RSS}.
133  * @property-read string $as_w3c The instance formatted according to {@link W3C}.
134  * @property-read string $as_db The instance formatted according to {@link DB}.
135  * @property-read string $as_number The instance formatted according to {@link NUMBER}.
136  * @property-read string $as_date The instance formatted according to {@link DATE}.
137  * @property-read string $as_time The instance formatted according to {@link TIME}.
138  *
139  * @property TimeZone $zone The timezone of the instance.
140  * @property-read DateTime $utc A new instance in the UTC timezone.
141  * @property-read DateTime $local A new instance in the local timezone.
142  * @property-read bool $is_utc `true` if the instance is in the UTC timezone.
143  * @property-read bool $is_local `true` if the instance is in the local timezone.
144  * @property-read bool $is_dst `true` if time occurs during Daylight Saving Time in its time zone.
145  *
146  * @method string format_as_atom() format_as_atom() Formats the instance according to {@link ATOM}.
147  * @method string format_as_cookie() format_as_cookie() Formats the instance according to {@link COOKIE}.
148  * @method string format_as_iso8601() format_as_iso8601() Formats the instance according to {@link ISO8601}.
149  * @method string format_as_rfc822() format_as_rfc822() Formats the instance according to {@link RFC822}.
150  * @method string format_as_rfc850() format_as_rfc850() Formats the instance according to {@link RFC850}.
151  * @method string format_as_rfc1036() format_as_rfc1036() Formats the instance according to {@link RFC1036}.
152  * @method string format_as_rfc1123() format_as_rfc1123() Formats the instance according to {@link RFC1123}.
153  * @method string format_as_rfc2822() format_as_rfc2822() Formats the instance according to {@link RFC2822}.
154  * @method string format_as_rfc3339() format_as_rfc3339() Formats the instance according to {@link RFC3339}.
155  * @method string format_as_rss() format_as_rss() Formats the instance according to {@link RSS}.
156  * @method string format_as_w3c() format_as_w3c() Formats the instance according to {@link W3C}.
157  * @method string format_as_db() format_as_db() Formats the instance according to {@link DB}.
158  * @method string format_as_number() format_as_number() Formats the instance according to {@link NUMBER}.
159  * @method string format_as_date() format_as_date() Formats the instance according to {@link DATE}.
160  * @method string format_as_time() format_as_time() Formats the instance according to {@link TIME}.
161  *
162  * @see http://en.wikipedia.org/wiki/ISO_8601
163  */
164 class DateTime extends \DateTime
165 {
166     /**
167      * DB (example: 2013-02-03 20:59:03)
168      *
169      * @var string
170      */
171     const DB = 'Y-m-d H:i:s';
172 
173     /**
174      * Number (example: 20130203205903)
175      *
176      * @var string
177      */
178     const NUMBER = 'YmdHis';
179 
180     /**
181      * Date (example: 2013-02-03)
182      *
183      * @var string
184      */
185     const DATE = 'Y-m-d';
186 
187     /**
188      * Time (example: 20:59:03)
189      *
190      * @var string
191      */
192     const TIME = 'H:i:s';
193 
194     /**
195      * Creates a {@link DateTime} instance from a source.
196      *
197      * <pre>
198      * <?php
199      *
200      * use ICanBoogie\DateTime;
201      *
202      * DateTime::from(new \DateTime('2001-01-01 01:01:01', new \DateTimeZone('Europe/Paris')));
203      * DateTime::from('2001-01-01 01:01:01', 'Europe/Paris');
204      * DateTime::from('now');
205      * </pre>
206      *
207      * @param mixed $source
208      * @param mixed $timezone The time zone to use to create the time. The value is ignored if the
209      * source is an instance of {@link \DateTime}.
210      *
211      * @return \ICanBoogie\DateTime
212      */
213     static public function from($source, $timezone=null)
214     {
215         if ($source instanceof static)
216         {
217             return clone $source;
218         }
219         else if ($source instanceof \DateTime)
220         {
221             return new static($source->format(self::DB), $source->getTimezone());
222         }
223 
224         return new static($source, $timezone);
225     }
226 
227     /**
228      * Returns an instance with the current local time and the local time zone.
229      *
230      * @return \ICanBoogie\DateTime
231      */
232     static public function now()
233     {
234         return new static();
235     }
236 
237     /**
238      * Returns an instance representing an empty date ("0000-00-00").
239      *
240      * <pre>
241      * <?php
242      *
243      * use ICanBoogie\DateTime;
244      *
245      * $d = DateTime::none();
246      * $d->is_empty;                      // true
247      * $d->zone->name;                    // "UTC"
248      *
249      * $d = DateTime::none('Asia/Tokyo');
250      * $d->is_empty;                      // true
251      * $d->zone->name;                    // "Asia/Tokio"
252      * </pre>
253      *
254      * @param \DateTimeZone|string $timezone The time zone in which the empty date is created.
255      * Defaults to "UTC".
256      *
257      * @return \ICanBoogie\DateTime
258      */
259     static public function none($timezone='utc')
260     {
261         return new static('0000-00-00', $timezone);
262     }
263 
264     /**
265      * If the time zone is specified as a string a {@link \DateTimeZone} instance is created and
266      * used instead.
267      *
268      * <pre>
269      * <?php
270      *
271      * use ICanBoogie\DateTime;
272      *
273      * new DateTime('2001-01-01 01:01:01', new \DateTimeZone('Europe/Paris')));
274      * new DateTime('2001-01-01 01:01:01', 'Europe/Paris');
275      * new DateTime;
276      * </pre>
277      *
278      * @param string $time Defaults to "now".
279      * @param \DateTimeZone|string|null $timezone
280      */
281     public function __construct($time='now', $timezone=null)
282     {
283         if (is_string($timezone))
284         {
285             $timezone = new \DateTimeZone($timezone);
286         }
287 
288         #
289         # PHP 5.3.3 considers null $timezone as an error and will complain that it is not
290         # a \DateTimeZone instance.
291         #
292 
293         $timezone === null ? parent::__construct($time) : parent::__construct($time, $timezone);
294     }
295 
296     public function __get($property)
297     {
298         if (strpos($property, 'as_') === 0)
299         {
300             return call_user_func(array($this, 'format_' . $property));
301         }
302 
303         switch ($property)
304         {
305             case 'timestamp':
306                 return $this->getTimestamp();
307 
308             case 'year':
309                 return (int) $this->format('Y');
310             case 'quarter':
311                 return floor(($this->month - 1) / 3) + 1;
312             case 'month':
313                 return (int) $this->format('m');
314             case 'week':
315                 return (int) $this->format('W');
316             case 'year_day':
317                 return (int) $this->format('z') + 1;
318             case 'weekday':
319                 return (int) $this->format('w') ?: 7;
320             case 'day':
321                 return (int) $this->format('d');
322             case 'hour':
323                 return (int) $this->format('H');
324             case 'minute':
325                 return (int) $this->format('i');
326             case 'second':
327                 return (int) $this->format('s');
328             case 'is_monday':
329                 return $this->weekday == 1;
330             case 'is_tuesday':
331                 return $this->weekday == 2;
332             case 'is_wednesday':
333                 return $this->weekday == 3;
334             case 'is_thursday':
335                 return $this->weekday == 4;
336             case 'is_friday':
337                 return $this->weekday == 5;
338             case 'is_saturday':
339                 return $this->weekday == 6;
340             case 'is_sunday':
341                 return $this->weekday == 7;
342             case 'is_today':
343                 $now = new static('now', $this->zone);
344                 return $this->as_date === $now->as_date;
345             case 'is_past':
346                 return $this < new static('now', $this->zone);
347             case 'is_future':
348                 return $this > new static('now', $this->zone);
349             case 'is_empty':
350                 return $this->year == -1 && $this->month == 11 && $this->day == 30;
351             case 'tomorrow':
352                 $time = clone $this;
353                 $time->modify('+1 day');
354                 $time->setTime(0, 0, 0);
355                 return $time;
356             case 'yesterday':
357                 $time = clone $this;
358                 $time->modify('-1 day');
359                 $time->setTime(0, 0, 0);
360                 return $time;
361 
362             /*
363              * days
364              */
365             case 'monday':
366             case 'tuesday':
367             case 'wednesday':
368             case 'thursday':
369             case 'friday':
370             case 'saturday':
371             case 'sunday':
372 
373                 return $this->{ 'get_' . $property }();
374 
375             case 'zone':
376                 return TimeZone::from($this->getTimezone());
377             case 'utc':
378             case 'local':
379                 $time = clone $this;
380                 $time->setTimezone($property);
381                 return $time;
382             case 'is_utc':
383                 return $this->zone->name == 'UTC';
384             case 'is_local':
385                 return $this->zone->name == date_default_timezone_get();
386             case 'is_dst':
387                 $timestamp = $this->timestamp;
388                 $transitions = $this->zone->getTransitions($timestamp, $timestamp);
389                 return $transitions[0]['isdst'];
390         }
391 
392         if (class_exists('ICanBoogie\PropertyNotDefined'))
393         {
394             throw new PropertyNotDefined(array($property, $this));
395         }
396         else
397         {
398             throw new \RuntimeException("Property is not defined: $property.");
399         }
400     }
401 
402     /**
403      * Returns Monday of the week.
404      *
405      * @return \ICanBoogie\DateTime
406      */
407     protected function get_monday()
408     {
409         $time = clone $this;
410         $day = $time->weekday;
411 
412         if ($day != 1)
413         {
414             $time->modify('-' . ($day - 1) . ' day');
415         }
416 
417         $time->setTime(0, 0, 0);
418 
419         return $time;
420     }
421 
422     /**
423      * Returns Tuesday of the week.
424      *
425      * @return \ICanBoogie\DateTime
426      */
427     protected function get_tuesday()
428     {
429         return $this->monday->modify('+1 day');
430     }
431 
432     /**
433      * Returns Wednesday of the week.
434      *
435      * @return \ICanBoogie\DateTime
436      */
437     protected function get_wednesday()
438     {
439         return $this->monday->modify('+2 day');
440     }
441 
442     /**
443      * Returns Thursday of the week.
444      *
445      * @return \ICanBoogie\DateTime
446      */
447     protected function get_thursday()
448     {
449         return $this->monday->modify('+3 day');
450     }
451 
452     /**
453      * Returns Friday of the week.
454      *
455      * @return \ICanBoogie\DateTime
456      */
457     protected function get_friday()
458     {
459         return $this->monday->modify('+4 day');
460     }
461 
462     /**
463      * Returns Saturday of the week.
464      *
465      * @return \ICanBoogie\DateTime
466      */
467     protected function get_saturday()
468     {
469         return $this->monday->modify('+5 day');
470     }
471 
472     /**
473      * Returns Sunday of the week.
474      *
475      * @return \ICanBoogie\DateTime
476      */
477     protected function get_sunday()
478     {
479         $time = clone $this;
480         $day = $time->weekday;
481 
482         if ($day != 7)
483         {
484             $time->modify('+' . (7 - $day) . ' day');
485         }
486 
487         $time->setTime(0, 0, 0);
488 
489         return $time;
490     }
491 
492     /**
493      * Sets the {@link $year}, {@link $month}, {@link $day}, {@link $hour}, {@link $minute},
494      * {@link $second}, {@link $timestamp} and {@link $zone} properties.
495      *
496      * @throws PropertyNotWritable in attempt to set a read-only property.
497      * @throws PropertyNotDefined in attempt to set an unsupported property.
498      */
499     public function __set($property, $value)
500     {
501         static $readonly = array('quarter', 'week', 'year_day', 'weekday',
502         'tomorrow', 'yesterday', 'utc', 'local');
503 
504         switch ($property)
505         {
506             case 'year':
507             case 'month':
508             case 'day':
509             case 'hour':
510             case 'minute':
511             case 'second':
512                 $this->change(array($property => $value));
513                 return;
514 
515             case 'timestamp':
516                 $this->setTimestamp($value);
517                 return;
518 
519             case 'zone':
520                 $this->setTimezone($value);
521                 return;
522         }
523 
524         if (strpos($property, 'is_') === 0 || strpos($property, 'as_') === 0 || in_array($property, $readonly) || method_exists($this, 'get_' . $property))
525         {
526             if (class_exists('ICanBoogie\PropertyNotWritable'))
527             {
528                 throw new PropertyNotWritable(array($property, $this));
529             }
530             else
531             {
532                 throw new \RuntimeException("Property is not writeable: $property.");
533             }
534         }
535 
536         if (class_exists('ICanBoogie\PropertyNotDefined'))
537         {
538             throw new PropertyNotDefined(array($property, $this));
539         }
540         else
541         {
542             throw new \RuntimeException("Property is not defined: $property.");
543         }
544     }
545 
546     /**
547      * Handles the `format_as_*` methods.
548      *
549      * If the format is {@link RFC822} or {@link RFC1123} and the time zone is equivalent to GMT,
550      * the offset `+0000` is replaced by `GMT` according to the specs.
551      *
552      * If the format is {@link ISO8601} and the time zone is equivalent to UTC, the offset `+0000`
553      * is replaced by `Z` according to the specs.
554      *
555      * @throws \BadMethodCallException in attempt to call an unsupported method.
556      */
557     public function __call($method, $arguments)
558     {
559         if (strpos($method, 'format_as_') === 0)
560         {
561             $as = strtoupper(substr($method, strlen('format_as_')));
562             $format = constant(__CLASS__ . '::' . $as);
563             $value = $this->format($format);
564 
565             if ($as == 'RFC822' || $as == 'RFC1123')
566             {
567                 $value = str_replace('+0000', 'GMT', $value);
568             }
569             else if ($as == 'ISO8601')
570             {
571                 $value = str_replace('+0000', 'Z', $value);
572             }
573 
574             return $value;
575         }
576 
577         throw new \BadMethodCallException("Unsupported method: $method.");
578     }
579 
580     /**
581      * Returns the datetime formated as {@link ISO8601}.
582      */
583     public function __toString()
584     {
585         return $this->as_iso8601;
586     }
587 
588     /**
589      * The timezone can be specified as a string.
590      *
591      * If the timezone is `local` the timezone returned by {@link date_default_timezone_get()} is
592      * used instead.
593      */
594     public function setTimezone($timezone)
595     {
596         if ($timezone === 'local')
597         {
598             $timezone = date_default_timezone_get();
599         }
600 
601         if (!($timezone instanceof \DateTimeZone))
602         {
603             $timezone = new \DateTimeZone($timezone);
604         }
605 
606         return parent::setTimezone($timezone);
607     }
608 
609     /**
610      * Modifies the properties of the instance occording to the options.
611      *
612      * The following properties can be updated: {@link $year}, {@link $month}, {@link $day},
613      * {@link $hour}, {@link $minute} and {@link $second}.
614      *
615      * Note: Values exceeding ranges are added to their parent values.
616      *
617      * <pre>
618      * <?php
619      *
620      * use ICanBoogie\DateTime;
621      *
622      * $time = new DateTime('now');
623      * $time->change(array('year' => 2000, 'second' => 0));
624      * </pre>
625      *
626      * @param array $options
627      * @param bool $cascade If `true`, time options (`hour`, `minute`, `second`) reset
628      * cascadingly, so if only the hour is passed, then minute and second is set to 0. If the hour
629      * and minute is passed, then second is set to 0.
630      */
631     public function change(array $options, $cascade=false)
632     {
633         static $default_options = array
634         (
635             'year' => null,
636             'month' => null,
637             'day' => null,
638             'hour' => null,
639             'minute' => null,
640             'second' => null
641         );
642 
643         extract(array_intersect_key($options + $default_options, $default_options));
644 
645         if ($cascade)
646         {
647             if ($hour !== null && $minute === null)
648             {
649                 $minute = 0;
650             }
651 
652             if ($minute !== null && $second === null)
653             {
654                 $second = 0;
655             }
656         }
657 
658         if ($year !== null || $month !== null || $day !== null)
659         {
660             $this->setDate
661             (
662                 $year === null ? $this->year : $year,
663                 $month === null ? $this->month : $month,
664                 $day === null ? $this->day : $day
665             );
666         }
667 
668         if ($hour !== null || $minute !== null || $second !== null)
669         {
670             $this->setTime
671             (
672                 $hour === null ? $this->hour : $hour,
673                 $minute === null ? $this->minute : $minute,
674                 $second === null ? $this->second : $second
675             );
676         }
677 
678         return $this;
679     }
680 
681     /**
682      * If the instance represents an empty date and the format is {@link DATE} or {@link DB},
683      * an empty date is returned, respectively "0000-00-00" and "0000-00-00 00:00:00". Note that
684      * the time information is discarted for {@link DB}. This only apply to {@link DATE} and
685      * {@link DB} formats. For instance {@link RSS} will return the following string:
686      * "Wed, 30 Nov -0001 00:00:00 +0000".
687      */
688     public function format($format)
689     {
690         if (($format == self::DATE || $format == self::DB) && $this->is_empty)
691         {
692             if ($format == self::DATE)
693             {
694                 return '0000-00-00';
695             }
696             else
697             {
698                 return '0000-00-00 00:00:00';
699             }
700         }
701 
702         return parent::format($format);
703     }
704 }
Autodoc API documentation generated by ApiGen 2.8.0