DateParser.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. namespace PicoFeed\Parser;
  3. use DateTime;
  4. use DateTimeZone;
  5. use PicoFeed\Base;
  6. /**
  7. * Date Parser.
  8. *
  9. * @package PicoFeed\Parser
  10. * @author Frederic Guillot
  11. */
  12. class DateParser extends Base
  13. {
  14. /**
  15. * Timezone used to parse feed dates.
  16. *
  17. * @access private
  18. * @var string
  19. */
  20. private $timezone = 'UTC';
  21. /**
  22. * Supported formats [ 'format' => length ].
  23. *
  24. * @var array
  25. */
  26. public $formats = array(
  27. DATE_ATOM => null,
  28. DATE_RSS => null,
  29. DATE_COOKIE => null,
  30. DATE_ISO8601 => null,
  31. DATE_RFC822 => null,
  32. DATE_RFC850 => null,
  33. DATE_RFC1036 => null,
  34. DATE_RFC1123 => null,
  35. DATE_RFC2822 => null,
  36. DATE_RFC3339 => null,
  37. 'l, d M Y H:i:s' => null,
  38. 'D, d M Y H:i:s' => 25,
  39. 'D, d M Y h:i:s' => 25,
  40. 'D M d Y H:i:s' => 24,
  41. 'j M Y H:i:s' => 20,
  42. 'Y-m-d H:i:s' => 19,
  43. 'Y-m-d\TH:i:s' => 19,
  44. 'd/m/Y H:i:s' => 19,
  45. 'D, d M Y' => 16,
  46. 'Y-m-d' => 10,
  47. 'd-m-Y' => 10,
  48. 'm-d-Y' => 10,
  49. 'd.m.Y' => 10,
  50. 'm.d.Y' => 10,
  51. 'd/m/Y' => 10,
  52. 'm/d/Y' => 10,
  53. );
  54. /**
  55. * Try to parse all date format for broken feeds.
  56. *
  57. * @param string $value Original date format
  58. *
  59. * @return DateTime
  60. */
  61. public function getDateTime($value)
  62. {
  63. $value = trim($value);
  64. foreach ($this->formats as $format => $length) {
  65. $truncated_value = $value;
  66. if ($length !== null) {
  67. $truncated_value = substr($truncated_value, 0, $length);
  68. }
  69. $date = $this->getValidDate($format, $truncated_value);
  70. if ($date !== false) {
  71. return $date;
  72. }
  73. }
  74. return $this->getCurrentDateTime();
  75. }
  76. /**
  77. * Get a valid date from a given format.
  78. *
  79. * @param string $format Date format
  80. * @param string $value Original date value
  81. *
  82. * @return DateTime|bool
  83. */
  84. public function getValidDate($format, $value)
  85. {
  86. $date = DateTime::createFromFormat($format, $value, $this->getTimeZone());
  87. if ($date !== false) {
  88. $errors = DateTime::getLastErrors();
  89. if ($errors['error_count'] === 0 && $errors['warning_count'] === 0) {
  90. return $date;
  91. }
  92. }
  93. return false;
  94. }
  95. /**
  96. * Get the current datetime.
  97. *
  98. * @return DateTime
  99. */
  100. public function getCurrentDateTime()
  101. {
  102. return new DateTime('now', $this->getTimeZone());
  103. }
  104. /**
  105. * Get DateTimeZone instance
  106. *
  107. * @access public
  108. * @return DateTimeZone
  109. */
  110. public function getTimeZone()
  111. {
  112. return new DateTimeZone($this->config->getTimezone() ?: $this->timezone);
  113. }
  114. }