Completed
Push — master ( 8f5bc0...179bc9 )
by WEBEWEB
03:06
created

DateTimeHelper::getWeekNumberToApply()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.3554
c 0
b 0
f 0
cc 5
nc 3
nop 4
1
<?php
2
3
/**
4
 * This file is part of the core-library package.
5
 *
6
 * (c) 2018 WEBEWEB
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace WBW\Library\Core\Argument;
13
14
use DateTime;
15
use Symfony\Component\Yaml\Yaml;
16
use WBW\Library\Core\Exception\Argument\DateArgumentException;
17
use WBW\Library\Core\Exception\Argument\IllegalArgumentException;
18
19
/**
20
 * Date/time helper.
21
 *
22
 * @author webeweb <https://github.com/webeweb/>
23
 * @package WBW\Library\Core\Argument
24
 */
25
class DateTimeHelper {
26
27
    /**
28
     * Compare two date/time.
29
     *
30
     * @param DateTime $a The date/time A.
31
     * @param DateTime $b The date/time B.
32
     * @return int Returns
33
     *  -1: if the date/time A is lesser than date/time B
34
     *   0: if the date/time are equals.
35
     *   1: if the date/time A is greater than date/time B
36
     * @throws IllegalArgumentException Throws an illegal argument exception if the two date/time does not have the same time zone.
37
     */
38
    public static function compare(DateTime $a, DateTime $b) {
39
        if (true === self::isLessThan($a, $b)) {
40
            return -1;
41
        }
42
        if (true === self::isGreaterThan($a, $b)) {
43
            return 1;
44
        }
45
        return 0;
46
    }
47
48
    /**
49
     * Compare tow date/time zones.
50
     *
51
     * @param DateTime $a The date/time A.
52
     * @param DateTime $b The date/time B.
53
     * @throws IllegalArgumentException Throws an illegal argument exception if the two date/time does not have the same time zone.
54
     */
55
    protected static function compareZone(DateTime $a, DateTime $b) {
56
        if (false === DateTimeZoneHelper::equals($a->getTimezone(), $b->getTimezone())) {
57
            throw new IllegalArgumentException("The two date/times does not have the same time zone");
58
        }
59
    }
60
61
    /**
62
     * Determines if two date/time are equals.
63
     *
64
     * @param DateTime $a The date/time A.
65
     * @param DateTime $b The date/time B.
66
     * @return boolean Returns true in case o success, false otherwise.
67
     * @throws IllegalArgumentException Throws an illegal argument exception if the two date/time does not have the same time zone.
68
     */
69
    public static function equals(DateTime $a, DateTime $b) {
70
        return 0 === self::compare($a, $b);
71
    }
72
73
    /**
74
     * Get a day number.
75
     *
76
     * @param DateTime $dateTime The date/time.
77
     * @return integer Returns the day number between 1 and 7 with monday equals to 1.
78
     */
79
    public static function getDayNumber(DateTime $dateTime) {
80
        return intval($dateTime->format("N"));
81
    }
82
83
    /**
84
     * Get the duration.
85
     *
86
     * @param DateTime $a The date/time A.
87
     * @param DateTime $b The date/time B.
88
     * @return int Returns the duration.
89
     * @throws IllegalArgumentException Throws an illegal argument exception if the two date/time does not have the same time zone.
90
     */
91
    public static function getDuration(DateTime $a, DateTime $b) {
92
        self::compareZone($a, $b);
93
        return $b->getTimestamp() - $a->getTimestamp();
94
    }
95
96
    /**
97
     * Get the greater date/time.
98
     *
99
     * @param DateTime $a The date/time A.
100
     * @param DateTime $b The date/time B.
101
     * @return DateTime Returns the greater date/time.
102
     * @throws IllegalArgumentException Throws an illegal argument exception if the two date/time does not have the same time zone.
103
     */
104
    public static function getGreater(DateTime $a, DateTime $b) {
105
        return 0 <= self::compare($a, $b) ? $a : $b;
106
    }
107
108
    /**
109
     * Get a month number.
110
     *
111
     * @param DateTime $dateTime The date/time.
112
     * @return integer Returns the month number.
113
     */
114
    public static function getMonthNumber(DateTime $dateTime) {
115
        return intval($dateTime->format("m"));
116
    }
117
118
    /**
119
     * Get the smaller date/time.
120
     *
121
     * @param DateTime $a The date/time A.
122
     * @param DateTime $b The date/time B.
123
     * @return DateTime Returns the smaller date/time.
124
     * @throws IllegalArgumentException Throws an illegal argument exception if the two date/time does not have the same time zone.
125
     */
126
    public static function getSmaller(DateTime $a, DateTime $b) {
127
        return 0 <= self::compare($a, $b) ? $b : $a;
128
    }
129
130
    /**
131
     * Get a week number.
132
     *
133
     * @param DateTime $dateTime The date/time.
134
     * @return integer Returns the week number.
135
     */
136
    public static function getWeekNumber(DateTime $dateTime) {
137
        return intval($dateTime->format("W"));
138
    }
139
140
    /**
141
     * Get a week number to apply with a schedule.
142
     *
143
     * <p>
144
     * For example:
145
     * We have a schedule etablished over 5 weeks.
146
     *
147
     * We start the schedule with the week number 1.
148
     * If the current date is 2018-01-01 and the start date is 2018-01-01, the week number is 1
149
     * If the current date is 2018-01-08 and the start date is 2018-01-01, the week number is 2
150
     * etc.
151
     *
152
     * We start the schedule with the week number 3.
153
     * If the current date is 2018-01-01 and the start date is 2018-01-01, the week number is 3
154
     * If the current date is 2018-01-08 and the start date is 2018-01-01, the week number is 4
155
     * etc.
156
     * </p>
157
     *
158
     * @param DateTime $date The date.
159
     * @param DateTime $startDate The start date.
160
     * @param integer $weekCount The week count.
161
     * @param integer $weekOffset The week offset.
162
     * @return integer Returns the week number to apply between 1 and $weekCount.
163
     */
164
    public static function getWeekNumberToApply(DateTime $date, DateTime $startDate, $weekCount, $weekOffset = 1) {
165
166
        // Check the week arguments.
167
        if ($weekCount <= 0 || $weekOffset <= 0 || $weekCount < $weekOffset) {
168
            return -1;
169
        }
170
171
        // Calculate.
172
        $result = intval($date->diff($startDate)->d / 7);
173
        $result %= $weekCount;
174
        $result += $weekOffset;
175
        if ($weekCount < $result) {
176
            $result -= $weekCount;
177
        }
178
179
        // Return.
180
        return $result;
181
    }
182
183
    /**
184
     * Get a year number.
185
     *
186
     * @param DateTime $dateTime The date/time.
187
     * @return integer Returns the year number.
188
     */
189
    public static function getYearNumber(DateTime $dateTime) {
190
        return intval($dateTime->format("Y"));
191
    }
192
193
    /**
194
     * Determines if a date/time is between date/time A and date/time B.
195
     *
196
     * @param DateTime $dateTime The date/time.
197
     * @param DateTime $a The date/time A.
198
     * @param DateTime $b The date/time B.
199
     * @return bool Returns true in case of success, false otherwise.
200
     * @throws IllegalArgumentException Throws an illegal argument exception if the two date/time does not have the same time zone.
201
     */
202
    public static function isBetween(DateTime $dateTime, DateTime $a, DateTime $b) {
203
        self::compareZone($a, $b);
204
        $c1 = $a->getTimestamp() <= $dateTime->getTimestamp();
205
        $c2 = $dateTime->getTimestamp() <= $b->getTimestamp();
206
        return $c1 && $c2;
207
    }
208
209
    /**
210
     * Determines if a value is a date.
211
     *
212
     * @param mixed $value The value.
213
     * @throws DateArgumentException Throws a Date argument exception if the value is not of expected type.
214
     */
215
    public static function isDate($value) {
216
        if (false === strtotime($value)) {
217
            throw new DateArgumentException($value);
218
        }
219
    }
220
221
    /**
222
     * Detremines if date/time A is greater than date/time B.
223
     *
224
     * @param DateTime $a The date/time A.
225
     * @param DateTime $b The date/time B.
226
     * @return bool Returns true in case of success, false otherwise.
227
     * @throws IllegalArgumentException Throws an illegal argument exception if the two date/time does not have the same time zone.
228
     */
229
    public static function isGreaterThan(DateTime $a, DateTime $b) {
230
        self::compareZone($a, $b);
231
        return $a->getTimestamp() > $b->getTimestamp();
232
    }
233
234
    /**
235
     * Detremines if date/time A is less than date/time B.
236
     *
237
     * @param DateTime $a The date/time A.
238
     * @param DateTime $b The date/time B.
239
     * @return bool Returns true in case of success, false otherwise.
240
     * @throws IllegalArgumentException Throws an illegal argument exception if the two date/time does not have the same time zone.
241
     */
242
    public static function isLessThan(DateTime $a, DateTime $b) {
243
        self::compareZone($a, $b);
244
        return $a->getTimestamp() < $b->getTimestamp();
245
    }
246
247
    /**
248
     * Translate the weekday part.
249
     *
250
     * @param string $date The date.
251
     * @param string $locale The locale.
252
     * @return string Returns the weekday part translated.
253
     */
254
    public static function translateWeekday($date, $locale = "en") {
255
256
        // Initialize.
257
        $template = __DIR__ . "/../Resources/translations/messages.%locale%.yml";
258
        $filename = str_replace("%locale%", $locale, $template);
259
260
        // Check if the filename exists.
261
        if (false === file_exists($filename)) {
262
            $filename = str_replace("%locale%", "en", $template);
263
        }
264
265
        // Parse the translations.
266
        $translations = Yaml::parse(file_get_contents($filename));
267
268
        // Return the weekday part translated.
269
        return str_ireplace(array_keys($translations["weekdays"]), array_values($translations["weekdays"]), $date);
270
    }
271
272
}
273