├── Domain └── Model │ ├── DateTime │ ├── Unit │ │ ├── Year.php │ │ ├── Day.php │ │ ├── Hour.php │ │ ├── Month.php │ │ ├── Minute.php │ │ └── Second.php │ ├── Point │ │ ├── Fixed │ │ │ ├── FixedPoint.php │ │ │ ├── DateOfYear.php │ │ │ └── TimeOfDay.php │ │ ├── Point.php │ │ └── Calendar │ │ │ ├── CalendarDate.php │ │ │ ├── DateTimeOfDay.php │ │ │ └── Date.php │ ├── Test │ │ ├── RecurringInterval │ │ │ └── RecurringIntervalTest.php │ │ ├── Point │ │ │ ├── Fixed │ │ │ │ ├── DateOfYearTest.php │ │ │ │ └── TimeOfDayTest.php │ │ │ └── Calendar │ │ │ │ ├── DateTimeOfDayTest.php │ │ │ │ └── DateTest.php │ │ ├── Interval │ │ │ └── IntervalTest.php │ │ └── Duration │ │ │ └── DurationTest.php │ ├── Interval │ │ ├── DateInterval.php │ │ ├── DateTimeOfDayInterval.php │ │ └── Interval.php │ ├── Duration │ │ └── Duration.php │ └── RecurringInterval │ │ └── RecurringInterval.php │ ├── Id │ ├── IntegerId.php │ ├── StringId.php │ ├── UuidId.php │ └── DefaultId.php │ └── Email │ ├── Test │ └── EmailTest.php │ └── Email.php ├── Infrastructure └── Persistence │ └── Doctrine │ ├── Embeddable │ └── DateTime │ │ ├── Interval.DateInterval.orm.yml │ │ └── Interval.DateTimeOfDayInterval.orm.yml │ └── Type │ └── DateTime │ ├── DateType.php │ └── DateTimeOfDayType.php ├── readme.md ├── composer.json └── LICENSE /Domain/Model/DateTime/Unit/Year.php: -------------------------------------------------------------------------------- 1 | =5.5", 24 | "zelenin/ddd-core": "~0.2.0" 25 | }, 26 | "autoload": { 27 | "psr-4": { 28 | "Zelenin\\Ddd\\ValueObject\\": "" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Point/Point.php: -------------------------------------------------------------------------------- 1 | toIso8601Format(), $iso8601); 20 | } 21 | 22 | /** 23 | * @return array 24 | */ 25 | public function validProvider() 26 | { 27 | return [ 28 | [Date::create(2015, 6, 15), Duration::create(0, 0, 2, 0, 0, 0), 5, 'R5/2015-06-15T00:00:00Z/P2D'] 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Aleksandr Zelenin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Point/Calendar/CalendarDate.php: -------------------------------------------------------------------------------- 1 | id = $id; 23 | } 24 | 25 | /** 26 | * @param mixed $id 27 | * 28 | * @return static 29 | */ 30 | public static function create($id) 31 | { 32 | return new static($id); 33 | } 34 | 35 | /** 36 | * @return mixed 37 | */ 38 | public function id() 39 | { 40 | return $this->id; 41 | } 42 | 43 | /** 44 | * @return mixed 45 | */ 46 | public function __toString() 47 | { 48 | return $this->id(); 49 | } 50 | 51 | /** 52 | * @param DefaultId $object 53 | * 54 | * @return bool 55 | */ 56 | public function equalsTo(Object $object) 57 | { 58 | if (!$this->sameTypeAs($object)) { 59 | throw new NotMatchTypeException($this); 60 | } 61 | 62 | return $this->id() === $object->id(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Infrastructure/Persistence/Doctrine/Type/DateTime/DateType.php: -------------------------------------------------------------------------------- 1 | getDateTypeDeclarationSQL($fieldDeclaration); 25 | } 26 | 27 | /** 28 | * @param string $value 29 | * @param AbstractPlatform $platform 30 | * 31 | * @return Date 32 | */ 33 | public function convertToPHPValue($value, AbstractPlatform $platform) 34 | { 35 | return Date::createFromString($value); 36 | } 37 | 38 | /** 39 | * @param Date $value 40 | * @param AbstractPlatform $platform 41 | * 42 | * @return string 43 | */ 44 | public function convertToDatabaseValue($value, AbstractPlatform $platform) 45 | { 46 | if ($value instanceof Date) { 47 | return $value->toDateTime()->format($platform->getDateFormatString()); 48 | } 49 | return parent::convertToDatabaseValue($value, $platform); 50 | } 51 | 52 | /** 53 | * @return string 54 | */ 55 | public function getName() 56 | { 57 | return static::NAME; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Domain/Model/Email/Test/EmailTest.php: -------------------------------------------------------------------------------- 1 | email() === $email); 17 | } 18 | 19 | /** 20 | * @dataProvider validEmails 21 | */ 22 | public function testPartsOfEmails($email, $name, $domain) 23 | { 24 | $object = Email::create($email); 25 | static::assertEquals($object->name(), $name); 26 | static::assertEquals($object->domain(), $domain); 27 | } 28 | 29 | /** 30 | * @dataProvider notValidEmails 31 | * @expectedException InvalidArgumentException 32 | */ 33 | public function testNotValidEmails($email) 34 | { 35 | Email::create($email); 36 | } 37 | 38 | /** 39 | * @return array 40 | */ 41 | public static function validEmails() 42 | { 43 | return [ 44 | ['name@domain.com', 'name', 'domain.com'], 45 | ['name@domain', 'name', 'domain'], 46 | ['имя@домен', 'имя', 'домен'], 47 | ['site+site@192.168.1.2', 'site+site', '192.168.1.2'], 48 | ['name@local', 'name', 'local'] 49 | ]; 50 | } 51 | 52 | /** 53 | * @return array 54 | */ 55 | public static function notValidEmails() 56 | { 57 | return [ 58 | ['name(at)domain.com'], 59 | ['namedomain'], 60 | ['имядомен'] 61 | ]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Infrastructure/Persistence/Doctrine/Type/DateTime/DateTimeOfDayType.php: -------------------------------------------------------------------------------- 1 | getDateTimeTypeDeclarationSQL($fieldDeclaration); 25 | } 26 | 27 | /** 28 | * @param string $value 29 | * @param AbstractPlatform $platform 30 | * 31 | * @return DateTimeOfDay 32 | */ 33 | public function convertToPHPValue($value, AbstractPlatform $platform) 34 | { 35 | return DateTimeOfDay::createFromString($value); 36 | } 37 | 38 | /** 39 | * @param DateTimeOfDay $value 40 | * @param AbstractPlatform $platform 41 | * 42 | * @return string 43 | */ 44 | public function convertToDatabaseValue($value, AbstractPlatform $platform) 45 | { 46 | if ($value instanceof DateTimeOfDay) { 47 | return $value->toDateTime()->format($platform->getDateTimeFormatString()); 48 | } 49 | return parent::convertToDatabaseValue($value, $platform); 50 | } 51 | 52 | /** 53 | * @return string 54 | */ 55 | public function getName() 56 | { 57 | return static::NAME; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Interval/DateInterval.php: -------------------------------------------------------------------------------- 1 | add($duration)); 48 | } 49 | 50 | /** 51 | * @param Date $end 52 | * @param Duration $duration 53 | * 54 | * @return static 55 | */ 56 | public static function createFromEndAndDuration(Date $end, Duration $duration) 57 | { 58 | return static::create($end->sub($duration), $end); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Domain/Model/Email/Email.php: -------------------------------------------------------------------------------- 1 | email = $email; 27 | } 28 | 29 | /** 30 | * @param string $email 31 | * 32 | * @return static 33 | */ 34 | public static function create($email) 35 | { 36 | return new static($email); 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function email() 43 | { 44 | return $this->email; 45 | } 46 | 47 | /** 48 | * @return string 49 | */ 50 | public function name() 51 | { 52 | $parts = explode('@', $this->email()); 53 | array_pop($parts); 54 | return implode('@', $parts); 55 | } 56 | 57 | /** 58 | * @return string 59 | */ 60 | public function domain() 61 | { 62 | $parts = explode('@', $this->email()); 63 | return array_pop($parts); 64 | } 65 | 66 | /** 67 | * @param static $object 68 | * 69 | * @return bool 70 | */ 71 | public function equalsTo(Object $object) 72 | { 73 | if (!$this->sameTypeAs($object)) { 74 | throw new NotMatchTypeException($this); 75 | } 76 | 77 | return $this->email() === $object->email(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Interval/DateTimeOfDayInterval.php: -------------------------------------------------------------------------------- 1 | add($duration)); 48 | } 49 | 50 | /** 51 | * @param DateTimeOfDay $end 52 | * @param Duration $duration 53 | * 54 | * @return static 55 | */ 56 | public static function createFromEndAndDuration(DateTimeOfDay $end, Duration $duration) 57 | { 58 | return static::create($end->sub($duration), $end); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Interval/Interval.php: -------------------------------------------------------------------------------- 1 | sameTypeAs($start)) { 32 | throw new NotMatchTypeException($end); 33 | } 34 | 35 | if ($end->earlierThan($start)) { 36 | throw new InvalidArgumentException(sprintf('%s must be later then %s', '$end', '$start')); 37 | } 38 | 39 | $this->start = $start; 40 | $this->end = $end; 41 | } 42 | 43 | /** 44 | * @return CalendarDate 45 | */ 46 | public function start() 47 | { 48 | return $this->start; 49 | } 50 | 51 | /** 52 | * @return CalendarDate 53 | */ 54 | public function end() 55 | { 56 | return $this->end; 57 | } 58 | 59 | /** 60 | * @return Duration 61 | */ 62 | public function duration() 63 | { 64 | return Duration::createFromDateInterval($this->start()->toDateTime()->diff($this->end()->toDateTime())); 65 | } 66 | 67 | /** 68 | * @return string 69 | */ 70 | public function toIso8601Format() 71 | { 72 | return $this->start()->toIso8601Format() . '/' . $this->end()->toIso8601Format(); 73 | } 74 | 75 | /** 76 | * @param static $object 77 | * 78 | * @return bool 79 | */ 80 | public function equalsTo(Object $object) 81 | { 82 | if (!$this->sameTypeAs($object)) { 83 | throw new NotMatchTypeException($this); 84 | } 85 | 86 | return $this->start()->equalsTo($object->start()) && $this->end()->equalsTo($object->end()); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Test/Point/Fixed/DateOfYearTest.php: -------------------------------------------------------------------------------- 1 | month()); 16 | static::assertEquals(2, $object->day()); 17 | 18 | $object = DateOfYear::createFromDateTime(new DateTime('1 february')); 19 | 20 | static::assertEquals(2, $object->month()); 21 | static::assertEquals(1, $object->day()); 22 | 23 | $object = DateOfYear::createFromString('1 march'); 24 | 25 | static::assertEquals(3, $object->month()); 26 | static::assertEquals(1, $object->day()); 27 | } 28 | 29 | public function testEqualsTo() 30 | { 31 | $object1 = DateOfYear::create(2, 1); 32 | $object2 = DateOfYear::createFromDateTime(new DateTime('1 february')); 33 | 34 | static::assertTrue($object1->equalsTo($object2)); 35 | 36 | $object1 = DateOfYear::create(2, 1); 37 | $object2 = DateOfYear::createFromDateTime(new DateTime('1 march')); 38 | 39 | static::assertFalse($object1->equalsTo($object2)); 40 | } 41 | 42 | public function testLaterThan() 43 | { 44 | $object1 = DateOfYear::create(3, 1); 45 | $object2 = DateOfYear::createFromDateTime(new DateTime('1 february')); 46 | 47 | static::assertTrue($object1->laterThan($object2)); 48 | 49 | $object1 = DateOfYear::create(2, 1); 50 | $object2 = DateOfYear::createFromDateTime(new DateTime('1 february')); 51 | 52 | static::assertFalse($object1->laterThan($object2)); 53 | 54 | $object1 = DateOfYear::create(1, 1); 55 | $object2 = DateOfYear::createFromDateTime(new DateTime('1 february')); 56 | 57 | static::assertFalse($object1->laterThan($object2)); 58 | } 59 | 60 | public function testEarlierThan() 61 | { 62 | $object1 = DateOfYear::create(3, 1); 63 | $object2 = DateOfYear::createFromDateTime(new DateTime('1 february')); 64 | 65 | static::assertFalse($object1->earlierThan($object2)); 66 | 67 | $object1 = DateOfYear::create(2, 1); 68 | $object2 = DateOfYear::createFromDateTime(new DateTime('1 february')); 69 | 70 | static::assertFalse($object1->earlierThan($object2)); 71 | 72 | $object1 = DateOfYear::create(1, 1); 73 | $object2 = DateOfYear::createFromDateTime(new DateTime('1 february')); 74 | 75 | static::assertTrue($object1->earlierThan($object2)); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Test/Interval/IntervalTest.php: -------------------------------------------------------------------------------- 1 | duration()->year(), $duration->year()); 36 | static::assertEquals($object->duration()->month(), $duration->month()); 37 | static::assertEquals($object->duration()->day(), $duration->day()); 38 | static::assertEquals($object->duration()->hour(), $duration->hour()); 39 | static::assertEquals($object->duration()->minute(), $duration->minute()); 40 | static::assertEquals($object->duration()->second(), $duration->second()); 41 | 42 | if ($iso8601) { 43 | static::assertEquals($object->toIso8601Format(), $iso8601); 44 | } 45 | } 46 | 47 | public function validProvider() 48 | { 49 | return [ 50 | [Date::create(2015, 6, 15), Date::create(2015, 6, 17), Duration::create(0, 0, 2, 0, 0, 0), '2015-06-15T00:00:00/2015-06-17T00:00:00'], 51 | [DateTimeOfDay::create(Date::create(2012, 6, 17), TimeOfDay::create(23, 1, 0)), DateTimeOfDay::create(Date::create(2015, 6, 17), TimeOfDay::create(23, 2, 0)), Duration::create(3, 0, 0, 0, 1, 0)], 52 | [Date::create(2015, 6, 15), Duration::create(0, 1, 5, 0, 0, 0), Duration::create(0, 1, 5, 0, 0, 0)], 53 | [Duration::create(0, 5, 12, 0, 0, 0), Date::create(2015, 6, 17), Duration::create(0, 5, 12, 0, 0, 0), '2015-01-05T00:00:00/2015-06-17T00:00:00'] 54 | ]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Test/Point/Fixed/TimeOfDayTest.php: -------------------------------------------------------------------------------- 1 | hour()); 16 | static::assertEquals(2, $object->minute()); 17 | static::assertEquals(5, $object->second()); 18 | 19 | $object = TimeOfDay::createFromDateTime(new DateTime('10:05:25')); 20 | 21 | static::assertEquals(10, $object->hour()); 22 | static::assertEquals(5, $object->minute()); 23 | static::assertEquals(25, $object->second()); 24 | 25 | $object = TimeOfDay::createFromString('10:05:25'); 26 | 27 | static::assertEquals(10, $object->hour()); 28 | static::assertEquals(5, $object->minute()); 29 | static::assertEquals(25, $object->second()); 30 | } 31 | 32 | public function testEqualsTo() 33 | { 34 | $object1 = TimeOfDay::create(10, 2, 5); 35 | $object2 = TimeOfDay::createFromDateTime(new DateTime('10:02:05')); 36 | 37 | static::assertTrue($object1->equalsTo($object2)); 38 | 39 | $object1 = TimeOfDay::create(10, 2, 4); 40 | $object2 = TimeOfDay::createFromDateTime(new DateTime('10:02:05')); 41 | 42 | static::assertFalse($object1->equalsTo($object2)); 43 | } 44 | 45 | public function testLaterThan() 46 | { 47 | $object1 = TimeOfDay::create(10, 2, 6); 48 | $object2 = TimeOfDay::createFromDateTime(new DateTime('10:02:05')); 49 | 50 | static::assertTrue($object1->laterThan($object2)); 51 | 52 | $object1 = TimeOfDay::create(10, 2, 5); 53 | $object2 = TimeOfDay::createFromDateTime(new DateTime('10:02:05')); 54 | 55 | static::assertFalse($object1->laterThan($object2)); 56 | 57 | $object1 = TimeOfDay::create(10, 2, 4); 58 | $object2 = TimeOfDay::createFromDateTime(new DateTime('10:02:05')); 59 | 60 | static::assertFalse($object1->laterThan($object2)); 61 | } 62 | 63 | public function testEarlierThan() 64 | { 65 | $object1 = TimeOfDay::create(10, 2, 6); 66 | $object2 = TimeOfDay::createFromDateTime(new DateTime('10:02:05')); 67 | 68 | static::assertFalse($object1->earlierThan($object2)); 69 | 70 | $object1 = TimeOfDay::create(10, 2, 5); 71 | $object2 = TimeOfDay::createFromDateTime(new DateTime('10:02:05')); 72 | 73 | static::assertFalse($object1->earlierThan($object2)); 74 | 75 | $object1 = TimeOfDay::create(10, 2, 4); 76 | $object2 = TimeOfDay::createFromDateTime(new DateTime('10:02:05')); 77 | 78 | static::assertTrue($object1->earlierThan($object2)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Test/Point/Calendar/DateTimeOfDayTest.php: -------------------------------------------------------------------------------- 1 | year()); 18 | static::assertEquals(10, $object->month()); 19 | static::assertEquals(11, $object->day()); 20 | static::assertEquals(15, $object->hour()); 21 | static::assertEquals(12, $object->minute()); 22 | static::assertEquals(13, $object->second()); 23 | 24 | static::assertInstanceOf(DateTime::class, $object->toDateTime()); 25 | } 26 | 27 | public function testEqualsTo() 28 | { 29 | $object1 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 30 | $object2 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 31 | 32 | static::assertTrue($object1->equalsTo($object2)); 33 | 34 | $object1 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 11, 13)); 35 | $object2 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 36 | 37 | static::assertFalse($object1->equalsTo($object2)); 38 | } 39 | 40 | public function testLaterThan() 41 | { 42 | $object1 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 13, 13)); 43 | $object2 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 44 | 45 | static::assertTrue($object1->laterThan($object2)); 46 | 47 | $object1 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 48 | $object2 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 49 | 50 | static::assertFalse($object1->laterThan($object2)); 51 | 52 | $object1 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 11, 13)); 53 | $object2 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 54 | 55 | static::assertFalse($object1->laterThan($object2)); 56 | } 57 | 58 | public function testEarlierThan() 59 | { 60 | $object1 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 13, 13)); 61 | $object2 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 62 | 63 | static::assertFalse($object1->earlierThan($object2)); 64 | 65 | $object1 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 66 | $object2 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 67 | 68 | static::assertFalse($object1->earlierThan($object2)); 69 | 70 | $object1 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 11, 13)); 71 | $object2 = DateTimeOfDay::create(Date::create(2005, 10, 11), TimeOfDay::create(15, 12, 13)); 72 | 73 | static::assertTrue($object1->earlierThan($object2)); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Test/Point/Calendar/DateTest.php: -------------------------------------------------------------------------------- 1 | year()); 19 | static::assertEquals($month, $object->month()); 20 | static::assertEquals($day, $object->day()); 21 | 22 | static::assertInstanceOf(DateTime::class, $object->toDateTime()); 23 | } 24 | 25 | /** 26 | * @dataProvider notValidProvider 27 | * @expectedException \Zelenin\Ddd\Core\Domain\Exception\InvalidArgumentException 28 | */ 29 | public function testNotValid($year, $month, $day) 30 | { 31 | Date::create($year, $month, $day); 32 | } 33 | 34 | public function testEqualsTo() 35 | { 36 | $object1 = Date::create(2005, 2, 11); 37 | $object2 = Date::createFromDateTime(new DateTime('2005-02-11')); 38 | 39 | static::assertTrue($object1->equalsTo($object2)); 40 | 41 | $object1 = Date::create(2005, 2, 11); 42 | $object2 = Date::createFromDateTime(new DateTime('2005-03-11')); 43 | 44 | static::assertFalse($object1->equalsTo($object2)); 45 | } 46 | 47 | public function testLaterThan() 48 | { 49 | $object1 = Date::create(2005, 3, 11); 50 | $object2 = Date::createFromDateTime(new DateTime('2005-02-11')); 51 | 52 | static::assertTrue($object1->laterThan($object2)); 53 | 54 | $object1 = Date::create(2005, 2, 11); 55 | $object2 = Date::createFromDateTime(new DateTime('2005-02-11')); 56 | 57 | static::assertFalse($object1->laterThan($object2)); 58 | 59 | $object1 = Date::create(2005, 1, 11); 60 | $object2 = Date::createFromDateTime(new DateTime('2005-02-11')); 61 | 62 | static::assertFalse($object1->laterThan($object2)); 63 | } 64 | 65 | public function testEarlierThan() 66 | { 67 | $object1 = Date::create(2005, 3, 11); 68 | $object2 = Date::createFromDateTime(new DateTime('2005-02-11')); 69 | 70 | static::assertFalse($object1->earlierThan($object2)); 71 | 72 | $object1 = Date::create(2005, 2, 11); 73 | $object2 = Date::createFromDateTime(new DateTime('2005-02-11')); 74 | 75 | static::assertFalse($object1->earlierThan($object2)); 76 | 77 | $object1 = Date::create(2005, 1, 11); 78 | $object2 = Date::createFromDateTime(new DateTime('2005-02-11')); 79 | 80 | static::assertTrue($object1->earlierThan($object2)); 81 | } 82 | 83 | public function validProvider() 84 | { 85 | return [ 86 | [2005, 1, 1], 87 | [2005, 6, 24], 88 | [2011, 12, 1], 89 | [-56, 2, 15] 90 | ]; 91 | } 92 | 93 | public function notValidProvider() 94 | { 95 | return [ 96 | [2005, 13, 10], 97 | [2005, 0, 11], 98 | [2005, 5, 35], 99 | [2005, 5, 0], 100 | [2005, 2, 32], 101 | ['2005', 2, 1], 102 | [2005, '2', 1], 103 | [2005, 2, '1'], 104 | ]; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Test/Duration/DurationTest.php: -------------------------------------------------------------------------------- 1 | year()); 20 | static::assertEquals($month, $object->month()); 21 | static::assertEquals($day, $object->day()); 22 | static::assertEquals($hour, $object->hour()); 23 | static::assertEquals($minute, $object->minute()); 24 | static::assertEquals($second, $object->second()); 25 | 26 | static::assertInstanceOf(DateInterval::class, $object->toDateInterval()); 27 | static::assertEquals($iso8601format, $object->toIso8601Format()); 28 | 29 | Duration::createFromDateInterval($object->toDateInterval()); 30 | Duration::createFromString($object->toIso8601Format()); 31 | } 32 | 33 | /** 34 | * @dataProvider notValidProvider 35 | * @expectedException \Zelenin\Ddd\Core\Domain\Exception\InvalidArgumentException 36 | */ 37 | public function testNotValid($year, $month, $day, $hour, $minute, $second, $iso8601format) 38 | { 39 | Duration::create($year, $month, $day, $hour, $minute, $second); 40 | } 41 | 42 | /** 43 | * @dataProvider validProvider 44 | */ 45 | public function testEquals($year, $month, $day, $hour, $minute, $second, $iso8601format) 46 | { 47 | $object1 = Duration::create($year, $month, $day, $hour, $minute, $second); 48 | $object2 = Duration::create($year, $month, $day, $hour, $minute, $second); 49 | 50 | static::assertTrue($object1->equalsTo($object2)); 51 | } 52 | 53 | /** 54 | * @dataProvider validProvider 55 | */ 56 | public function testNotEquals($year, $month, $day, $hour, $minute, $second, $iso8601format) 57 | { 58 | $object1 = Duration::create($year, $month, $day, $hour, $minute, $second); 59 | $object2 = Duration::create($year, $month, $day, $hour, $minute, $second + 1); 60 | 61 | static::assertFalse($object1->equalsTo($object2)); 62 | } 63 | 64 | /** 65 | * @dataProvider validProvider 66 | * @expectedException \Zelenin\Ddd\Core\Domain\Exception\NotMatchTypeException 67 | */ 68 | public function testEqualsNotSameType($year, $month, $day, $hour, $minute, $second, $iso8601format) 69 | { 70 | $object1 = Duration::create($year, $month, $day, $hour, $minute, $second); 71 | $object2 = Date::create(1, 1, 1); 72 | 73 | $object1->equalsTo($object2); 74 | } 75 | 76 | public function validProvider() 77 | { 78 | return [ 79 | [1, 2, 3, 4, 5, 6, 'P1Y2M3DT4H5M6S'], 80 | [1, 0, 0, 4, 5, 6, 'P1YT4H5M6S'], 81 | [0, 0, 0, 0, 0, 6, 'PT6S'], 82 | [0, 1, 0, 0, 0, 0, 'P1M'] 83 | ]; 84 | } 85 | 86 | public function notValidProvider() 87 | { 88 | return [ 89 | ['1', 2, 3, 4, 5, 6, 'P1Y2M3DT4H5M6S'], 90 | [1, '2', 3, 4, 5, 6, 'P1Y2M3DT4H5M6S'], 91 | [1, 2, '3', 4, 5, 6, 'P1Y2M3DT4H5M6S'], 92 | [1, 2, 3, '4', 5, 6, 'P1Y2M3DT4H5M6S'], 93 | [1, 2, 3, 4, '5', 6, 'P1Y2M3DT4H5M6S'], 94 | [1, 2, 3, 4, 5, '6', 'P1Y2M3DT4H5M6S'], 95 | ]; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Point/Fixed/DateOfYear.php: -------------------------------------------------------------------------------- 1 | Month::max()) { 40 | throw new InvalidArgumentException(sprintf('%s should be in range %d-%d', '$month', Month::min(), Month::max())); 41 | } 42 | if ($day < Day::min() || $day > Day::max()) { 43 | throw new InvalidArgumentException(sprintf('%s should be in range %d-%d', '$day', Day::min(), Day::max())); 44 | } 45 | 46 | $this->month = $month; 47 | $this->day = $day; 48 | } 49 | 50 | /** 51 | * @param int $month 52 | * @param int $day 53 | * 54 | * @return static 55 | */ 56 | public static function create($month, $day) 57 | { 58 | return new static($month, $day); 59 | } 60 | 61 | /** 62 | * @param DateTimeInterface $dateTime 63 | * 64 | * @return static 65 | */ 66 | public static function createFromDateTime(DateTimeInterface $dateTime) 67 | { 68 | return static::create((int)$dateTime->format('m'), (int)$dateTime->format('d')); 69 | } 70 | 71 | /** 72 | * @param string $date 73 | * 74 | * @return static 75 | */ 76 | public static function createFromString($date) 77 | { 78 | return static::createFromDateTime(new DateTimeImmutable($date)); 79 | } 80 | 81 | /** 82 | * @return int 83 | */ 84 | public function month() 85 | { 86 | return $this->month; 87 | } 88 | 89 | /** 90 | * @return int 91 | */ 92 | public function day() 93 | { 94 | return $this->day; 95 | } 96 | 97 | /** 98 | * @param DateOfYear $object 99 | * 100 | * @return bool 101 | */ 102 | public function equalsTo(Object $object) 103 | { 104 | if (!$this->sameTypeAs($object)) { 105 | throw new NotMatchTypeException($this); 106 | } 107 | 108 | return $this->month() === $object->month() && $this->day() === $object->day(); 109 | } 110 | 111 | /** 112 | * @param DateOfYear $object 113 | * 114 | * @return bool 115 | */ 116 | public function laterThan($object) 117 | { 118 | if (!$this->sameTypeAs($object)) { 119 | throw new NotMatchTypeException($this); 120 | } 121 | 122 | return 123 | ($this->month() > $object->month()) || 124 | ($this->month() >= $object->month() && $this->day() > $object->day()); 125 | } 126 | 127 | /** 128 | * @param DateOfYear $object 129 | * 130 | * @return bool 131 | */ 132 | public function earlierThan($object) 133 | { 134 | if (!$this->sameTypeAs($object)) { 135 | throw new NotMatchTypeException($this); 136 | } 137 | 138 | return $this->equalsTo($object) === false && $this->laterThan($object) === false; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Point/Fixed/TimeOfDay.php: -------------------------------------------------------------------------------- 1 | Hour::max()) { 50 | throw new InvalidArgumentException(sprintf('%s should be in range %d-%d', '$hour', Hour::min(), Hour::max())); 51 | } 52 | if ($minute < Minute::min() || $minute > Minute::max()) { 53 | throw new InvalidArgumentException(sprintf('%s should be in range %d-%d', '$minute', Minute::min(), Minute::max())); 54 | } 55 | if ($second < Second::min() || $second > Second::max()) { 56 | throw new InvalidArgumentException(sprintf('%s should be in range %d-%d', '$second', Second::min(), Second::max())); 57 | } 58 | 59 | $this->hour = $hour; 60 | $this->minute = $minute; 61 | $this->second = $second; 62 | } 63 | 64 | /** 65 | * @param $hour 66 | * @param $minute 67 | * @param $second 68 | * 69 | * @return self 70 | */ 71 | public static function create($hour, $minute, $second) 72 | { 73 | return new static($hour, $minute, $second); 74 | } 75 | 76 | /** 77 | * @param DateTimeInterface $dateTime 78 | * 79 | * @return self 80 | */ 81 | public static function createFromDateTime(DateTimeInterface $dateTime) 82 | { 83 | return static::create((int)$dateTime->format('H'), (int)$dateTime->format('i'), (int)$dateTime->format('s')); 84 | } 85 | 86 | /** 87 | * @param string $date 88 | * 89 | * @return self 90 | */ 91 | public static function createFromString($date) 92 | { 93 | return static::createFromDateTime(new DateTimeImmutable($date)); 94 | } 95 | 96 | /** 97 | * @return self 98 | */ 99 | public static function now() 100 | { 101 | return static::createFromDateTime(new DateTimeImmutable()); 102 | } 103 | 104 | /** 105 | * @return int 106 | */ 107 | public function hour() 108 | { 109 | return $this->hour; 110 | } 111 | 112 | /** 113 | * @return int 114 | */ 115 | public function minute() 116 | { 117 | return $this->minute; 118 | } 119 | 120 | /** 121 | * @return int 122 | */ 123 | public function second() 124 | { 125 | return $this->second; 126 | } 127 | 128 | /** 129 | * @return string 130 | */ 131 | public function toIso8601Format() 132 | { 133 | return sprintf('%02d:%02d:%02d', $this->hour(), $this->minute(), $this->second()); 134 | } 135 | 136 | /** 137 | * @param TimeOfDay $object 138 | * 139 | * @return bool 140 | */ 141 | public function equalsTo(Object $object) 142 | { 143 | if (!$this->sameTypeAs($object)) { 144 | throw new NotMatchTypeException($this); 145 | } 146 | 147 | return 148 | $this->hour() === $object->hour() && 149 | $this->minute() === $object->minute() && 150 | $this->second() === $object->second(); 151 | } 152 | 153 | /** 154 | * @param TimeOfDay $object 155 | * 156 | * @return bool 157 | */ 158 | public function laterThan($object) 159 | { 160 | if (!$this->sameTypeAs($object)) { 161 | throw new NotMatchTypeException($this); 162 | } 163 | 164 | return ($this->hour() > $object->hour()) || 165 | ($this->hour() >= $object->hour() && $this->minute() > $object->minute()) || 166 | ($this->hour() >= $object->hour() && $this->minute() >= $object->minute() && $this->second() > $object->second()); 167 | } 168 | 169 | /** 170 | * @param TimeOfDay $object 171 | * 172 | * @return bool 173 | */ 174 | public function earlierThan($object) 175 | { 176 | if (!$this->sameTypeAs($object)) { 177 | throw new NotMatchTypeException($this); 178 | } 179 | 180 | return $this->equalsTo($object) === false && $this->laterThan($object) === false; 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Point/Calendar/DateTimeOfDay.php: -------------------------------------------------------------------------------- 1 | date = $date; 33 | $this->time = $time; 34 | } 35 | 36 | /** 37 | * @param Date $date 38 | * @param TimeOfDay $time 39 | * 40 | * @return self 41 | */ 42 | public static function create(Date $date, TimeOfDay $time) 43 | { 44 | return new static($date, $time); 45 | } 46 | 47 | /** 48 | * @param DateTimeInterface $dateTime 49 | * 50 | * @return self 51 | */ 52 | public static function createFromDateTime(DateTimeInterface $dateTime) 53 | { 54 | return static::create(Date::createFromDateTime($dateTime), TimeOfDay::createFromDateTime($dateTime)); 55 | } 56 | 57 | /** 58 | * @param string $date 59 | * 60 | * @return self 61 | */ 62 | public static function createFromString($date) 63 | { 64 | return static::createFromDateTime(new DateTimeImmutable($date)); 65 | } 66 | 67 | /** 68 | * @return self 69 | */ 70 | public static function now() 71 | { 72 | return static::createFromDateTime(new DateTimeImmutable()); 73 | } 74 | 75 | /** 76 | * @return Date 77 | */ 78 | public function date() 79 | { 80 | return $this->date; 81 | } 82 | 83 | /** 84 | * @return TimeOfDay 85 | */ 86 | public function time() 87 | { 88 | return $this->time; 89 | } 90 | 91 | /** 92 | * @return int 93 | */ 94 | public function year() 95 | { 96 | return $this->date()->year(); 97 | } 98 | 99 | /** 100 | * @return int 101 | */ 102 | public function month() 103 | { 104 | return $this->date()->month(); 105 | } 106 | 107 | /** 108 | * @return int 109 | */ 110 | public function day() 111 | { 112 | return $this->date()->day(); 113 | } 114 | 115 | /** 116 | * @return int 117 | */ 118 | public function hour() 119 | { 120 | return $this->time()->hour(); 121 | } 122 | 123 | /** 124 | * @return int 125 | */ 126 | public function minute() 127 | { 128 | return $this->time()->minute(); 129 | } 130 | 131 | /** 132 | * @return int 133 | */ 134 | public function second() 135 | { 136 | return $this->time()->second(); 137 | } 138 | 139 | /** 140 | * @return DateTime 141 | */ 142 | public function toDateTime() 143 | { 144 | $dateTime = new DateTime(); 145 | $dateTime->setDate($this->year(), $this->month(), $this->day()); 146 | $dateTime->setTime($this->hour(), $this->minute(), $this->second()); 147 | 148 | return $dateTime; 149 | } 150 | 151 | /** 152 | * @return string 153 | */ 154 | public function toIso8601Format() 155 | { 156 | return $this->toDateTime()->format('Y-m-d\TH:i:s'); 157 | } 158 | 159 | /** 160 | * @param DateTimeOfDay $object 161 | * 162 | * @return bool 163 | */ 164 | public function equalsTo(Object $object) 165 | { 166 | if (!$this->sameTypeAs($object)) { 167 | throw new NotMatchTypeException($this); 168 | } 169 | 170 | return $this->date()->equalsTo($object->date()) && $this->time()->equalsTo($object->time()); 171 | } 172 | 173 | /** 174 | * @param DateTimeOfDay $object 175 | * 176 | * @return bool 177 | */ 178 | public function earlierThan($object) 179 | { 180 | if (!$this->sameTypeAs($object)) { 181 | throw new NotMatchTypeException($this); 182 | } 183 | 184 | return $this->date()->earlierThan($object->date()) || ($this->date()->equalsTo($object->date()) && $this->time()->earlierThan($object->time())); 185 | } 186 | 187 | /** 188 | * @param DateTimeOfDay $object 189 | * 190 | * @return bool 191 | */ 192 | public function laterThan($object) 193 | { 194 | if (!$this->sameTypeAs($object)) { 195 | throw new NotMatchTypeException($this); 196 | } 197 | 198 | return $this->date()->laterThan($object->date()) || ($this->date()->equalsTo($object->date()) && $this->time()->laterThan($object->time())); 199 | } 200 | 201 | /** 202 | * @param Duration $duration 203 | * 204 | * @return self 205 | */ 206 | public function add(Duration $duration) 207 | { 208 | return static::createFromDateTime($this->toDateTime()->add($duration->toDateInterval())); 209 | } 210 | 211 | /** 212 | * @param Duration $duration 213 | * 214 | * @return self 215 | */ 216 | public function sub(Duration $duration) 217 | { 218 | return static::createFromDateTime($this->toDateTime()->sub($duration->toDateInterval())); 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Duration/Duration.php: -------------------------------------------------------------------------------- 1 | year = $year; 73 | $this->month = $month; 74 | $this->day = $day; 75 | $this->hour = $hour; 76 | $this->minute = $minute; 77 | $this->second = $second; 78 | } 79 | 80 | /** 81 | * @param int $year 82 | * @param int $month 83 | * @param int $day 84 | * @param int $hour 85 | * @param int $minute 86 | * @param int $second 87 | * 88 | * @return static 89 | */ 90 | public static function create($year, $month, $day, $hour, $minute, $second) 91 | { 92 | return new static($year, $month, $day, $hour, $minute, $second); 93 | } 94 | 95 | /** 96 | * @param DateInterval $dateInterval 97 | * 98 | * @return static 99 | */ 100 | public static function createFromDateInterval(DateInterval $dateInterval) 101 | { 102 | return static::create((int)$dateInterval->format('%y'), (int)$dateInterval->format('%m'), (int)$dateInterval->format('%d'), (int)$dateInterval->format('%h'), (int)$dateInterval->format('%i'), (int)$dateInterval->format('%s')); 103 | } 104 | 105 | /** 106 | * @param $string 107 | * 108 | * @return static 109 | */ 110 | public static function createFromString($string) 111 | { 112 | return static::createFromDateInterval(new DateInterval($string)); 113 | } 114 | 115 | /** 116 | * @return int 117 | */ 118 | public function year() 119 | { 120 | return $this->year; 121 | } 122 | 123 | /** 124 | * @return int 125 | */ 126 | public function month() 127 | { 128 | return $this->month; 129 | } 130 | 131 | /** 132 | * @return int 133 | */ 134 | public function day() 135 | { 136 | return $this->day; 137 | } 138 | 139 | /** 140 | * @return int 141 | */ 142 | public function hour() 143 | { 144 | return $this->hour; 145 | } 146 | 147 | /** 148 | * @return int 149 | */ 150 | public function minute() 151 | { 152 | return $this->minute; 153 | } 154 | 155 | /** 156 | * @return int 157 | */ 158 | public function second() 159 | { 160 | return $this->second; 161 | } 162 | 163 | /** 164 | * @return string 165 | */ 166 | public function toIso8601Format() 167 | { 168 | $date = [ 169 | 'Y' => $this->year(), 170 | 'M' => $this->month(), 171 | 'D' => $this->day() 172 | ]; 173 | $time = [ 174 | 'H' => $this->hour(), 175 | 'M' => $this->minute(), 176 | 'S' => $this->second() 177 | ]; 178 | 179 | $date = array_filter(array_map(function ($value, $key) { 180 | return $value ? $value . $key : null; 181 | }, array_values($date), array_keys($date))); 182 | 183 | $time = array_filter(array_map(function ($value, $key) { 184 | return $value ? $value . $key : null; 185 | }, array_values($time), array_keys($time))); 186 | 187 | return 'P' . implode('', $date) . ($time ? 'T' . implode('', $time) : ''); 188 | } 189 | 190 | /** 191 | * @param Duration $object 192 | * 193 | * @return bool 194 | */ 195 | public function equalsTo(Object $object) 196 | { 197 | if (!$this->sameTypeAs($object)) { 198 | throw new NotMatchTypeException($this); 199 | } 200 | 201 | return 202 | $this->year() === $object->year() && 203 | $this->month() === $object->month() && 204 | $this->day() === $object->day() && 205 | $this->hour() === $object->hour() && 206 | $this->minute() === $object->minute() && 207 | $this->second() === $object->second(); 208 | } 209 | 210 | /** 211 | * @return DateInterval 212 | */ 213 | public function toDateInterval() 214 | { 215 | return new DateInterval($this->toIso8601Format()); 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/Point/Calendar/Date.php: -------------------------------------------------------------------------------- 1 | Month::max()) { 51 | throw new InvalidArgumentException(sprintf('%s should be in range %d-%d', '$month', Month::min(), Month::max())); 52 | } 53 | /** 54 | * @todo 02-31 55 | */ 56 | if ($day < Day::min() || $day > Day::max()) { 57 | throw new InvalidArgumentException(sprintf('%s should be in range %d-%d', '$day', Day::min(), Day::max())); 58 | } 59 | 60 | $this->year = $year; 61 | $this->month = $month; 62 | $this->day = $day; 63 | } 64 | 65 | /** 66 | * @param int $year 67 | * @param int $month 68 | * @param int $day 69 | * 70 | * @return self 71 | */ 72 | public static function create($year, $month, $day) 73 | { 74 | return new static($year, $month, $day); 75 | } 76 | 77 | /** 78 | * @param DateTimeInterface $dateTime 79 | * 80 | * @return self 81 | */ 82 | public static function createFromDateTime(DateTimeInterface $dateTime) 83 | { 84 | return static::create((int)$dateTime->format('Y'), (int)$dateTime->format('m'), (int)$dateTime->format('d')); 85 | } 86 | 87 | /** 88 | * @param string $date 89 | * 90 | * @return self 91 | */ 92 | public static function createFromString($date) 93 | { 94 | return static::createFromDateTime(new DateTimeImmutable($date)); 95 | } 96 | 97 | /** 98 | * @return self 99 | */ 100 | public static function now() 101 | { 102 | return static::createFromDateTime(new DateTimeImmutable()); 103 | } 104 | 105 | /** 106 | * @return int 107 | */ 108 | public function year() 109 | { 110 | return $this->year; 111 | } 112 | 113 | /** 114 | * @return int 115 | */ 116 | public function month() 117 | { 118 | return $this->month; 119 | } 120 | 121 | /** 122 | * @return int 123 | */ 124 | public function day() 125 | { 126 | return $this->day; 127 | } 128 | 129 | /** 130 | * @return DateTime 131 | */ 132 | public function toDateTime() 133 | { 134 | $dateTime = new DateTime(); 135 | $dateTime->setDate($this->year(), $this->month(), $this->day()); 136 | $dateTime->setTime(0, 0, 0); 137 | 138 | return $dateTime; 139 | } 140 | 141 | /** 142 | * @return string 143 | */ 144 | public function toIso8601Format() 145 | { 146 | return $this->toDateTime()->format('Y-m-d\TH:i:s'); 147 | } 148 | 149 | /** 150 | * @param Date $object 151 | * 152 | * @return bool 153 | */ 154 | public function equalsTo(Object $object) 155 | { 156 | if (!$this->sameTypeAs($object)) { 157 | throw new NotMatchTypeException($this); 158 | } 159 | 160 | return 161 | $this->year() === $object->year() && 162 | $this->month() === $object->month() && 163 | $this->day() === $object->day(); 164 | } 165 | 166 | /** 167 | * @param Date $object 168 | * 169 | * @return bool 170 | */ 171 | public function laterThan($object) 172 | { 173 | if (!$this->sameTypeAs($object)) { 174 | throw new NotMatchTypeException($this); 175 | } 176 | 177 | return ($this->year() > $object->year()) || 178 | ($this->year() >= $object->year() && $this->month() > $object->month()) || 179 | ($this->year() >= $object->year() && $this->month() >= $object->month() && $this->day() > $object->day()); 180 | } 181 | 182 | /** 183 | * @param Date $object 184 | * 185 | * @return bool 186 | */ 187 | public function earlierThan($object) 188 | { 189 | if (!$this->sameTypeAs($object)) { 190 | throw new NotMatchTypeException($this); 191 | } 192 | 193 | return !$this->equalsTo($object) && !$this->laterThan($object); 194 | } 195 | 196 | /** 197 | * @param Duration $duration 198 | * 199 | * @return self 200 | */ 201 | public function add(Duration $duration) 202 | { 203 | return static::createFromDateTime($this->toDateTime()->add($duration->toDateInterval())); 204 | } 205 | 206 | /** 207 | * @param Duration $duration 208 | * 209 | * @return self 210 | */ 211 | public function sub(Duration $duration) 212 | { 213 | return static::createFromDateTime($this->toDateTime()->sub($duration->toDateInterval())); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /Domain/Model/DateTime/RecurringInterval/RecurringInterval.php: -------------------------------------------------------------------------------- 1 | earlierThan($start)) { 59 | throw new InvalidArgumentException(sprintf('%s must be later then %s', '$end', '$start')); 60 | } 61 | 62 | $this->start = $start; 63 | $this->end = $end; 64 | $this->duration = $duration; 65 | $this->recurrence = $recurrence; 66 | } 67 | 68 | /** 69 | * @param CalendarDate $start 70 | * @param Duration $duration 71 | * @param int|null $recurrence 72 | * 73 | * @return static 74 | */ 75 | public static function create(CalendarDate $start, CalendarDate $end = null, Duration $duration, $recurrence = null) 76 | { 77 | return new static($start, $end, $duration, $recurrence); 78 | } 79 | 80 | /** 81 | * @param CalendarDate $start 82 | * @param CalendarDate $end 83 | * @param int|null $recurrence 84 | * 85 | * @return static 86 | */ 87 | public static function createFromStartEnd(CalendarDate $start, CalendarDate $end, $recurrence = null) 88 | { 89 | return static::create($start, null, Interval::create($start, $end)->duration(), $recurrence); 90 | } 91 | 92 | /** 93 | * @param CalendarDate $start 94 | * @param CalendarDate $end 95 | * @param Duration $duration 96 | * @param null $recurrence 97 | * 98 | * @return static 99 | */ 100 | public static function createFromStartEndDuration(CalendarDate $start, CalendarDate $end, Duration $duration) 101 | { 102 | return static::create($start, $end, $duration, null); 103 | } 104 | 105 | /** 106 | * @param CalendarDate $start 107 | * @param Duration $duration 108 | * @param int|null $recurrence 109 | * 110 | * @return static 111 | */ 112 | public static function createFromStartDuration(CalendarDate $start, Duration $duration, $recurrence = null) 113 | { 114 | return static::create($start, null, $duration, $recurrence); 115 | } 116 | 117 | /** 118 | * @param CalendarDate $end 119 | * @param Duration $duration 120 | * @param int|null $recurrence 121 | * 122 | * @return static 123 | */ 124 | public static function createFromEndDuration(CalendarDate $end, Duration $duration, $recurrence = null) 125 | { 126 | return static::create($end->sub($duration), null, $duration, $recurrence); 127 | } 128 | 129 | /** 130 | * @return CalendarDate 131 | */ 132 | public function start() 133 | { 134 | return $this->start; 135 | } 136 | 137 | /** 138 | * @return CalendarDate 139 | */ 140 | public function end() 141 | { 142 | return $this->end; 143 | } 144 | 145 | /** 146 | * @return Duration 147 | */ 148 | public function duration() 149 | { 150 | return $this->duration; 151 | } 152 | 153 | /** 154 | * @return int|null 155 | */ 156 | public function recurrence() 157 | { 158 | return $this->recurrence; 159 | } 160 | 161 | /** 162 | * @return string 163 | */ 164 | public function toIso8601Format() 165 | { 166 | $data = [ 167 | 'R' . ($this->recurrence() ?: ''), 168 | $this->start()->toIso8601Format() . 'Z', 169 | $this->duration()->toIso8601Format(), 170 | $this->end() ? $this->end()->toIso8601Format() . 'Z' : '' 171 | ]; 172 | return implode('/', array_filter($data)); 173 | } 174 | 175 | /** 176 | * @param static $object 177 | * 178 | * @return bool 179 | */ 180 | public function equalsTo(Object $object) 181 | { 182 | if (!$this->sameTypeAs($object)) { 183 | throw new NotMatchTypeException($this); 184 | } 185 | 186 | return $this->start()->equalsTo($object->start()) && $this->duration()->equalsTo($object->duration()) && $this->recurrence() === $object->recurrence(); 187 | } 188 | 189 | /** 190 | * @return CalendarDate 191 | */ 192 | public function current() 193 | { 194 | if ($this->current === null) { 195 | $this->current = $this->start(); 196 | } 197 | return $this->current; 198 | } 199 | 200 | public function next() 201 | { 202 | $this->current = $this->current()->add($this->duration()); 203 | $this->currentRecurrence++; 204 | } 205 | 206 | /** 207 | * @return int 208 | */ 209 | public function key() 210 | { 211 | return $this->currentRecurrence; 212 | } 213 | 214 | /** 215 | * @return bool 216 | */ 217 | public function valid() 218 | { 219 | return !(($this->end() && $this->current()->laterThan($this->end())) || ($this->recurrence() && $this->currentRecurrence > $this->recurrence())); 220 | } 221 | 222 | public function rewind() 223 | { 224 | $this->current = $this->start(); 225 | $this->currentRecurrence = 0; 226 | } 227 | 228 | /** 229 | * @return CalendarDate[] 230 | */ 231 | public function toArray() 232 | { 233 | return iterator_to_array($this); 234 | } 235 | } 236 | --------------------------------------------------------------------------------