-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDate.php
More file actions
186 lines (157 loc) · 5.22 KB
/
Date.php
File metadata and controls
186 lines (157 loc) · 5.22 KB
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
<?php
declare(strict_types=1);
/**
* You may not change or alter any portion of this comment or credits
* of supporting developers from this source code or any supporting source code
* which is considered copyrighted (c) material of the original comment or credit authors.
*
* This program 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.
*/
/**
* @copyright 2000-2026 XOOPS Project (https://xoops.org/)
* @license GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
* @author XOOPS Development Team
*/
namespace Xoops\Helpers\Utility;
use DateInterval;
use DatePeriod;
use DateTimeImmutable;
use Xoops\Helpers\Contracts\DateTimeProviderInterface;
use Xoops\Helpers\Provider\SystemDateTimeProvider;
/**
* Date and time utility helpers.
*
* Provides date range generation, validation, arithmetic,
* and comparison methods. Uses DateTimeImmutable throughout.
*
* The DateTime source is injectable via setProvider() for testing.
*/
final class Date
{
private static ?DateTimeProviderInterface $provider = null;
/**
* Inject a custom DateTime provider (useful for testing).
*/
public static function setProvider(DateTimeProviderInterface $provider): void
{
self::$provider = $provider;
}
/**
* Reset the provider to the system default.
*/
public static function resetProvider(): void
{
self::$provider = null;
}
/**
* Get the current DateTimeImmutable instance.
*/
public static function now(): DateTimeImmutable
{
return self::getProvider()->now();
}
/**
* Generate a range of dates between start and end (inclusive).
*
* @param string $start Start date string
* @param string $end End date string
* @param string $step DateInterval spec (default: "P1D" = 1 day)
* @param string|null $format Output format, or null for DateTimeImmutable objects
* @return array<string|DateTimeImmutable>
*/
public static function range(string $start, string $end, string $step = 'P1D', ?string $format = 'Y-m-d'): array
{
$startDate = new DateTimeImmutable($start);
$endDate = new DateTimeImmutable($end);
$interval = new DateInterval($step);
$period = new DatePeriod($startDate, $interval, $endDate->add(new DateInterval('P1D')));
$result = [];
foreach ($period as $date) {
$result[] = $format !== null ? $date->format($format) : $date;
}
return $result;
}
/**
* Calculate the difference between two dates.
*/
public static function diff(string $start, string $end): DateInterval
{
return (new DateTimeImmutable($start))->diff(new DateTimeImmutable($end));
}
/**
* Validate a date string against a format.
*/
public static function isValid(string $date, string $format = 'Y-m-d'): bool
{
$parsed = DateTimeImmutable::createFromFormat($format, $date);
return $parsed !== false && $parsed->format($format) === $date;
}
/**
* Add days to a date and return formatted result.
*/
public static function addDays(string $date, int $days, string $format = 'Y-m-d'): string
{
$modifier = ($days >= 0 ? '+' : '') . $days . ' days';
return (new DateTimeImmutable($date))->modify($modifier)->format($format);
}
/**
* Subtract days from a date and return formatted result.
*/
public static function subDays(string $date, int $days, string $format = 'Y-m-d'): string
{
return self::addDays($date, -$days, $format);
}
/**
* Check if a date falls on a weekend (Saturday or Sunday).
*/
public static function isWeekend(string $date): bool
{
$dayOfWeek = (int) (new DateTimeImmutable($date))->format('N');
return $dayOfWeek >= 6;
}
/**
* Check if a date is today.
*/
public static function isToday(string $date): bool
{
return (new DateTimeImmutable($date))->format('Y-m-d') === self::now()->format('Y-m-d');
}
/**
* Check if a date is in the past.
*/
public static function isPast(string $date): bool
{
return new DateTimeImmutable($date) < self::now();
}
/**
* Check if a date is in the future.
*/
public static function isFuture(string $date): bool
{
return new DateTimeImmutable($date) > self::now();
}
/**
* Reformat a date string from one format to another.
*/
public static function reformat(string $date, string $fromFormat, string $toFormat): string
{
$parsed = DateTimeImmutable::createFromFormat($fromFormat, $date);
if ($parsed === false) {
return $date;
}
return $parsed->format($toFormat);
}
/**
* Get the age in years from a birth date.
*/
public static function age(string $birthDate): int
{
return (int) (new DateTimeImmutable($birthDate))->diff(self::now())->y;
}
private static function getProvider(): DateTimeProviderInterface
{
return self::$provider ??= new SystemDateTimeProvider();
}
}