-
Notifications
You must be signed in to change notification settings - Fork 6
/
Recurrent.php
95 lines (84 loc) · 2.1 KB
/
Recurrent.php
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
<?php
/*
Copyright 2014-2019 Ondrej Novy
This file is part of otodo.
otodo is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
otodo is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with otodo. If not, see <http://www.gnu.org/licenses/>.
*/
class Recurrent {
public $fromNow = false;
public $count;
public $unit;
public $businessDay = false;
public function __construct($str) {
$this->fromNow = true;
$str = strval($str);
if ($str[0] == '+') {
$this->fromNow = false;
$str = substr($str, 1);
}
if (!preg_match('/^(\d+)([dwmy]?) ?(b)?$/', $str, $matches)) {
throw new RecurrentParseException($str);
}
$this->count = $matches[1];
if (isset($matches[2]) && $matches[2] != '') {
$this->unit = $matches[2];
} else {
$this->unit = 'd';
}
if (isset($matches[3]) && $matches[3] == 'b') {
$this->businessDay = true;
}
}
public function toString() {
$out = '';
if (!$this->fromNow) {
$out .= '+';
}
$out .= $this->count . $this->unit;
if ($this->businessDay) {
$out .= 'b';
}
return $out;
}
public function recurr($oldTs) {
assert($oldTs instanceof DateTime || $oldTs === null);
if ($this->fromNow || $oldTs === null) {
$ts = new DateTime('today');
} else {
$ts = clone $oldTs;
}
switch ($this->unit) {
case 'd':
$m = 'day';
break;
case 'm':
$m = 'month';
break;
case 'w':
$m = 'week';
break;
case 'y':
$m = 'year';
break;
default:
throw new RecurrentParseException('Unknown unit: ' . $this->unit);
break;
}
$ts->modify('+' . $this->count . ' ' . $m);
if ($this->businessDay) {
while (in_array($ts->format('N'), array(6, 7))) {
$ts->modify('+1day');
}
}
return $ts;
}
}