]> git.mxchange.org Git - friendica.git/blob - src/Util/DateTimeFormat.php
Catch exceptions for Worker::AddContact()
[friendica.git] / src / Util / DateTimeFormat.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2022, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Util;
23
24 use Friendica\Core\Logger;
25 use DateTime;
26 use DateTimeZone;
27 use Exception;
28
29 /**
30  * Temporal class
31  */
32 class DateTimeFormat
33 {
34         const ATOM  = 'Y-m-d\TH:i:s\Z';
35         const MYSQL = 'Y-m-d H:i:s';
36         const HTTP  = 'D, d M Y H:i:s \G\M\T';
37         const JSON  = 'Y-m-d\TH:i:s.v\Z';
38         const API   = 'D M d H:i:s +0000 Y';
39
40         static $localTimezone = 'UTC';
41
42         public static function setLocalTimeZone(string $timezone)
43         {
44                 self::$localTimezone = $timezone;
45         }
46
47         /**
48          * convert() shorthand for UTC.
49          *
50          * @param string $time   A date/time string
51          * @param string $format DateTime format string or Temporal constant
52          * @return string
53          * @throws Exception
54          */
55         public static function utc(string $time, string $format = self::MYSQL): string
56         {
57                 return self::convert($time, 'UTC', 'UTC', $format);
58         }
59
60         /**
61          * convert() shorthand for local.
62          *
63          * @param string $time   A date/time string
64          * @param string $format DateTime format string or Temporal constant
65          * @return string
66          * @throws Exception
67          */
68         public static function local($time, $format = self::MYSQL)
69         {
70                 return self::convert($time, self::$localTimezone, 'UTC', $format);
71         }
72
73         /**
74          * convert() shorthand for timezoned now.
75          *
76          * @param        $timezone
77          * @param string $format DateTime format string or Temporal constant
78          * @return string
79          * @throws Exception
80          */
81         public static function timezoneNow($timezone, $format = self::MYSQL)
82         {
83                 return self::convert('now', $timezone, 'UTC', $format);
84         }
85
86         /**
87          * convert() shorthand for local now.
88          *
89          * @param string $format DateTime format string or Temporal constant
90          * @return string
91          * @throws Exception
92          */
93         public static function localNow($format = self::MYSQL)
94         {
95                 return self::local('now', $format);
96         }
97
98         /**
99          * convert() shorthand for UTC now.
100          *
101          * @param string $format DateTime format string or Temporal constant
102          * @return string
103          * @throws Exception
104          */
105         public static function utcNow(string $format = self::MYSQL): string
106         {
107                 return self::utc('now', $format);
108         }
109
110         /**
111          * General purpose date parse/convert/format function.
112          *
113          * @param string $s       Some parseable date/time string
114          * @param string $tz_to   Destination timezone
115          * @param string $tz_from Source timezone
116          * @param string $format  Output format recognised from php's DateTime class
117          *                        http://www.php.net/manual/en/datetime.format.php
118          *
119          * @return string Formatted date according to given format
120          * @throws Exception
121          */
122         public static function convert($s = 'now', $tz_to = 'UTC', $tz_from = 'UTC', $format = self::MYSQL)
123         {
124                 // Defaults to UTC if nothing is set, but throws an exception if set to empty string.
125                 // Provide some sane defaults regardless.
126                 if ($tz_from === '') {
127                         $tz_from = 'UTC';
128                 }
129
130                 if ($tz_to === '') {
131                         $tz_to = 'UTC';
132                 }
133
134                 if (($s === '') || (!is_string($s))) {
135                         $s = 'now';
136                 }
137
138                 /*
139                  * Slight hackish adjustment so that 'zero' datetime actually returns what is intended
140                  * otherwise we end up with -0001-11-30 ...
141                  * add 32 days so that we at least get year 00, and then hack around the fact that
142                  * months and days always start with 1.
143                  */
144                 if (substr($s, 0, 10) <= '0001-01-01') {
145                         if ($s < '0000-00-00') {
146                                 $s = '0000-00-00';
147                         }
148                         $d = new DateTime($s . ' + 32 days', new DateTimeZone('UTC'));
149                         return str_replace('1', '0', $d->format($format));
150                 }
151
152                 try {
153                         $from_obj = new DateTimeZone($tz_from);
154                 } catch (Exception $e) {
155                         $from_obj = new DateTimeZone('UTC');
156                 }
157
158                 try {
159                         $d = new DateTime($s, $from_obj);
160                 } catch (Exception $e) {
161                         Logger::notice('DateTimeFormat::convert: exception: ' . $e->getMessage());
162                         $d = new DateTime('now', $from_obj);
163                 }
164
165                 try {
166                         $to_obj = new DateTimeZone($tz_to);
167                 } catch (Exception $e) {
168                         $to_obj = new DateTimeZone('UTC');
169                 }
170
171                 $d->setTimezone($to_obj);
172
173                 return $d->format($format);
174         }
175
176         /**
177          * Checks, if the given string is a date with the pattern YYYY-MM
178          *
179          * @param string $dateString The given date
180          *
181          * @return boolean True, if the date is a valid pattern
182          */
183         public function isYearMonth(string $dateString)
184         {
185                 // Check format (2019-01, 2019-1, 2019-10)
186                 if (!preg_match('/^([12]\d{3}-(1[0-2]|0[1-9]|\d))$/', $dateString)) {
187                         return false;
188                 }
189
190                 $date = DateTime::createFromFormat('Y-m', $dateString);
191
192                 if (!$date) {
193                         return false;
194                 }
195
196                 try {
197                         $now = new DateTime();
198                 } catch (\Throwable $t) {
199                         return false;
200                 }
201
202                 if ($date > $now) {
203                         return false;
204                 }
205
206                 return true;
207         }
208
209         /**
210          * Checks, if the given string is a date with the pattern YYYY-MM-DD
211          *
212          * @param string $dateString The given date
213          *
214          * @return boolean True, if the date is a valid pattern
215          */
216         public function isYearMonthDay(string $dateString)
217         {
218                 $date = DateTime::createFromFormat('Y-m-d', $dateString);
219                 if (!$date) {
220                         return false;
221                 }
222
223                 if (DateTime::getLastErrors()['error_count'] || DateTime::getLastErrors()['warning_count']) {
224                         return false;
225                 }
226
227                 return true;
228         }
229 }