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: 
<?php
namespace Apptus\ESales\Connector\Time;

/**
 * A week date on the format YYYY-Www-D, as defined by ISO 8601.
 *
 * ISO 8601 defines week numbers in the following way. The week with the year's first Thursday in
 * it is called week 01. Weeks are numbered from 01 to 52 or 53.
 *
 * ISO 8601 also defines numbers for day of week. Monday is number 1, Tuesday number 2 and so on
 * up to Sunday which is number 7. Use the Weekday enumeration to convert between
 * day numbers and day names.
 */
class WeekDate extends IsoDate {
    /** @internal */
    const ABSOLUTE_PATTERN = '/^([0-9][0-9][0-9][0-9])((-?)W([0-5][0-9])((-?)([1-7]))?)?$/';
    /** @internal */
    const RELATIVE_DAY_PATTERN = '/^((([0-9][0-9][0-9][0-9])(-?))?W([0-5][0-9])(-?))?([1-7])$/';
    /** @internal */
    const RELATIVE_WEEK_PATTERN = '/^(([0-9][0-9][0-9][0-9])(-?))?W([0-5][0-9])$/';
    /** @internal */
    const RELATIVE_YEAR_PATTERN = '/^([0-9][0-9][0-9][0-9])$/';

    /**
     * @internal
     * @param string
     * @return WeekDate|null
     */
    public static function tryParseAbsolute($input) {
        $matches = array ();
        $m = preg_match(self::ABSOLUTE_PATTERN, $input, $matches);

        if ($m === 1) {
            $year = (int) $matches[1];
            $week = empty($matches[4]) ? null : (int) $matches[4];
            $day = empty($matches[7]) ? null : (int) $matches[7];
            return new WeekDate($year, $week, $day);
        }

        return null;
    }

    /**
     * @internal
     * @param string
     * @param WeekDate
     * @return WeekDate|null
     */
    public static function tryParseRelative($input, WeekDate $start) {
        if ($start->dayOfWeek() !== null) {
            $matches = array ();
            $m = preg_match(self::RELATIVE_DAY_PATTERN, $input, $matches);

            if ($m === 1) {
                $year = empty($matches[3]) ? $start->year() : (int) $matches[3];
                $week = empty($matches[5]) ? $start->week() : (int) $matches[5];
                $day = (int) $matches[7];
                return new WeekDate($year, $week, $day);
            }
        } elseif ($start->week() !== null) {
            $matches = array ();
            $m = preg_match(self::RELATIVE_WEEK_PATTERN, $input, $matches);

            if ($m === 1) {
                $year = empty($matches[2]) ? $start->year() : (int) $matches[2];
                $week = (int) $matches[4];
                return new WeekDate($year, $week, null);
            }
        } else {
            $matches = array ();
            $m = preg_match(self::RELATIVE_YEAR_PATTERN, $input, $matches);

            if ($m === 1) {
                $year = (int) $matches[1];
                return new WeekDate($year, null, null);
            }
        }

        return null;
    }

    private $year;
    private $week;
    private $dayOfWeek;

    /**
     * Creates a new week date with the specified year, week and day of week.
     *
     * Day of week may be omitted, causing less precision. If day of week is
     * omitted, then week number may also be omitted. However, year is required.
     *
     * @param int
     *          The year. May not be null.
     * @param int|null
     *          The week number according to ISO 8601. May be null.
     * @param int|null
     *          The weekday according to ISO 8601. May be null.
     * @throws \InvalidArgumentException
     */
    public function __construct($year, $week, $dayOfWeek) {
        if ($year === null) {
            throw new \InvalidArgumentException('Year may not be null.');
        }

        if ($week !== null && ($week < 1 || $week > 53)) {
            throw new \InvalidArgumentException('Week must be in the range 1-53.');
        }

        if ($dayOfWeek !== null && $week === null) {
            throw new \InvalidArgumentException('Week may not be null when day of week is specified.');
        }

        if ($dayOfWeek !== null && ($dayOfWeek < 1 || $dayOfWeek > 7)) {
            throw new \InvalidArgumentException('Day of week must be in the range 1-7.');
        }
        $this->year = $year;
        $this->week = $week;
        $this->dayOfWeek = $dayOfWeek;
    }

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

    /**
     * Returns the week. May return null.
     *
     * @return int|null The week or null if week is not defined.
     */
    public function week() {
        return $this->week;
    }

    /**
     * Returns the day of week. May return null.
     *
     * @return int|null The day or null if day is not defined.
     */
    public function dayOfWeek() {
        return $this->dayOfWeek;
    }

    /**
     * @internal
     */
    public function hasDayPrecision() {
        return $this->dayOfWeek != null;
    }

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

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

            if ($this->dayOfWeek !== null) {
                $result .= '-' . $this->dayOfWeek;
            }
        }

        return $result;
    }

    public function toTimePoint(Time $t = null, \DateTimeZone $tz) {
        if ($t === null) {
            $t = new Time(0, 0, 0, null);
        }

        $year = $this->year;
        $week = $this->week !== null ? $this->week : 1;
        $hour = $t->hour();
        $minute = $t->minute();
        if ($minute === null) $minute = 0;
        $second = $t->second();
        if ($second === null) $second = 0;

        if ($t->offset() !== null) {
            $tz = new \DateTimeZone('UTC');
        }

        $dt = new \DateTime($year . '-W' . $week, $tz);
        if ($this->dayOfWeek !== null && $this->dayOfWeek > 1) {
            $dt->modify(($this->dayOfWeek - 1) . ' days');
        }
        $dt->setTime($hour, $minute, $second);
        $offset = $t->offset();
        if ($offset !== null) {
            if ($offset < 0) {
                $dt->add(new \DateInterval('PT' . -$offset . 'M'));
            } else {
                $dt->sub(new \DateInterval('PT' . $offset . 'M'));
            }
        }
        return TimePoint::fromDateTime($dt);
    }

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

        $that = $o;

        if ($this->dayOfWeek !== $that->dayOfWeek) return false;
        if ($this->week !== null ? $this->week !== $that->week : $that->week !== null) return false;
        if ($this->year !== null ? $this->year !== $that->year : $that->year !== null) return false;

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