示例#1
0
 /**
  * Obtains an instance of `Duration` by parsing a text string.
  *
  * This will parse the ISO-8601 duration format `PnDTnHnMn.nS`
  * which is the format returned by `__toString()`.
  *
  * All of the values (days, hours, minutes, seconds, nanoseconds) are optional,
  * but the duration must at least contain one of the (days, hours, minutes, seconds) values.
  *
  * A day is considered to by 24 hours, or 86400 seconds.
  *
  * The 'T' separator must only be present if one the (hours, minutes, seconds) values are present.
  *
  * Each of the (days, hours, minutes, seconds) values can optionally be preceded with a '+' or '-' sign.
  * The whole string can also start with an optional '+' or '-' sign, which will further affect all the fields.
  *
  * @param string $text
  *
  * @return \Brick\DateTime\Duration
  *
  * @throws \Brick\DateTime\Parser\DateTimeParseException
  */
 public static function parse($text)
 {
     $pattern = '/^' . '([\\-\\+]?)' . 'P' . '(?:([\\-\\+]?[0-9]+)D)?' . '(?:(T)' . '(?:([\\-\\+]?[0-9]+)H)?' . '(?:([\\-\\+]?[0-9]+)M)?' . '(?:([\\-\\+]?[0-9]+)(?:\\.([0-9]{1,9}))?S)?' . ')?' . '()$/i';
     if (preg_match($pattern, $text, $matches) !== 1) {
         throw Parser\DateTimeParseException::invalidDuration($text);
     }
     list(, $sign, $days, $t, $hours, $minutes, $seconds, $nanos) = $matches;
     if ($hours === '' && $minutes === '' && $seconds === '') {
         if ($days === '' || $t === 'T') {
             throw Parser\DateTimeParseException::invalidDuration($text);
         }
     }
     $allNegative = $sign === '-';
     $secondsNegative = $seconds !== '' && $seconds[0] === '-';
     $nanos = str_pad($nanos, 9, '0', STR_PAD_RIGHT);
     $days = (int) $days;
     $hours = (int) $hours;
     $minutes = (int) $minutes;
     $seconds = (int) $seconds;
     $nanos = (int) $nanos;
     if ($secondsNegative) {
         $nanos = -$nanos;
     }
     if ($allNegative) {
         $days = -$days;
         $hours = -$hours;
         $minutes = -$minutes;
         $seconds = -$seconds;
         $nanos = -$nanos;
     }
     $seconds += LocalTime::SECONDS_PER_DAY * $days + LocalTime::SECONDS_PER_HOUR * $hours + LocalTime::SECONDS_PER_MINUTE * $minutes;
     if ($nanos < 0) {
         $nanos += LocalTime::NANOS_PER_SECOND;
         $seconds--;
     }
     return new Duration($seconds, $nanos);
 }
示例#2
0
 /**
  * Obtains an instance of `Period` by parsing a text string.
  *
  * This will parse the ISO-8601 period format `PnYnMnWnD`
  * which is the format returned by `__toString()`.
  *
  * All of the values (years, months, weeks, days) are optional,
  * but the period must at least contain one of these values.
  *
  * A week is converted to 7 days.
  *
  * Each of the (years, months, weeks, days) values can optionally be preceded with a '+' or '-' sign.
  * The whole string can also start with an optional '+' or '-' sign, which will further affect all the fields.
  *
  * @param string $text
  *
  * @return \Brick\DateTime\Period
  *
  * @throws \Brick\DateTime\Parser\DateTimeParseException
  */
 public static function parse($text)
 {
     $pattern = '/^' . '([\\-\\+]?)' . 'P' . '(?:([\\-\\+]?[0-9]+)Y)?' . '(?:([\\-\\+]?[0-9]+)M)?' . '(?:([\\-\\+]?[0-9]+)W)?' . '(?:([\\-\\+]?[0-9]+)D)?' . '()$/i';
     if (preg_match($pattern, $text, $matches) !== 1) {
         throw Parser\DateTimeParseException::invalidPeriod($text);
     }
     list(, $sign, $years, $months, $weeks, $days) = $matches;
     if ($years === '' && $months === '' && $weeks === '' && $days === '') {
         throw Parser\DateTimeParseException::invalidPeriod($text);
     }
     $years = (int) $years;
     $months = (int) $months;
     $weeks = (int) $weeks;
     $days = (int) $days;
     $days += LocalTime::DAYS_PER_WEEK * $weeks;
     if ($sign === '-') {
         $years = -$years;
         $months = -$months;
         $days = -$days;
     }
     return new Period($years, $months, $days);
 }