4
4
5
5
namespace Dot \Twig \Extension ;
6
6
7
+ use DateTime ;
8
+ use DateTimeImmutable ;
7
9
use DateTimeInterface ;
10
+ use DateTimeZone ;
11
+ use Exception ;
8
12
use Twig \Environment ;
9
13
use Twig \Extension \AbstractExtension ;
10
14
use Twig \Extension \CoreExtension ;
11
15
use Twig \TwigFilter ;
12
16
17
+ use function ctype_digit ;
18
+ use function strtolower ;
19
+ use function substr ;
20
+
13
21
class DateExtension extends AbstractExtension
14
22
{
15
23
public static array $ units = [
@@ -31,15 +39,24 @@ public function getFilters(): array
31
39
/**
32
40
* Filters for converting dates to a time ago string like Facebook and Twitter has.
33
41
* If none given, the current time will be used.
42
+ *
43
+ * @throws Exception
34
44
*/
35
45
public function diff (
36
46
Environment $ env ,
37
47
string |DateTimeInterface |null $ date ,
38
- string |DateTimeInterface |null $ now = null
48
+ string |DateTimeInterface |null $ now = null ,
49
+ string |DateTimeZone |null $ timezone = null ,
39
50
): string {
51
+ if (null === $ timezone ) {
52
+ $ timezone = $ env ->getExtension (CoreExtension::class)->getTimezone ();
53
+ } elseif (! $ timezone instanceof DateTimeZone) {
54
+ $ timezone = new DateTimeZone ($ timezone );
55
+ }
56
+
40
57
// Convert both dates to DateTime instances.
41
- $ date = $ env -> getExtension (CoreExtension::class)-> convertDate ($ date );
42
- $ now = $ env -> getExtension (CoreExtension::class)-> convertDate ($ now );
58
+ $ date = $ this -> convertDate ($ date, $ timezone );
59
+ $ now = $ this -> convertDate ($ now, $ timezone );
43
60
44
61
// Get the difference between the two DateTime objects.
45
62
$ diff = $ date ->diff ($ now );
@@ -56,6 +73,40 @@ public function diff(
56
73
return '' ;
57
74
}
58
75
76
+ /**
77
+ * @throws Exception
78
+ */
79
+ protected function convertDate (string |DateTimeInterface |null $ date , DateTimeZone $ timezone ): DateTimeInterface
80
+ {
81
+ if ($ date instanceof DateTimeImmutable) {
82
+ return $ date ->setTimezone ($ timezone );
83
+ }
84
+
85
+ if ($ date instanceof DateTimeInterface) {
86
+ $ date = clone $ date ;
87
+ $ date ->setTimezone ($ timezone );
88
+
89
+ return $ date ;
90
+ }
91
+
92
+ if (null === $ date || 'now ' === strtolower ($ date )) {
93
+ if (null === $ date ) {
94
+ $ date = 'now ' ;
95
+ }
96
+
97
+ return new DateTime ($ date , $ timezone );
98
+ }
99
+
100
+ if (
101
+ ctype_digit ($ date )
102
+ || (! empty ($ date ) && '- ' === $ date [0 ] && ctype_digit (substr ($ date , 1 )))
103
+ ) {
104
+ return new DateTime ('@ ' . $ date , $ timezone );
105
+ } else {
106
+ return new DateTime ($ date , $ timezone );
107
+ }
108
+ }
109
+
59
110
public function getPluralizedInterval (mixed $ count , int $ invert , string $ unit ): string
60
111
{
61
112
if (1 !== $ count ) {
0 commit comments