Bitrix-D7  20.5.0
main/lib/type/date.php
См. документацию.
1 <?php
2 namespace Bitrix\Main\Type;
3 
4 use Bitrix\Main;
6 
7 class Date
8 {
9  /** @var \DateTime */
10  protected $value;
11 
12  /**
13  * @param string $date String representation of date.
14  * @param string $format PHP date format. If not specified, the format is got from the current culture.
15  *
16  * @throws Main\ObjectException
17  */
18  public function __construct($date = null, $format = null)
19  {
20  $this->value = new \DateTime();
21  if ($date !== null && $date !== "")
22  {
23  if ($format === null)
24  {
25  $format = static::getFormat();
26  }
27 
28  $parsedValue = $this->parse($format, $date);
29 
30  if($parsedValue === false)
31  {
32  throw new Main\ObjectException("Incorrect date: ".$date);
33  }
34 
35  if(isset($parsedValue["timestamp"]))
36  {
37  $this->value->setTimestamp($parsedValue["timestamp"]);
38  }
39  else
40  {
41  $this->value->setDate($parsedValue['year'], $parsedValue['month'], $parsedValue['day']);
42  }
43  }
44  $this->value->setTime(0, 0, 0);
45  }
46 
47  /**
48  * @param string $format
49  * @param string $time
50  * @return array|bool
51  */
52  protected function parse($format, $time)
53  {
54  $parsedValue = date_parse_from_format($format, $time);
55 
56  //Ignore errors when format is longer than date
57  //or date string is longer than format
58  if ($parsedValue['error_count'] > 1)
59  {
60  $error = current($parsedValue['errors']);
61 
62  if ($error === 'A two digit second could not be found')
63  {
64  //possibly missed seconds with am/pm format
65  $timestamp = strtotime($time);
66 
67  if ($timestamp === false)
68  {
69  return false;
70  }
71 
72  return [
73  "timestamp" => $timestamp,
74  ];
75  }
76  if ($error !== 'Trailing data' && $error !== 'Data missing')
77  {
78  return false;
79  }
80  }
81 
82  if(isset($parsedValue["relative"]["second"]) && $parsedValue["relative"]["second"] <> 0)
83  {
84  return [
85  "timestamp" => $parsedValue["relative"]["second"],
86  ];
87  }
88 
89  //normalize values
90  if($parsedValue['month'] === false)
91  {
92  $parsedValue['month'] = 1;
93  }
94  if($parsedValue['day'] === false)
95  {
96  $parsedValue['day'] = 1;
97  }
98 
99  return $parsedValue;
100  }
101 
102  /**
103  * Formats date value to string.
104  *
105  * @param string $format PHP date format.
106  *
107  * @return string
108  */
109  public function format($format)
110  {
111  return $this->value->format($format);
112  }
113 
114  /**
115  * Produces the copy of the object.
116  *
117  * @return void
118  */
119  public function __clone()
120  {
121  $this->value = clone $this->value;
122  }
123 
124  /**
125  * Performs dates arithmetic.
126  *
127  * Each duration period is represented by an integer value followed by a period
128  * designator. If the duration contains time elements, that portion of the
129  * specification is preceded by the letter T.
130  * Period Designators: Y - years, M - months, D - days, W - weeks, H - hours,
131  * M - minutes, S - seconds.
132  * Examples: two days - 2D, two seconds - T2S, six years and five minutes - 6YT5M.
133  * The unit types must be entered from the largest scale unit on the left to the
134  * smallest scale unit on the right.
135  * Use first "-" char for negative periods.
136  * OR
137  * Relative period.
138  * Examples: "+5 weeks", "12 day", "-7 weekdays", '3 months - 5 days'
139  *
140  * @param string $interval Time interval to add.
141  *
142  * @return $this
143  */
144  public function add($interval)
145  {
146  $i = $this->tryToCreateIntervalByDesignators($interval);
147  if ($i == null)
148  {
149  $i = \DateInterval::createFromDateString($interval);
150  }
151 
152  $this->value->add($i);
153 
154  return $this;
155  }
156 
157  /**
158  * Sets the current date of the DateTime object to a different date.
159  * @param int $year
160  * @param int $month
161  * @param int $day
162  *
163  * @return $this
164  */
165  public function setDate($year, $month, $day)
166  {
167  $this->value->setDate($year, $month, $day);
168 
169  return $this;
170  }
171 
172  private function tryToCreateIntervalByDesignators($interval)
173  {
174  if (!is_string($interval) || strpos($interval, ' ') !== false)
175  {
176  return null;
177  }
178 
179  $i = null;
180  try
181  {
182  $intervalTmp = strtoupper($interval);
183  $isNegative = false;
184  $firstChar = substr($intervalTmp, 0, 1);
185  if ($firstChar === "-")
186  {
187  $isNegative = true;
188  $intervalTmp = substr($intervalTmp, 1);
189  $firstChar = substr($intervalTmp, 0, 1);
190  }
191 
192  if ($firstChar !== "P")
193  {
194  $intervalTmp = "P".$intervalTmp;
195  }
196  $i = new \DateInterval($intervalTmp);
197  if ($isNegative)
198  {
199  $i->invert = 1;
200  }
201  }
202  catch (\Exception $e)
203  {
204  }
205 
206  return $i;
207  }
208 
209  /**
210  * Returns Unix timestamp from date.
211  *
212  * @return int
213  */
214  public function getTimestamp()
215  {
216  return $this->value->getTimestamp();
217  }
218 
219  /**
220  * Returns difference between dates.
221  *
222  * @param DateTime $time
223  * @return \DateInterval
224  */
225  public function getDiff(DateTime $time)
226  {
227  return $this->value->diff($time->value);
228  }
229 
230  /**
231  * Converts a date to the string.
232  *
233  * @param Context\Culture $culture Culture contains date format.
234  *
235  * @return string
236  */
237  public function toString(Context\Culture $culture = null)
238  {
239  $format = static::getFormat($culture);
240  return $this->format($format);
241  }
242 
243  /**
244  * Converts a date to the string with default culture format setting.
245  *
246  * @return string
247  */
248  public function __toString()
249  {
250  return $this->toString();
251  }
252 
253  /**
254  * Returns a date format from the culture in the php format.
255  *
256  * @param Context\Culture $culture Optional culture.
257  *
258  * @return string
259  */
260  public static function getFormat(Context\Culture $culture = null)
261  {
262  static $defaultCulture = null;
263 
264  if($culture === null)
265  {
266  if($defaultCulture === null)
267  {
268  $context = Context::getCurrent();
269  if($context)
270  {
271  $defaultCulture = $context->getCulture();
272  }
273  }
274  $culture = $defaultCulture;
275  }
276 
277  $format = static::getCultureFormat($culture);
278 
279  return static::convertFormatToPhp($format);
280  }
281 
282  /**
283  * Returns short date culture format.
284  *
285  * @param Context\Culture $culture Culture.
286  *
287  * @return string
288  */
289  protected static function getCultureFormat(Context\Culture $culture = null)
290  {
291  if($culture)
292  {
293  return $culture->getDateFormat();
294  }
295  return "DD.MM.YYYY";
296  }
297 
298  /**
299  * Converts date format from culture to php format.
300  *
301  * @param string $format Format string.
302  *
303  * @return mixed
304  */
305  public static function convertFormatToPhp($format)
306  {
307  static $from = array(
308  "YYYY", // 1999
309  "MMMM", // January - December
310  "MM", // 01 - 12
311  "DD", // 01 - 31
312  "TT", // AM - PM
313  "T", // am - pm
314  "MI", // 00 - 59
315  "SS", // 00 - 59
316  );
317  static $to = array(
318  "Y", // 1999
319  "F", // January - December
320  "m", // 01 - 12
321  "d", // 01 - 31
322  "A", // AM - PM
323  "a", // am - pm
324  "i", // 00 - 59
325  "s", // 00 - 59
326  );
327 
328  $format = str_replace($from, $to, $format);
329 
330  $tempFormat = $format;
331  $format = str_replace("HH", "H", $format); // 00 - 24
332  if ($tempFormat === $format)
333  {
334  $format = str_replace("H", "h", $format); // 01 - 12
335  }
336 
337  $tempFormat = $format;
338  $format = str_replace("GG", "G", $format); // 0 - 24
339  if ($tempFormat === $format)
340  {
341  $format = str_replace("G", "g", $format); // 1 - 12
342  }
343 
344  return $format;
345  }
346 
347  /**
348  * Checks the string for correct date (by trying to create Date object).
349  *
350  * @param string $time String representation of date.
351  * @param string $format PHP date format. If not specified, the format is got from the current culture.
352  *
353  * @return bool
354  */
355  public static function isCorrect($time, $format = null)
356  {
357  if (empty($time))
358  {
359  return false;
360  }
361 
362  $result = true;
363 
364  try
365  {
366  new static($time, $format);
367  }
368  catch (Main\ObjectException $ex)
369  {
370  $result = false;
371  }
372 
373  return $result;
374  }
375 
376  /**
377  * Creates Date object from PHP \DateTime object.
378  *
379  * @param \DateTime $datetime Source object.
380  *
381  * @return static
382  */
383  public static function createFromPhp(\DateTime $datetime)
384  {
385  $d = new static();
386  $d->value = clone $datetime;
387  $d->value->setTime(0, 0, 0);
388  return $d;
389  }
390 
391  /**
392  * Creates Date object from Unix timestamp.
393  *
394  * @param int $timestamp Source timestamp.
395  *
396  * @return static
397  */
398  public static function createFromTimestamp($timestamp)
399  {
400  $d = new static();
401  $d->value->setTimestamp($timestamp);
402  $d->value->setTime(0, 0, 0);
403  return $d;
404  }
405 
406  /**
407  * Creates Date object from Text (return array of result object)
408  * Examples: "end of next week", "tomorrow morning", "friday 25.10"
409  *
410  * @param string $text
411  * @return DateTime|null
412  */
413  public static function createFromText($text)
414  {
415  $result = Main\Text\DateConverter::decode($text);
416  if (empty($result))
417  {
418  return null;
419  }
420 
421  return $result[0]->getDate();
422  }
423 }
Context of current request.
static getCurrent()
Static method returns current instance of context.
Exception is thrown when the object can't be constructed.
static decode($text, $limit=0)
Creates Date object from Text (return array of result object)
static createFromTimestamp($timestamp)
Creates Date object from Unix timestamp.
static getFormat(Context\Culture $culture=null)
Returns a date format from the culture in the php format.
add($interval)
Performs dates arithmetic.
setDate($year, $month, $day)
Sets the current date of the DateTime object to a different date.
format($format)
Formats date value to string.
__toString()
Converts a date to the string with default culture format setting.
toString(Context\Culture $culture=null)
Converts a date to the string.
static getCultureFormat(Context\Culture $culture=null)
Returns short date culture format.
getTimestamp()
Returns Unix timestamp from date.
__construct($date=null, $format=null)
__clone()
Produces the copy of the object.
static convertFormatToPhp($format)
Converts date format from culture to php format.
getDiff(DateTime $time)
Returns difference between dates.
static createFromText($text)
Creates Date object from Text (return array of result object) Examples: "end of next week",...
static isCorrect($time, $format=null)
Checks the string for correct date (by trying to create Date object).
static createFromPhp(\DateTime $datetime)
Creates Date object from PHP \DateTime object.
setTime($hour, $minute, $second=0, $microseconds=0)