Overview

Packages

  • Jyxo_Beholder
  • Jyxo_Charset
  • Jyxo_Color
  • Jyxo_Css
  • Jyxo_ErrorHandling
  • Jyxo_FirePhp
  • Jyxo_Gettext
    • Parser
  • Jyxo_Html
  • Jyxo_Input
    • Chain
    • Filter
    • Validator
  • Jyxo_Mail
    • Email
    • Parser
    • Sender
  • Jyxo_Rpc
    • Json
    • Xml
  • Jyxo_Shell
  • Jyxo_SpamFilter
  • Jyxo_Spl
  • Jyxo_String
  • Jyxo_Svn
  • Jyxo_Time
  • Jyxo_Timer
  • Jyxo_Webdav
  • Jyxo_XmlReader
  • PHP

Classes

  • Jyxo_Time_Composer
  • Jyxo_Time_Time
  • Jyxo_Time_Util

Exceptions

  • Jyxo_Time_ComposerException
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * Jyxo PHP Library
  5:  *
  6:  * LICENSE
  7:  *
  8:  * This source file is subject to the new BSD license that is bundled
  9:  * with this package in the file license.txt.
 10:  * It is also available through the world-wide-web at this URL:
 11:  * https://github.com/jyxo/php/blob/master/license.txt
 12:  */
 13: 
 14: /**
 15:  * Class for working with date and time.
 16:  * Internally uses a DateTime object.
 17:  * Initialization is possible using almost any date/time format (unix timestamp, SQL form, ...).
 18:  *
 19:  * Requires the Gettext PHP extension or any other implementation of the _(string) translation function.
 20:  *
 21:  * @category Jyxo
 22:  * @package Jyxo_Time
 23:  * @copyright Copyright (c) 2005-2011 Jyxo, s.r.o.
 24:  * @license https://github.com/jyxo/php/blob/master/license.txt
 25:  * @author Jaroslav Hanslík
 26:  * @author Jan Kolibač
 27:  * @author Roman Řáha
 28:  * @author Martin Šamšula
 29:  * @author Ondřej Nešpor
 30:  */
 31: class Jyxo_Time_Time implements Serializable
 32: {
 33:     /**
 34:      * Second.
 35:      *
 36:      * @var string
 37:      */
 38:     const SECOND = 'second';
 39: 
 40:     /**
 41:      * Minute.
 42:      *
 43:      * @var string
 44:      */
 45:     const MINUTE = 'minute';
 46: 
 47:     /**
 48:      * Hour.
 49:      *
 50:      * @var string
 51:      */
 52:     const HOUR = 'hour';
 53: 
 54:     /**
 55:      * Day.
 56:      *
 57:      * @var string
 58:      */
 59:     const DAY = 'day';
 60: 
 61:     /**
 62:      * Week.
 63:      *
 64:      * @var string
 65:      */
 66:     const WEEK = 'week';
 67: 
 68:     /**
 69:      * Month.
 70:      *
 71:      * @var string
 72:      */
 73:     const MONTH = 'month';
 74: 
 75:     /**
 76:      * Year.
 77:      *
 78:      * @var string
 79:      */
 80:     const YEAR = 'year';
 81: 
 82:     /**
 83:      * Number of seconds in a second.
 84:      *
 85:      * @var integer
 86:      */
 87:     const INTERVAL_SECOND = 1;
 88: 
 89:     /**
 90:      * Number of seconds in a minute.
 91:      *
 92:      * @var integer
 93:      */
 94:     const INTERVAL_MINUTE = 60;
 95: 
 96:     /**
 97:      * Number of seconds in an hour.
 98:      *
 99:      * @var integer
100:      */
101:     const INTERVAL_HOUR = 3600;
102: 
103:     /**
104:      * Number of seconds in a day.
105:      *
106:      * @var integer
107:      */
108:     const INTERVAL_DAY = 86400;
109: 
110:     /**
111:      * Number of seconds in a week.
112:      *
113:      * @var integer
114:      */
115:     const INTERVAL_WEEK = 604800;
116: 
117:     /**
118:      * Number of seconds in a month.
119:      *
120:      * @var integer
121:      */
122:     const INTERVAL_MONTH = 2592000;
123: 
124:     /**
125:      * Number of seconds in a year.
126:      *
127:      * @var integer
128:      */
129:     const INTERVAL_YEAR = 31536000;
130: 
131:     /**
132:      * DateTime instance.
133:      *
134:      * @var DateTime
135:      */
136:     private $dateTime;
137: 
138:     /**
139:      * DateTimeZone instance of the original timezone.
140:      *
141:      * @var DateTimeZone
142:      */
143:     private $originalTimeZone;
144: 
145:     /**
146:      * Constructor.
147:      *
148:      * Creates an instance and initializes the internal date/time representation.
149:      *
150:      * @param string|integer|Jyxo_Time_Time|DateTime $time Date/time definition
151:      * @param string|DateTimeZone $timeZone Time zone definition
152:      * @throws InvalidArgumentException If an incompatible date/time format or time zone definition was provided
153:      */
154:     public function __construct($time, $timeZone = null)
155:     {
156:         if (!is_object($time)) {
157:             $timeZone = $this->createTimeZone($timeZone ? $timeZone : date_default_timezone_get());
158: 
159:             if (is_numeric($time)) {
160:                 // Unix timestamp as an integer or string
161:                 $this->dateTime = new DateTime(null, $timeZone);
162:                 $this->dateTime->setTimestamp($time);
163:             } elseif (is_string($time)) {
164:                 // Textual representation
165:                 try {
166:                     $this->dateTime = new DateTime($time, $timeZone);
167:                 } catch (Exception $e) {
168:                     throw new InvalidArgumentException(sprintf('Provided textual date/time definition "%s" is invalid', $time), 0, $e);
169:                 }
170:             } else {
171:                 throw new InvalidArgumentException('Provided date/time must be a number, Jyxo_Time_Time or DateTime instance or a parameter compatible with PHP function strtotime().');
172:             }
173:         } elseif ($time instanceof self) {
174:             // Jyxo_Time_Time
175:             $this->dateTime = new DateTime($time->format('Y-m-d H:i:s'), $time->getTimeZone());
176:             if ($timeZone) {
177:                 $this->dateTime->setTimezone($this->createTimeZone($timeZone));
178:             }
179:         } elseif ($time instanceof DateTime) {
180:             // DateTime
181:             $this->dateTime = clone ($time);
182:             if ($timeZone) {
183:                 $this->dateTime->setTimezone($this->createTimeZone($timeZone));
184:             }
185:         } else {
186:             throw new InvalidArgumentException('Provided date/time must be a number, Jyxo_Time_Time or DateTime instance or a parameter compatible with PHP function strtotime().');
187:         }
188:     }
189: 
190:     /**
191:      * Creates a DateTimeZone object from a time zone definition
192:      *
193:      * @param string|DateTimeZone $definition Time zone definition
194:      * @return DateTimeZone
195:      * @throws InvalidArgumentException If an invalid time zone definition was provided
196:      */
197:     protected function createTimeZone($definition)
198:     {
199:         if (is_string($definition)) {
200:             try {
201:                 return new DateTimeZone($definition);
202:             } catch (Exception $e) {
203:                 throw new InvalidArgumentException(sprintf('Invalid timezone definition "%s"', $definition), 0, $e);
204:             }
205:         } elseif (!$definition instanceof DateTimeZone) {
206:             throw new InvalidArgumentException('Invalid timezone definition');
207:         }
208: 
209:         return $definition;
210:     }
211: 
212:     /**
213:      * Helper function for creating an instance with the given date/time.
214:      *
215:      * Useful for one-time usage.
216:      *
217:      * @param string|integer|Jyxo_Time_Time|DateTime $time Date/time definition
218:      * @param string|DateTimeZone $timeZone Time zone definition
219:      * @return Jyxo_Time_Time
220:      */
221:     public static function get($time, $timeZone = null)
222:     {
223:         return new self($time, $timeZone);
224:     }
225: 
226:     /**
227:      * Returns an instance with the current date/time.
228:      *
229:      * @return Jyxo_Time_Time
230:      */
231:     public static function now()
232:     {
233:         return new self(time());
234:     }
235: 
236:     /**
237:      * Creates an instance using a date/time definition in the given format.
238:      *
239:      * @param string $format Date/time format
240:      * @param string $time Date/time definition
241:      * @return Jyxo_Time_Time
242:      */
243:     public static function createFromFormat($format, $time)
244:     {
245:         return new self(DateTime::createFromFormat($format, $time));
246:     }
247: 
248:     /**
249:      * Returns date/time in the requested format.
250:      *
251:      * @param string $name Format name
252:      * @return mixed
253:      * @throws InvalidArgumentException If an unknown format is requested
254:      */
255:     public function __get($name)
256:     {
257:         switch ($name) {
258:             case 'sql':
259:                 return $this->dateTime->format(DateTime::ISO8601);
260:             case 'email':
261:                 return $this->dateTime->format(DateTime::RFC822);
262:             case 'web':
263:                 return $this->dateTime->format(DateTime::W3C);
264:             case 'cookie':
265:                 return $this->dateTime->format(DateTime::COOKIE);
266:             case 'rss':
267:                 return $this->dateTime->format(DateTime::RSS);
268:             case 'unix':
269:                 // Returns false if the stored date/time has no valid unix timestamp representation
270:                 return $this->dateTime->getTimestamp();
271:             case 'http':
272:                 $this->setTemporaryTimeZone('GMT');
273:                 $result = $this->dateTime->format('D, d M Y H:i:s') . ' GMT';
274:                 $this->revertOriginalTimeZone();
275:                 return $result;
276:             case 'extended':
277:                 return $this->formatExtended();
278:             case 'interval':
279:                 return $this->formatAsInterval();
280:             case 'full':
281:                 if ((int) $this->dateTime->diff(new DateTime())->format('%y%m%d%h') > 0) {
282:                     // If the difference between now and the stored date/time if greater than one hour
283:                     return $this->formatExtended();
284:                 } else {
285:                     return $this->formatAsInterval();
286:                 }
287:             default:
288:                 throw new InvalidArgumentException(sprintf('Unknown format %s.', $name));
289:         }
290:     }
291: 
292:     /**
293:      * Calls a method directly on the internal DateTime object.
294:      *
295:      * @param string $method Method name
296:      * @param array $args Method arguments
297:      * @return mixed
298:      */
299:     public function __call($method, $args)
300:     {
301:         return call_user_func_array(array($this->dateTime, $method), $args);
302:     }
303: 
304:     /**
305:      * Returns date/time in the unix timestamp format.
306:      *
307:      * @return string Returns empty string if the stored date/time has no valid UT representation
308:      */
309:     public function __toString()
310:     {
311:         return (string) $this->dateTime->getTimestamp();
312:     }
313: 
314:     /**
315:      * Returns the actual time zone.
316:      *
317:      * @return DateTimeZone
318:      */
319:     public function getTimeZone()
320:     {
321:         return $this->dateTime->getTimezone();
322:     }
323: 
324:     /**
325:      * Sets a new time zone.
326:      *
327:      * @param string|DateTimeZone $timeZone The new time zone
328:      * @return Jyxo_Time_Time
329:      */
330:     public function setTimeZone($timeZone)
331:     {
332:         $this->dateTime->setTimezone($this->createTimeZone($timeZone));
333:         return $this;
334:     }
335: 
336:     /**
337:      * Sets a time zone temporarily.
338:      *
339:      * @param string|DateTimeZone $timeZone Temporary time zone definition
340:      * @throws InvalidArgumentException If an invalid time zone definition was provided
341:      */
342:     protected function setTemporaryTimeZone($timeZone)
343:     {
344:         $this->originalTimeZone = $this->dateTime->getTimezone();
345:         try {
346:             $this->setTimeZone($this->createTimeZone($timeZone));
347:         } catch (InvalidArgumentException $e) {
348:             $this->originalTimeZone = null;
349:             throw $e;
350:         }
351:     }
352: 
353:     /**
354:      * Reverts the original time zone.
355:      *
356:      * @return Jyxo_Time_Time
357:      * @throws InvalidArgumentException If there is no time zone to return to
358:      */
359:     protected function revertOriginalTimeZone()
360:     {
361:         if (null !== $this->originalTimeZone) {
362:             $this->dateTime->setTimezone($this->originalTimeZone);
363:             $this->originalTimeZone = null;
364:         }
365: 
366:         return $this;
367:     }
368: 
369:     /**
370:      * Returns date/time in the given format with months and days translated.
371:      *
372:      * @param string $format Requested format
373:      * @param string|DateTimeZone $timeZone Result time zone definition
374:      * @return string
375:      */
376:     public function format($format, $timeZone = null)
377:     {
378:         // Prepares the right result time zone if needed
379:         if ($timeZone) {
380:             $this->setTemporaryTimeZone($timeZone);
381:         }
382: 
383:         // Translation required?
384:         if (preg_match('~(?:^|[^\\\])[lDFM]~', $format)) {
385:             static $days = array();
386:             if (empty($days)) {
387:                 $days = array(_('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday'), _('Sunday'));
388:             }
389: 
390:             static $daysShort = array();
391:             if (empty($daysShort)) {
392:                 $daysShort = array(_('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'), _('Sat'), _('Sun'));
393:             }
394: 
395:             static $months = array();
396:             if (empty($months)) {
397:                 $months = array(
398:                     _('January'), _('February'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'),
399:                     _('September'), _('October'), _('November'), _('December')
400:                 );
401:             }
402:             static $monthsGen = array();
403:             if (empty($monthsGen)) {
404:                 $monthsGen = array(
405:                     _('January#~Genitive'), _('February#~Genitive'), _('March#~Genitive'), _('April#~Genitive'), _('May#~Genitive'),
406:                     _('June#~Genitive'), _('July#~Genitive'), _('August#~Genitive'), _('September#~Genitive'),
407:                     _('October#~Genitive'), _('November#~Genitive'), _('December#~Genitive')
408:                 );
409:             }
410:             static $monthsShort = array();
411:             if (empty($monthsShort)) {
412:                 $monthsShort = array(_('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May#~Shortcut'), _('Jun'), _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec'));
413:             }
414: 
415:             // Replace certain identifiers with fake ones
416:             $search = array('~(^|[^\\\])l~', '~(^|[^\\\])D~', '~(^|[^\\\])F~', '~(^|[^\\\])M~');
417:             $replace = array('$1<===>', '$1<___>', '$1<--->', '$1<...>');
418:             $format = preg_replace($search, $replace, $format);
419: 
420:             // Format the rest of the date
421:             $date = $this->dateTime->format($format);
422: 
423:             // Calculate day and month
424:             $day = $this->dateTime->format('N') - 1;
425:             $month = $this->dateTime->format('n') - 1;
426: 
427:             // If the month is not at the beginning, the genitive case and lowercase will be used
428:             $monthName = 0 !== strpos($format, '<--->') ? mb_strtolower($monthsGen[$month], 'utf-8') : $months[$month];
429: 
430:             // Add translated days and months into the result
431:             $result = strtr(
432:                 $date,
433:                 array(
434:                     '<===>' => $days[$day],
435:                     '<___>' => $daysShort[$day],
436:                     '<--->' => $monthName,
437:                     '<...>' => $monthsShort[$month]
438:                 )
439:             );
440:         } else {
441:             // No need to translate
442:             $result = $this->dateTime->format($format);
443:         }
444: 
445:         // If a custom result timezone was specified, revert the original one
446:         if ($timeZone) {
447:             $this->revertOriginalTimeZone();
448:         }
449: 
450:         return $result;
451:     }
452: 
453:     /**
454:      * Returns date/time in the form of:
455:      *
456:      * Today at 10:00
457:      * Yesterday at 10:00
458:      * Friday at 10:00
459:      * 21. March 2009 at 10:00
460:      *
461:      * @param string $dateFormat Date format
462:      * @param string $timeFormat Time format
463:      * @param string|DateTimeZone $timeZone Result time zone definition
464:      * @return string
465:      */
466:     public function formatExtended($dateFormat = 'j. F Y', $timeFormat = 'G:i', $timeZone = null)
467:     {
468:         // Sets a custom result time zone if needed
469:         if ($timeZone) {
470:             $this->setTemporaryTimeZone($timeZone);
471:         }
472: 
473:         if (($this->dateTime < new DateTime('midnight - 6 days', $this->dateTime->getTimezone())) || ($this->dateTime >= new DateTime('midnight + 24 hours', $this->dateTime->getTimezone()))) {
474:             // Past and future dates
475:             $date = $this->format($dateFormat);
476:         } elseif ($this->dateTime >= new DateTime('midnight', $this->dateTime->getTimezone())) {
477:             // Today
478:             $date = _('Today');
479:         } elseif ($this->dateTime >= new DateTime('midnight - 24 hours', $this->dateTime->getTimezone())) {
480:             // Yesterday
481:             $date = _('Yesterday');
482:         } else {
483:             // Last week
484:             static $days = array();
485:             if (empty($days)) {
486:                 $days = array(_('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday'), _('Sunday'));
487:             }
488:             $date = $days[$this->dateTime->format('N') - 1];
489:         }
490: 
491:         // If no time format is provided, only date will be returned
492:         if (empty($timeFormat)) {
493:             $result = $date;
494:         } else {
495:             // Returns date along with time
496:             $result = $date . ' ' . _('at') . ' ' . $this->dateTime->format($timeFormat);
497:         }
498: 
499:         // If a custom result timezone was specified, revert the original one
500:         if ($timeZone) {
501:             $this->revertOriginalTimeZone();
502:         }
503: 
504:         return $result;
505:     }
506: 
507:     /**
508:      * Function for formatting time differences into human readable forms.
509:      *
510:      * $t < 10 seconds = Now
511:      * 10 seconds <= $t < 60 seconds
512:      * 1 minute <= $t < 1 hour
513:      * 1 hour <= $t < 24 hours
514:      * 1 day <= $t < 7 days
515:      * 1 week <= $t < 4 weeks
516:      * 1 month <= $t < 12 months
517:      * 1 year <= $t < n years
518:      *
519:      * @param boolean $useTense Defines if declension should be used
520:      * @param string|DateTimeZone $timeZone Result time zone definition
521:      * @return string
522:      */
523:     public function formatAsInterval($useTense = true, $timeZone = null)
524:     {
525:         static $intervalList = array(
526:             self::YEAR => self::INTERVAL_YEAR,
527:             self::MONTH => self::INTERVAL_MONTH,
528:             self::WEEK => self::INTERVAL_WEEK,
529:             self::DAY => self::INTERVAL_DAY,
530:             self::HOUR => self::INTERVAL_HOUR,
531:             self::MINUTE => self::INTERVAL_MINUTE,
532:             self::SECOND => self::INTERVAL_SECOND
533:         );
534: 
535:         // Comparison time zone
536:         $timeZone = $timeZone ? $this->createTimeZone($timeZone) : $this->dateTime->getTimezone();
537: 
538:         // Difference between the stored date/time and now
539:         $differenceObject = $this->dateTime->diff(new DateTime(null, $timeZone));
540:         $diffArray = array_combine(
541:             array_keys($intervalList),
542:             explode('-', $differenceObject->format('%y-%m-0-%d-%h-%i-%s'))
543:         );
544: 
545:         // Compute the difference in seconds
546:         $diff = 0;
547:         foreach ($diffArray as $interval => $intervalCount) {
548:             $diff += $intervalList[$interval] * $intervalCount;
549:         }
550: 
551:         // If the difference is less than 10 seconds, "now" is returned
552:         if ($diff < 10) {
553:             return _('Now');
554:         }
555: 
556:         // Find the appropriate unit and calculate number of units
557:         foreach ($intervalList as $interval => $seconds) {
558:             if ($seconds <= $diff) {
559:                 $num = round($diff / $seconds);
560:                 break;
561:             }
562:         }
563: 
564:         // Past or future
565:         $period = '+' === $differenceObject->format('%R') ? 'past' : 'future';
566: 
567:         // Dictionary - this part could be written shorter but this implementation is faster
568:         $tense = $useTense ? $period : 'infinitive';
569:         switch ($tense) {
570:             // Past
571:             case 'past':
572:                 switch ($interval) {
573:                     case self::YEAR:
574:                         return sprintf(ngettext('Year ago', '%s years ago', $num), $num);
575:                     case self::MONTH:
576:                         return sprintf(ngettext('Month ago', '%s months ago', $num), $num);
577:                     case self::WEEK:
578:                         return sprintf(ngettext('Week ago', '%s weeks ago', $num), $num);
579:                     case self::DAY:
580:                         return sprintf(ngettext('Day ago', '%s days ago', $num), $num);
581:                     case self::HOUR:
582:                         return sprintf(ngettext('Hour ago', '%s hours ago', $num), $num);
583:                     case self::MINUTE:
584:                         return sprintf(ngettext('Minute ago', '%s minutes ago', $num), $num);
585:                     case self::SECOND:
586:                     default:
587:                         return sprintf(ngettext('Second ago', '%s seconds ago', $num), $num);
588:                 }
589:                 break;
590: 
591:             // Future
592:             case 'future':
593:                 switch ($interval) {
594:                     case self::YEAR:
595:                         return sprintf(ngettext('In year', 'In %s years', $num), $num);
596:                     case self::MONTH:
597:                         return sprintf(ngettext('In month', 'In %s months', $num), $num);
598:                     case self::WEEK:
599:                         return sprintf(ngettext('In week', 'In %s weeks', $num), $num);
600:                     case self::DAY:
601:                         return sprintf(ngettext('In day', 'In %s days', $num), $num);
602:                     case self::HOUR:
603:                         return sprintf(ngettext('In hour', 'In %s hours', $num), $num);
604:                     case self::MINUTE:
605:                         return sprintf(ngettext('In minute', 'In %s minutes', $num), $num);
606:                     case self::SECOND:
607:                     default:
608:                         return sprintf(ngettext('In second', 'In %s seconds', $num), $num);
609:                 }
610:                 break;
611: 
612:             // Infinitive
613:             case 'infinitive':
614:                 switch ($interval) {
615:                     case self::YEAR:
616:                         return sprintf(ngettext('Year', '%s years', $num), $num);
617:                     case self::MONTH:
618:                         return sprintf(ngettext('Month', '%s months', $num), $num);
619:                     case self::WEEK:
620:                         return sprintf(ngettext('Week', '%s weeks', $num), $num);
621:                     case self::DAY:
622:                         return sprintf(ngettext('Day', '%s days', $num), $num);
623:                     case self::HOUR:
624:                         return sprintf(ngettext('Hour', '%s hours', $num), $num);
625:                     case self::MINUTE:
626:                         return sprintf(ngettext('Minute', '%s minutes', $num), $num);
627:                     case self::SECOND:
628:                     default:
629:                         return sprintf(ngettext('Second', '%s seconds', $num), $num);
630:                 }
631:                 break;
632:             default:
633:                 break;
634:         }
635:     }
636: 
637:     /**
638:      * Returns a new date/time object and adds with the given interval added.
639:      *
640:      * @param integer|string $interval Number of seconds or a string compatible with the strtotime() function
641:      * @return Jyxo_Time_Time
642:      */
643:     public function plus($interval)
644:     {
645:         if (is_numeric($interval)) {
646:             $interval .= ' seconds';
647:         }
648: 
649:         $dateTime = clone $this->dateTime;
650:         $dateTime->modify('+' . (string) $interval);
651: 
652:         return new self($dateTime);
653:     }
654: 
655:     /**
656:      * Returns a new date/time object and adds with the given interval subtracted.
657:      *
658:      * @param integer|string $interval Number of seconds or a string compatible with the strtotime() function
659:      * @return Jyxo_Time_Time
660:      */
661:     public function minus($interval)
662:     {
663:         if (is_numeric($interval)) {
664:             $interval .= ' seconds';
665:         }
666: 
667:         $dateTime = clone $this->dateTime;
668:         $dateTime->modify('-' . (string) $interval);
669: 
670:         return new self($dateTime);
671:     }
672: 
673:     /**
674:      * Checks if the date/time already happened.
675:      *
676:      * Compares the internal date/time with the current local time of the appropriate time zone.
677:      *
678:      * @return boolean
679:      */
680:     public function hasHappened()
681:     {
682:         return '+' === $this->dateTime->diff(DateTime::createFromFormat('U', time(), $this->dateTime->getTimezone()))->format('%R');
683:     }
684: 
685:     /**
686:      * Returns a new instance with date/time truncated to the given unit.
687:      *
688:      * @param string $unit Unit to truncate the date/time to
689:      * @return Jyxo_Time_Time
690:      * @throws InvalidArgumentException If an invalid unit is provided
691:      */
692:     public function truncate($unit)
693:     {
694:         $dateTime = array(
695:             self::YEAR => 0,
696:             self::MONTH => 1,
697:             self::DAY => 1,
698:             self::HOUR => 0,
699:             self::MINUTE => 0,
700:             self::SECOND => 0
701:         );
702: 
703:         switch ((string) $unit) {
704:             case self::SECOND:
705:                 $dateTime[self::SECOND] = $this->dateTime->format('s');
706:                 // Intentionally missing break
707:             case self::MINUTE:
708:                 $dateTime[self::MINUTE] = $this->dateTime->format('i');
709:                 // Intentionally missing break
710:             case self::HOUR:
711:                 $dateTime[self::HOUR] = $this->dateTime->format('H');
712:                 // Intentionally missing break
713:             case self::DAY:
714:                 $dateTime[self::DAY] = $this->dateTime->format('d');
715:                 // Intentionally missing break
716:             case self::MONTH:
717:                 $dateTime[self::MONTH] = $this->dateTime->format('m');
718:                 // Intentionally missing break
719:             case self::YEAR:
720:                 $dateTime[self::YEAR] = $this->dateTime->format('Y');
721:                 break;
722:             default:
723:                 throw new InvalidArgumentException(sprintf('Time unit %s is not defined.', $unit));
724:         }
725: 
726:         return new self(vsprintf('%s-%s-%sT%s:%s:%s', $dateTime), $this->dateTime->getTimezone());
727:     }
728: 
729:     /**
730:      * Object serialization.
731:      *
732:      * @return string
733:      */
734:     public function serialize()
735:     {
736:         return $this->dateTime->format('Y-m-d H:i:s ') . $this->dateTime->getTimezone()->getName();
737:     }
738: 
739:     /**
740:      * Object deserialization.
741:      *
742:      * @param string $serialized Serialized data
743:      * @throws InvalidArgumentException On deserialization error
744:      */
745:     public function unserialize($serialized)
746:     {
747:         try {
748:             $data = explode(' ', $serialized);
749:             if (count($data) != 3) {
750:                 throw new Exception('Serialized data have to be in the "Y-m-d H:i:s TimeZone" format');
751:             }
752: 
753:             if (preg_match('~([+-]\d{2}):?([\d]{2})~', $data[2], $matches)) {
754:                 // Timezone defined by an UTC offset
755: 
756:                 if ($matches[2] < 0 || $matches[2] > 59 || intval($matches[1] . $matches[2]) < -1200 || intval($matches[1] . $matches[2]) > 1200) {
757:                     // Invalid offset - minutes part is invalid or the whole offset is not <= 12:00 and >= -12:00
758:                     throw new Exception(sprintf('Invalid time zone UTC offset definition: %s', $matches[0]));
759:                 }
760: 
761:                 $data[1] .= ' ' . $matches[1] . $matches[2];
762:                 $this->dateTime = new DateTime($data[0] . ' ' . $data[1]);
763:             } else {
764:                 $this->dateTime = new DateTime($data[0] . ' ' . $data[1], $this->createTimeZone($data[2]));
765:             }
766: 
767:         } catch (Exception $e) {
768:             throw new InvalidArgumentException('Deserialization error', 0, $e);
769:         }
770:     }
771: }
772: 
Jyxo PHP Library API documentation generated by ApiGen 2.3.0