Overview

Namespaces

  • Apptus
    • ESales
      • Connector
        • Report
        • Time
    • Util
      • Cache
  • PHP
  • Overview
  • Namespace
  • Class
  • Tree
  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 
<?php
namespace Apptus\ESales\Connector\Time;

/**
 * A time of day in ISO 8601 format.
 */
class Time {
    /** @internal */
    const ABSOLUTE_PATTERN = '/^([0-2][0-9])((:?)([0-6][0-9])((:?)([0-6][0-9]))?)?(Z|(([\\+-])([0-1][0-9])((:?)([0-6][0-9]))?))?$/';
    /** @internal */
    const RELATIVE_SECOND_PATTERN = '/^((([0-2][0-9])(:?))?([0-6][0-9])(:?))([0-6][0-9])(Z|(([\\+-])([0-1][0-9])((:?)([0-6][0-9]))?))?$/';
    /** @internal */
    const RELATIVE_MINUTE_PATTERN = '/^(([0-2][0-9])(:?))?([0-6][0-9])(Z|(([\\+-])([0-1][0-9])((:?)([0-6][0-9]))?))?$/';
    /** @internal */
    const RELATIVE_HOUR_PATTERN = '/^([0-2][0-9])(Z|(([\\+-])([0-1][0-9])((:?)([0-6][0-9]))?))?$/';


    /**
     * Parses a time of day in ISO 8601 format and returns it as a Time object.
     *
     * If parsing fails, this method throws an exception.
     *
     * @param string
     *          The input string.
     * @throws \InvalidArgumentException if the input cannot be parsed.
     * @return Time A Time object.
    */
    public static function parse($input) {
        if ($input === null) {
            throw new \InvalidArgumentException('Argument input is null.');
        }

        if ($input === null || $input == '') {
            return null;
        }

        $matches = array ();
        $m = preg_match(self::ABSOLUTE_PATTERN, $input, $matches);

        if ($m === 1) {
            $hour = (int) $matches[1];
            $minute = empty($matches[4]) ? null : (int) $matches[4];
            $second = empty($matches[7]) ? null : (int) $matches[7];
            $offset = self::parseOffset($matches, 8, null);
            return new Time($hour, $minute, $second, $offset);
        }

        throw new \InvalidArgumentException('Illegal time format. ISO 8601 format required.');
    }

    /**
     * Parses a time of day in ISO 8601 format and returns it as a Time object.
     *
     * If parsing fails, this method throws an exception.
     *
     * The time may omit the larger units, which in such case will be
     * inherited from the start time supplied.
     *
     * @param string
     *          The input string.
     * @param Time
     *          The start time.
     * @return Time A Time object.
     * @throws \InvalidArgumentException if the input cannot be parsed.
     */
    public static function parseInContext($input, Time $start) {
        if ($start->second() !== null) {
            $matches = array ();
            $m = preg_match(self::RELATIVE_SECOND_PATTERN, $input, $matches);

            if ($m === 1) {
                $hour = empty($matches[3]) ? $start->hour() : (int) $matches[3];
                $minute = empty($matches[5]) ? $start->minute() : (int) $matches[5];
                $second = (int) $matches[7];
                $offset = self::parseOffset($matches, 8, $start->offset());
                return new Time($hour, $minute, $second, $offset);
            }
        } elseif ($start->minute() !== null) {
            $matches = array ();
            $m = preg_match(self::RELATIVE_MINUTE_PATTERN, $input, $matches);

            if ($m === 1) {
                $hour = empty($matches[2]) ? $start->hour() : (int) $matches[2];
                $minute = (int) $matches[4];
                $offset = self::parseOffset($matches, 5, $start->offset());
                return new Time($hour, $minute, null, $offset);
            }
        } else {
            $matches = array ();
            $m = preg_match(self::RELATIVE_HOUR_PATTERN, $input, $matches);

            if ($m === 1) {
                $hour = (int) $matches[1];
                $offset = self::parseOffset($matches, 2, $start->offset());
                return new Time($hour, null, null, $offset);
            }
        }

        throw new \InvalidArgumentException('Illegal time format. ISO 8601 format required.');
    }

    private static function parseOffset(array $matches, $index, $defaultValue) {
        if (empty($matches[$index])) {
            return $defaultValue;
        } elseif ($matches[$index] === 'Z') {
            return 0;
        } else {
            $sign = $matches[$index+2];
            $hour = $matches[$index+3];
            $minute = $matches[$index+6];

            $offsetInMinutes = 60 * (int) $hour;
            $offsetInMinutes += $minute == null ? 0 : (int) $minute;

            if ($sign === '-') {
                $offsetInMinutes = -$offsetInMinutes;
            }

            return $offsetInMinutes;
        }
    }

    private $hour;
    private $minute;
    private $second;
    private $offset;

    /**
     * Creates a time with the specified hour, minute and second.
     *
     * Minute and second may be omitted for less precision.
     *
     * The offset specifies difference from UTC in number of minutes.
     * The offset may be positive, negative or 0. If the offset is null, then
     * according to ISO 8601 should use local time.
     *
     * @param int
     *          The hour. May not be null.
     * @param int|null
     *          The minute. May be null.
     * @param int|null
     *          The second. May be null.
     * @param int|null
     *          The offset from UTC in minutes. May be null.
     * @throws \InvalidArgumentException
     */
    public function __construct($hour, $minute, $second, $offset) {
        if ($hour === null) {
            throw new \InvalidArgumentException('Hour may not be null.');
        }

        $this->hour = $hour;
        $this->minute = $minute;
        $this->second = $second;
        $this->offset = $offset;
    }

    /**
     * Returns the hour. Never returns null.
     *
     * @return int
     */
    public function hour() {
        return $this->hour;
    }

    /**
     * Returns the minute. May return null.
     *
     * @return int|null
     */
    public function minute() {
        return $this->minute;
    }

    /**
     * Returns the second. May return null.
     *
     * @return int|null
     */
    public function second() {
        return $this->second;
    }

    /**
     * Returns the offset from UTC in minutes. May return null.
     *
     * @return int|null
     */
    public function offset() {
        return $this->offset;
    }

    public function __toString() {
        $result = sprintf('%02d', $this->hour);

        if ($this->minute !== null) {
            $result .= sprintf(':%02d', $this->minute);

            if ($this->second !== null) {
                $result .= sprintf(':%02d', $this->second);
            }
        }

        if ($this->offset !== null) {
            if ($this->offset === 0) {
                $result .= 'Z';
            } elseif ($this->offset > 0) {
                $result .= sprintf('+%02d:%02d', (int) $this->offset / 60, $this->offset % 60);
            } else {
                $result .= sprintf('-%02d:%02d', (int) -$this->offset / 60, -$this->offset % 60);
            }
        }

        return $result;
    }

    public function equals($o) {
        if ($this === $o) return true;
        if ($o === null || gettype($o) !== 'object' || get_class($this) !== get_class($o)) return false;

        $time = $o;

        if ($this->hour !== null ? $this->hour !== $time->hour : $time->hour !== null) return false;
        if ($this->minute !== null ? $this->minute !== $time->minute : $time->minute !== null) return false;
        if ($this->offset !== null ? $this->offset !== $time->offset : $time->offset !== null) return false;
        if ($this->second !== null ? $this->second !== $time->second : $time->second !== null) return false;

        return true;
    }
}
Apptus ESales Connector PHP API documentation generated by ApiGen