1*2afbbbaeSAndreas Gohr<?php 2*2afbbbaeSAndreas Gohr 3*2afbbbaeSAndreas Gohrdeclare(strict_types=1); 4*2afbbbaeSAndreas Gohr/** 5*2afbbbaeSAndreas Gohr * SimplePie 6*2afbbbaeSAndreas Gohr * 7*2afbbbaeSAndreas Gohr * A PHP-Based RSS and Atom Feed Framework. 8*2afbbbaeSAndreas Gohr * Takes the hard work out of managing a complete RSS/Atom solution. 9*2afbbbaeSAndreas Gohr * 10*2afbbbaeSAndreas Gohr * Copyright (c) 2004-2022, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors 11*2afbbbaeSAndreas Gohr * All rights reserved. 12*2afbbbaeSAndreas Gohr * 13*2afbbbaeSAndreas Gohr * Redistribution and use in source and binary forms, with or without modification, are 14*2afbbbaeSAndreas Gohr * permitted provided that the following conditions are met: 15*2afbbbaeSAndreas Gohr * 16*2afbbbaeSAndreas Gohr * * Redistributions of source code must retain the above copyright notice, this list of 17*2afbbbaeSAndreas Gohr * conditions and the following disclaimer. 18*2afbbbaeSAndreas Gohr * 19*2afbbbaeSAndreas Gohr * * Redistributions in binary form must reproduce the above copyright notice, this list 20*2afbbbaeSAndreas Gohr * of conditions and the following disclaimer in the documentation and/or other materials 21*2afbbbaeSAndreas Gohr * provided with the distribution. 22*2afbbbaeSAndreas Gohr * 23*2afbbbaeSAndreas Gohr * * Neither the name of the SimplePie Team nor the names of its contributors may be used 24*2afbbbaeSAndreas Gohr * to endorse or promote products derived from this software without specific prior 25*2afbbbaeSAndreas Gohr * written permission. 26*2afbbbaeSAndreas Gohr * 27*2afbbbaeSAndreas Gohr * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 28*2afbbbaeSAndreas Gohr * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 29*2afbbbaeSAndreas Gohr * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 30*2afbbbaeSAndreas Gohr * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31*2afbbbaeSAndreas Gohr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 32*2afbbbaeSAndreas Gohr * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33*2afbbbaeSAndreas Gohr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 34*2afbbbaeSAndreas Gohr * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35*2afbbbaeSAndreas Gohr * POSSIBILITY OF SUCH DAMAGE. 36*2afbbbaeSAndreas Gohr * 37*2afbbbaeSAndreas Gohr * @package SimplePie 38*2afbbbaeSAndreas Gohr * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue 39*2afbbbaeSAndreas Gohr * @author Ryan Parman 40*2afbbbaeSAndreas Gohr * @author Sam Sneddon 41*2afbbbaeSAndreas Gohr * @author Ryan McCue 42*2afbbbaeSAndreas Gohr * @link http://simplepie.org/ SimplePie 43*2afbbbaeSAndreas Gohr * @license http://www.opensource.org/licenses/bsd-license.php BSD License 44*2afbbbaeSAndreas Gohr */ 45*2afbbbaeSAndreas Gohr 46*2afbbbaeSAndreas Gohrnamespace SimplePie\Parse; 47*2afbbbaeSAndreas Gohr 48*2afbbbaeSAndreas Gohr/** 49*2afbbbaeSAndreas Gohr * Date Parser 50*2afbbbaeSAndreas Gohr * 51*2afbbbaeSAndreas Gohr * @package SimplePie 52*2afbbbaeSAndreas Gohr * @subpackage Parsing 53*2afbbbaeSAndreas Gohr */ 54*2afbbbaeSAndreas Gohrclass Date 55*2afbbbaeSAndreas Gohr{ 56*2afbbbaeSAndreas Gohr /** 57*2afbbbaeSAndreas Gohr * Input data 58*2afbbbaeSAndreas Gohr * 59*2afbbbaeSAndreas Gohr * @access protected 60*2afbbbaeSAndreas Gohr * @var string 61*2afbbbaeSAndreas Gohr */ 62*2afbbbaeSAndreas Gohr public $date; 63*2afbbbaeSAndreas Gohr 64*2afbbbaeSAndreas Gohr /** 65*2afbbbaeSAndreas Gohr * List of days, calendar day name => ordinal day number in the week 66*2afbbbaeSAndreas Gohr * 67*2afbbbaeSAndreas Gohr * @access protected 68*2afbbbaeSAndreas Gohr * @var array 69*2afbbbaeSAndreas Gohr */ 70*2afbbbaeSAndreas Gohr public $day = [ 71*2afbbbaeSAndreas Gohr // English 72*2afbbbaeSAndreas Gohr 'mon' => 1, 73*2afbbbaeSAndreas Gohr 'monday' => 1, 74*2afbbbaeSAndreas Gohr 'tue' => 2, 75*2afbbbaeSAndreas Gohr 'tuesday' => 2, 76*2afbbbaeSAndreas Gohr 'wed' => 3, 77*2afbbbaeSAndreas Gohr 'wednesday' => 3, 78*2afbbbaeSAndreas Gohr 'thu' => 4, 79*2afbbbaeSAndreas Gohr 'thursday' => 4, 80*2afbbbaeSAndreas Gohr 'fri' => 5, 81*2afbbbaeSAndreas Gohr 'friday' => 5, 82*2afbbbaeSAndreas Gohr 'sat' => 6, 83*2afbbbaeSAndreas Gohr 'saturday' => 6, 84*2afbbbaeSAndreas Gohr 'sun' => 7, 85*2afbbbaeSAndreas Gohr 'sunday' => 7, 86*2afbbbaeSAndreas Gohr // Dutch 87*2afbbbaeSAndreas Gohr 'maandag' => 1, 88*2afbbbaeSAndreas Gohr 'dinsdag' => 2, 89*2afbbbaeSAndreas Gohr 'woensdag' => 3, 90*2afbbbaeSAndreas Gohr 'donderdag' => 4, 91*2afbbbaeSAndreas Gohr 'vrijdag' => 5, 92*2afbbbaeSAndreas Gohr 'zaterdag' => 6, 93*2afbbbaeSAndreas Gohr 'zondag' => 7, 94*2afbbbaeSAndreas Gohr // French 95*2afbbbaeSAndreas Gohr 'lundi' => 1, 96*2afbbbaeSAndreas Gohr 'mardi' => 2, 97*2afbbbaeSAndreas Gohr 'mercredi' => 3, 98*2afbbbaeSAndreas Gohr 'jeudi' => 4, 99*2afbbbaeSAndreas Gohr 'vendredi' => 5, 100*2afbbbaeSAndreas Gohr 'samedi' => 6, 101*2afbbbaeSAndreas Gohr 'dimanche' => 7, 102*2afbbbaeSAndreas Gohr // German 103*2afbbbaeSAndreas Gohr 'montag' => 1, 104*2afbbbaeSAndreas Gohr 'mo' => 1, 105*2afbbbaeSAndreas Gohr 'dienstag' => 2, 106*2afbbbaeSAndreas Gohr 'di' => 2, 107*2afbbbaeSAndreas Gohr 'mittwoch' => 3, 108*2afbbbaeSAndreas Gohr 'mi' => 3, 109*2afbbbaeSAndreas Gohr 'donnerstag' => 4, 110*2afbbbaeSAndreas Gohr 'do' => 4, 111*2afbbbaeSAndreas Gohr 'freitag' => 5, 112*2afbbbaeSAndreas Gohr 'fr' => 5, 113*2afbbbaeSAndreas Gohr 'samstag' => 6, 114*2afbbbaeSAndreas Gohr 'sa' => 6, 115*2afbbbaeSAndreas Gohr 'sonnabend' => 6, 116*2afbbbaeSAndreas Gohr // AFAIK no short form for sonnabend 117*2afbbbaeSAndreas Gohr 'so' => 7, 118*2afbbbaeSAndreas Gohr 'sonntag' => 7, 119*2afbbbaeSAndreas Gohr // Italian 120*2afbbbaeSAndreas Gohr 'lunedì' => 1, 121*2afbbbaeSAndreas Gohr 'martedì' => 2, 122*2afbbbaeSAndreas Gohr 'mercoledì' => 3, 123*2afbbbaeSAndreas Gohr 'giovedì' => 4, 124*2afbbbaeSAndreas Gohr 'venerdì' => 5, 125*2afbbbaeSAndreas Gohr 'sabato' => 6, 126*2afbbbaeSAndreas Gohr 'domenica' => 7, 127*2afbbbaeSAndreas Gohr // Spanish 128*2afbbbaeSAndreas Gohr 'lunes' => 1, 129*2afbbbaeSAndreas Gohr 'martes' => 2, 130*2afbbbaeSAndreas Gohr 'miércoles' => 3, 131*2afbbbaeSAndreas Gohr 'jueves' => 4, 132*2afbbbaeSAndreas Gohr 'viernes' => 5, 133*2afbbbaeSAndreas Gohr 'sábado' => 6, 134*2afbbbaeSAndreas Gohr 'domingo' => 7, 135*2afbbbaeSAndreas Gohr // Finnish 136*2afbbbaeSAndreas Gohr 'maanantai' => 1, 137*2afbbbaeSAndreas Gohr 'tiistai' => 2, 138*2afbbbaeSAndreas Gohr 'keskiviikko' => 3, 139*2afbbbaeSAndreas Gohr 'torstai' => 4, 140*2afbbbaeSAndreas Gohr 'perjantai' => 5, 141*2afbbbaeSAndreas Gohr 'lauantai' => 6, 142*2afbbbaeSAndreas Gohr 'sunnuntai' => 7, 143*2afbbbaeSAndreas Gohr // Hungarian 144*2afbbbaeSAndreas Gohr 'hétfő' => 1, 145*2afbbbaeSAndreas Gohr 'kedd' => 2, 146*2afbbbaeSAndreas Gohr 'szerda' => 3, 147*2afbbbaeSAndreas Gohr 'csütörtok' => 4, 148*2afbbbaeSAndreas Gohr 'péntek' => 5, 149*2afbbbaeSAndreas Gohr 'szombat' => 6, 150*2afbbbaeSAndreas Gohr 'vasárnap' => 7, 151*2afbbbaeSAndreas Gohr // Greek 152*2afbbbaeSAndreas Gohr 'Δευ' => 1, 153*2afbbbaeSAndreas Gohr 'Τρι' => 2, 154*2afbbbaeSAndreas Gohr 'Τετ' => 3, 155*2afbbbaeSAndreas Gohr 'Πεμ' => 4, 156*2afbbbaeSAndreas Gohr 'Παρ' => 5, 157*2afbbbaeSAndreas Gohr 'Σαβ' => 6, 158*2afbbbaeSAndreas Gohr 'Κυρ' => 7, 159*2afbbbaeSAndreas Gohr // Russian 160*2afbbbaeSAndreas Gohr 'Пн.' => 1, 161*2afbbbaeSAndreas Gohr 'Вт.' => 2, 162*2afbbbaeSAndreas Gohr 'Ср.' => 3, 163*2afbbbaeSAndreas Gohr 'Чт.' => 4, 164*2afbbbaeSAndreas Gohr 'Пт.' => 5, 165*2afbbbaeSAndreas Gohr 'Сб.' => 6, 166*2afbbbaeSAndreas Gohr 'Вс.' => 7, 167*2afbbbaeSAndreas Gohr ]; 168*2afbbbaeSAndreas Gohr 169*2afbbbaeSAndreas Gohr /** 170*2afbbbaeSAndreas Gohr * List of months, calendar month name => calendar month number 171*2afbbbaeSAndreas Gohr * 172*2afbbbaeSAndreas Gohr * @access protected 173*2afbbbaeSAndreas Gohr * @var array 174*2afbbbaeSAndreas Gohr */ 175*2afbbbaeSAndreas Gohr public $month = [ 176*2afbbbaeSAndreas Gohr // English 177*2afbbbaeSAndreas Gohr 'jan' => 1, 178*2afbbbaeSAndreas Gohr 'january' => 1, 179*2afbbbaeSAndreas Gohr 'feb' => 2, 180*2afbbbaeSAndreas Gohr 'february' => 2, 181*2afbbbaeSAndreas Gohr 'mar' => 3, 182*2afbbbaeSAndreas Gohr 'march' => 3, 183*2afbbbaeSAndreas Gohr 'apr' => 4, 184*2afbbbaeSAndreas Gohr 'april' => 4, 185*2afbbbaeSAndreas Gohr 'may' => 5, 186*2afbbbaeSAndreas Gohr // No long form of May 187*2afbbbaeSAndreas Gohr 'jun' => 6, 188*2afbbbaeSAndreas Gohr 'june' => 6, 189*2afbbbaeSAndreas Gohr 'jul' => 7, 190*2afbbbaeSAndreas Gohr 'july' => 7, 191*2afbbbaeSAndreas Gohr 'aug' => 8, 192*2afbbbaeSAndreas Gohr 'august' => 8, 193*2afbbbaeSAndreas Gohr 'sep' => 9, 194*2afbbbaeSAndreas Gohr 'september' => 9, 195*2afbbbaeSAndreas Gohr 'oct' => 10, 196*2afbbbaeSAndreas Gohr 'october' => 10, 197*2afbbbaeSAndreas Gohr 'nov' => 11, 198*2afbbbaeSAndreas Gohr 'november' => 11, 199*2afbbbaeSAndreas Gohr 'dec' => 12, 200*2afbbbaeSAndreas Gohr 'december' => 12, 201*2afbbbaeSAndreas Gohr // Dutch 202*2afbbbaeSAndreas Gohr 'januari' => 1, 203*2afbbbaeSAndreas Gohr 'februari' => 2, 204*2afbbbaeSAndreas Gohr 'maart' => 3, 205*2afbbbaeSAndreas Gohr 'april' => 4, 206*2afbbbaeSAndreas Gohr 'mei' => 5, 207*2afbbbaeSAndreas Gohr 'juni' => 6, 208*2afbbbaeSAndreas Gohr 'juli' => 7, 209*2afbbbaeSAndreas Gohr 'augustus' => 8, 210*2afbbbaeSAndreas Gohr 'september' => 9, 211*2afbbbaeSAndreas Gohr 'oktober' => 10, 212*2afbbbaeSAndreas Gohr 'november' => 11, 213*2afbbbaeSAndreas Gohr 'december' => 12, 214*2afbbbaeSAndreas Gohr // French 215*2afbbbaeSAndreas Gohr 'janvier' => 1, 216*2afbbbaeSAndreas Gohr 'février' => 2, 217*2afbbbaeSAndreas Gohr 'mars' => 3, 218*2afbbbaeSAndreas Gohr 'avril' => 4, 219*2afbbbaeSAndreas Gohr 'mai' => 5, 220*2afbbbaeSAndreas Gohr 'juin' => 6, 221*2afbbbaeSAndreas Gohr 'juillet' => 7, 222*2afbbbaeSAndreas Gohr 'août' => 8, 223*2afbbbaeSAndreas Gohr 'septembre' => 9, 224*2afbbbaeSAndreas Gohr 'octobre' => 10, 225*2afbbbaeSAndreas Gohr 'novembre' => 11, 226*2afbbbaeSAndreas Gohr 'décembre' => 12, 227*2afbbbaeSAndreas Gohr // German 228*2afbbbaeSAndreas Gohr 'januar' => 1, 229*2afbbbaeSAndreas Gohr 'jan' => 1, 230*2afbbbaeSAndreas Gohr 'februar' => 2, 231*2afbbbaeSAndreas Gohr 'feb' => 2, 232*2afbbbaeSAndreas Gohr 'märz' => 3, 233*2afbbbaeSAndreas Gohr 'mär' => 3, 234*2afbbbaeSAndreas Gohr 'april' => 4, 235*2afbbbaeSAndreas Gohr 'apr' => 4, 236*2afbbbaeSAndreas Gohr 'mai' => 5, // no short form for may 237*2afbbbaeSAndreas Gohr 'juni' => 6, 238*2afbbbaeSAndreas Gohr 'jun' => 6, 239*2afbbbaeSAndreas Gohr 'juli' => 7, 240*2afbbbaeSAndreas Gohr 'jul' => 7, 241*2afbbbaeSAndreas Gohr 'august' => 8, 242*2afbbbaeSAndreas Gohr 'aug' => 8, 243*2afbbbaeSAndreas Gohr 'september' => 9, 244*2afbbbaeSAndreas Gohr 'sep' => 9, 245*2afbbbaeSAndreas Gohr 'oktober' => 10, 246*2afbbbaeSAndreas Gohr 'okt' => 10, 247*2afbbbaeSAndreas Gohr 'november' => 11, 248*2afbbbaeSAndreas Gohr 'nov' => 11, 249*2afbbbaeSAndreas Gohr 'dezember' => 12, 250*2afbbbaeSAndreas Gohr 'dez' => 12, 251*2afbbbaeSAndreas Gohr // Italian 252*2afbbbaeSAndreas Gohr 'gennaio' => 1, 253*2afbbbaeSAndreas Gohr 'febbraio' => 2, 254*2afbbbaeSAndreas Gohr 'marzo' => 3, 255*2afbbbaeSAndreas Gohr 'aprile' => 4, 256*2afbbbaeSAndreas Gohr 'maggio' => 5, 257*2afbbbaeSAndreas Gohr 'giugno' => 6, 258*2afbbbaeSAndreas Gohr 'luglio' => 7, 259*2afbbbaeSAndreas Gohr 'agosto' => 8, 260*2afbbbaeSAndreas Gohr 'settembre' => 9, 261*2afbbbaeSAndreas Gohr 'ottobre' => 10, 262*2afbbbaeSAndreas Gohr 'novembre' => 11, 263*2afbbbaeSAndreas Gohr 'dicembre' => 12, 264*2afbbbaeSAndreas Gohr // Spanish 265*2afbbbaeSAndreas Gohr 'enero' => 1, 266*2afbbbaeSAndreas Gohr 'febrero' => 2, 267*2afbbbaeSAndreas Gohr 'marzo' => 3, 268*2afbbbaeSAndreas Gohr 'abril' => 4, 269*2afbbbaeSAndreas Gohr 'mayo' => 5, 270*2afbbbaeSAndreas Gohr 'junio' => 6, 271*2afbbbaeSAndreas Gohr 'julio' => 7, 272*2afbbbaeSAndreas Gohr 'agosto' => 8, 273*2afbbbaeSAndreas Gohr 'septiembre' => 9, 274*2afbbbaeSAndreas Gohr 'setiembre' => 9, 275*2afbbbaeSAndreas Gohr 'octubre' => 10, 276*2afbbbaeSAndreas Gohr 'noviembre' => 11, 277*2afbbbaeSAndreas Gohr 'diciembre' => 12, 278*2afbbbaeSAndreas Gohr // Finnish 279*2afbbbaeSAndreas Gohr 'tammikuu' => 1, 280*2afbbbaeSAndreas Gohr 'helmikuu' => 2, 281*2afbbbaeSAndreas Gohr 'maaliskuu' => 3, 282*2afbbbaeSAndreas Gohr 'huhtikuu' => 4, 283*2afbbbaeSAndreas Gohr 'toukokuu' => 5, 284*2afbbbaeSAndreas Gohr 'kesäkuu' => 6, 285*2afbbbaeSAndreas Gohr 'heinäkuu' => 7, 286*2afbbbaeSAndreas Gohr 'elokuu' => 8, 287*2afbbbaeSAndreas Gohr 'suuskuu' => 9, 288*2afbbbaeSAndreas Gohr 'lokakuu' => 10, 289*2afbbbaeSAndreas Gohr 'marras' => 11, 290*2afbbbaeSAndreas Gohr 'joulukuu' => 12, 291*2afbbbaeSAndreas Gohr // Hungarian 292*2afbbbaeSAndreas Gohr 'január' => 1, 293*2afbbbaeSAndreas Gohr 'február' => 2, 294*2afbbbaeSAndreas Gohr 'március' => 3, 295*2afbbbaeSAndreas Gohr 'április' => 4, 296*2afbbbaeSAndreas Gohr 'május' => 5, 297*2afbbbaeSAndreas Gohr 'június' => 6, 298*2afbbbaeSAndreas Gohr 'július' => 7, 299*2afbbbaeSAndreas Gohr 'augusztus' => 8, 300*2afbbbaeSAndreas Gohr 'szeptember' => 9, 301*2afbbbaeSAndreas Gohr 'október' => 10, 302*2afbbbaeSAndreas Gohr 'november' => 11, 303*2afbbbaeSAndreas Gohr 'december' => 12, 304*2afbbbaeSAndreas Gohr // Greek 305*2afbbbaeSAndreas Gohr 'Ιαν' => 1, 306*2afbbbaeSAndreas Gohr 'Φεβ' => 2, 307*2afbbbaeSAndreas Gohr 'Μάώ' => 3, 308*2afbbbaeSAndreas Gohr 'Μαώ' => 3, 309*2afbbbaeSAndreas Gohr 'Απρ' => 4, 310*2afbbbaeSAndreas Gohr 'Μάι' => 5, 311*2afbbbaeSAndreas Gohr 'Μαϊ' => 5, 312*2afbbbaeSAndreas Gohr 'Μαι' => 5, 313*2afbbbaeSAndreas Gohr 'Ιούν' => 6, 314*2afbbbaeSAndreas Gohr 'Ιον' => 6, 315*2afbbbaeSAndreas Gohr 'Ιούλ' => 7, 316*2afbbbaeSAndreas Gohr 'Ιολ' => 7, 317*2afbbbaeSAndreas Gohr 'Αύγ' => 8, 318*2afbbbaeSAndreas Gohr 'Αυγ' => 8, 319*2afbbbaeSAndreas Gohr 'Σεπ' => 9, 320*2afbbbaeSAndreas Gohr 'Οκτ' => 10, 321*2afbbbaeSAndreas Gohr 'Νοέ' => 11, 322*2afbbbaeSAndreas Gohr 'Δεκ' => 12, 323*2afbbbaeSAndreas Gohr // Russian 324*2afbbbaeSAndreas Gohr 'Янв' => 1, 325*2afbbbaeSAndreas Gohr 'января' => 1, 326*2afbbbaeSAndreas Gohr 'Фев' => 2, 327*2afbbbaeSAndreas Gohr 'февраля' => 2, 328*2afbbbaeSAndreas Gohr 'Мар' => 3, 329*2afbbbaeSAndreas Gohr 'марта' => 3, 330*2afbbbaeSAndreas Gohr 'Апр' => 4, 331*2afbbbaeSAndreas Gohr 'апреля' => 4, 332*2afbbbaeSAndreas Gohr 'Май' => 5, 333*2afbbbaeSAndreas Gohr 'мая' => 5, 334*2afbbbaeSAndreas Gohr 'Июн' => 6, 335*2afbbbaeSAndreas Gohr 'июня' => 6, 336*2afbbbaeSAndreas Gohr 'Июл' => 7, 337*2afbbbaeSAndreas Gohr 'июля' => 7, 338*2afbbbaeSAndreas Gohr 'Авг' => 8, 339*2afbbbaeSAndreas Gohr 'августа' => 8, 340*2afbbbaeSAndreas Gohr 'Сен' => 9, 341*2afbbbaeSAndreas Gohr 'сентября' => 9, 342*2afbbbaeSAndreas Gohr 'Окт' => 10, 343*2afbbbaeSAndreas Gohr 'октября' => 10, 344*2afbbbaeSAndreas Gohr 'Ноя' => 11, 345*2afbbbaeSAndreas Gohr 'ноября' => 11, 346*2afbbbaeSAndreas Gohr 'Дек' => 12, 347*2afbbbaeSAndreas Gohr 'декабря' => 12, 348*2afbbbaeSAndreas Gohr 349*2afbbbaeSAndreas Gohr ]; 350*2afbbbaeSAndreas Gohr 351*2afbbbaeSAndreas Gohr /** 352*2afbbbaeSAndreas Gohr * List of timezones, abbreviation => offset from UTC 353*2afbbbaeSAndreas Gohr * 354*2afbbbaeSAndreas Gohr * @access protected 355*2afbbbaeSAndreas Gohr * @var array 356*2afbbbaeSAndreas Gohr */ 357*2afbbbaeSAndreas Gohr public $timezone = [ 358*2afbbbaeSAndreas Gohr 'ACDT' => 37800, 359*2afbbbaeSAndreas Gohr 'ACIT' => 28800, 360*2afbbbaeSAndreas Gohr 'ACST' => 34200, 361*2afbbbaeSAndreas Gohr 'ACT' => -18000, 362*2afbbbaeSAndreas Gohr 'ACWDT' => 35100, 363*2afbbbaeSAndreas Gohr 'ACWST' => 31500, 364*2afbbbaeSAndreas Gohr 'AEDT' => 39600, 365*2afbbbaeSAndreas Gohr 'AEST' => 36000, 366*2afbbbaeSAndreas Gohr 'AFT' => 16200, 367*2afbbbaeSAndreas Gohr 'AKDT' => -28800, 368*2afbbbaeSAndreas Gohr 'AKST' => -32400, 369*2afbbbaeSAndreas Gohr 'AMDT' => 18000, 370*2afbbbaeSAndreas Gohr 'AMT' => -14400, 371*2afbbbaeSAndreas Gohr 'ANAST' => 46800, 372*2afbbbaeSAndreas Gohr 'ANAT' => 43200, 373*2afbbbaeSAndreas Gohr 'ART' => -10800, 374*2afbbbaeSAndreas Gohr 'AZOST' => -3600, 375*2afbbbaeSAndreas Gohr 'AZST' => 18000, 376*2afbbbaeSAndreas Gohr 'AZT' => 14400, 377*2afbbbaeSAndreas Gohr 'BIOT' => 21600, 378*2afbbbaeSAndreas Gohr 'BIT' => -43200, 379*2afbbbaeSAndreas Gohr 'BOT' => -14400, 380*2afbbbaeSAndreas Gohr 'BRST' => -7200, 381*2afbbbaeSAndreas Gohr 'BRT' => -10800, 382*2afbbbaeSAndreas Gohr 'BST' => 3600, 383*2afbbbaeSAndreas Gohr 'BTT' => 21600, 384*2afbbbaeSAndreas Gohr 'CAST' => 18000, 385*2afbbbaeSAndreas Gohr 'CAT' => 7200, 386*2afbbbaeSAndreas Gohr 'CCT' => 23400, 387*2afbbbaeSAndreas Gohr 'CDT' => -18000, 388*2afbbbaeSAndreas Gohr 'CEDT' => 7200, 389*2afbbbaeSAndreas Gohr 'CEST' => 7200, 390*2afbbbaeSAndreas Gohr 'CET' => 3600, 391*2afbbbaeSAndreas Gohr 'CGST' => -7200, 392*2afbbbaeSAndreas Gohr 'CGT' => -10800, 393*2afbbbaeSAndreas Gohr 'CHADT' => 49500, 394*2afbbbaeSAndreas Gohr 'CHAST' => 45900, 395*2afbbbaeSAndreas Gohr 'CIST' => -28800, 396*2afbbbaeSAndreas Gohr 'CKT' => -36000, 397*2afbbbaeSAndreas Gohr 'CLDT' => -10800, 398*2afbbbaeSAndreas Gohr 'CLST' => -14400, 399*2afbbbaeSAndreas Gohr 'COT' => -18000, 400*2afbbbaeSAndreas Gohr 'CST' => -21600, 401*2afbbbaeSAndreas Gohr 'CVT' => -3600, 402*2afbbbaeSAndreas Gohr 'CXT' => 25200, 403*2afbbbaeSAndreas Gohr 'DAVT' => 25200, 404*2afbbbaeSAndreas Gohr 'DTAT' => 36000, 405*2afbbbaeSAndreas Gohr 'EADT' => -18000, 406*2afbbbaeSAndreas Gohr 'EAST' => -21600, 407*2afbbbaeSAndreas Gohr 'EAT' => 10800, 408*2afbbbaeSAndreas Gohr 'ECT' => -18000, 409*2afbbbaeSAndreas Gohr 'EDT' => -14400, 410*2afbbbaeSAndreas Gohr 'EEST' => 10800, 411*2afbbbaeSAndreas Gohr 'EET' => 7200, 412*2afbbbaeSAndreas Gohr 'EGT' => -3600, 413*2afbbbaeSAndreas Gohr 'EKST' => 21600, 414*2afbbbaeSAndreas Gohr 'EST' => -18000, 415*2afbbbaeSAndreas Gohr 'FJT' => 43200, 416*2afbbbaeSAndreas Gohr 'FKDT' => -10800, 417*2afbbbaeSAndreas Gohr 'FKST' => -14400, 418*2afbbbaeSAndreas Gohr 'FNT' => -7200, 419*2afbbbaeSAndreas Gohr 'GALT' => -21600, 420*2afbbbaeSAndreas Gohr 'GEDT' => 14400, 421*2afbbbaeSAndreas Gohr 'GEST' => 10800, 422*2afbbbaeSAndreas Gohr 'GFT' => -10800, 423*2afbbbaeSAndreas Gohr 'GILT' => 43200, 424*2afbbbaeSAndreas Gohr 'GIT' => -32400, 425*2afbbbaeSAndreas Gohr 'GST' => 14400, 426*2afbbbaeSAndreas Gohr 'GST' => -7200, 427*2afbbbaeSAndreas Gohr 'GYT' => -14400, 428*2afbbbaeSAndreas Gohr 'HAA' => -10800, 429*2afbbbaeSAndreas Gohr 'HAC' => -18000, 430*2afbbbaeSAndreas Gohr 'HADT' => -32400, 431*2afbbbaeSAndreas Gohr 'HAE' => -14400, 432*2afbbbaeSAndreas Gohr 'HAP' => -25200, 433*2afbbbaeSAndreas Gohr 'HAR' => -21600, 434*2afbbbaeSAndreas Gohr 'HAST' => -36000, 435*2afbbbaeSAndreas Gohr 'HAT' => -9000, 436*2afbbbaeSAndreas Gohr 'HAY' => -28800, 437*2afbbbaeSAndreas Gohr 'HKST' => 28800, 438*2afbbbaeSAndreas Gohr 'HMT' => 18000, 439*2afbbbaeSAndreas Gohr 'HNA' => -14400, 440*2afbbbaeSAndreas Gohr 'HNC' => -21600, 441*2afbbbaeSAndreas Gohr 'HNE' => -18000, 442*2afbbbaeSAndreas Gohr 'HNP' => -28800, 443*2afbbbaeSAndreas Gohr 'HNR' => -25200, 444*2afbbbaeSAndreas Gohr 'HNT' => -12600, 445*2afbbbaeSAndreas Gohr 'HNY' => -32400, 446*2afbbbaeSAndreas Gohr 'IRDT' => 16200, 447*2afbbbaeSAndreas Gohr 'IRKST' => 32400, 448*2afbbbaeSAndreas Gohr 'IRKT' => 28800, 449*2afbbbaeSAndreas Gohr 'IRST' => 12600, 450*2afbbbaeSAndreas Gohr 'JFDT' => -10800, 451*2afbbbaeSAndreas Gohr 'JFST' => -14400, 452*2afbbbaeSAndreas Gohr 'JST' => 32400, 453*2afbbbaeSAndreas Gohr 'KGST' => 21600, 454*2afbbbaeSAndreas Gohr 'KGT' => 18000, 455*2afbbbaeSAndreas Gohr 'KOST' => 39600, 456*2afbbbaeSAndreas Gohr 'KOVST' => 28800, 457*2afbbbaeSAndreas Gohr 'KOVT' => 25200, 458*2afbbbaeSAndreas Gohr 'KRAST' => 28800, 459*2afbbbaeSAndreas Gohr 'KRAT' => 25200, 460*2afbbbaeSAndreas Gohr 'KST' => 32400, 461*2afbbbaeSAndreas Gohr 'LHDT' => 39600, 462*2afbbbaeSAndreas Gohr 'LHST' => 37800, 463*2afbbbaeSAndreas Gohr 'LINT' => 50400, 464*2afbbbaeSAndreas Gohr 'LKT' => 21600, 465*2afbbbaeSAndreas Gohr 'MAGST' => 43200, 466*2afbbbaeSAndreas Gohr 'MAGT' => 39600, 467*2afbbbaeSAndreas Gohr 'MAWT' => 21600, 468*2afbbbaeSAndreas Gohr 'MDT' => -21600, 469*2afbbbaeSAndreas Gohr 'MESZ' => 7200, 470*2afbbbaeSAndreas Gohr 'MEZ' => 3600, 471*2afbbbaeSAndreas Gohr 'MHT' => 43200, 472*2afbbbaeSAndreas Gohr 'MIT' => -34200, 473*2afbbbaeSAndreas Gohr 'MNST' => 32400, 474*2afbbbaeSAndreas Gohr 'MSDT' => 14400, 475*2afbbbaeSAndreas Gohr 'MSST' => 10800, 476*2afbbbaeSAndreas Gohr 'MST' => -25200, 477*2afbbbaeSAndreas Gohr 'MUT' => 14400, 478*2afbbbaeSAndreas Gohr 'MVT' => 18000, 479*2afbbbaeSAndreas Gohr 'MYT' => 28800, 480*2afbbbaeSAndreas Gohr 'NCT' => 39600, 481*2afbbbaeSAndreas Gohr 'NDT' => -9000, 482*2afbbbaeSAndreas Gohr 'NFT' => 41400, 483*2afbbbaeSAndreas Gohr 'NMIT' => 36000, 484*2afbbbaeSAndreas Gohr 'NOVST' => 25200, 485*2afbbbaeSAndreas Gohr 'NOVT' => 21600, 486*2afbbbaeSAndreas Gohr 'NPT' => 20700, 487*2afbbbaeSAndreas Gohr 'NRT' => 43200, 488*2afbbbaeSAndreas Gohr 'NST' => -12600, 489*2afbbbaeSAndreas Gohr 'NUT' => -39600, 490*2afbbbaeSAndreas Gohr 'NZDT' => 46800, 491*2afbbbaeSAndreas Gohr 'NZST' => 43200, 492*2afbbbaeSAndreas Gohr 'OMSST' => 25200, 493*2afbbbaeSAndreas Gohr 'OMST' => 21600, 494*2afbbbaeSAndreas Gohr 'PDT' => -25200, 495*2afbbbaeSAndreas Gohr 'PET' => -18000, 496*2afbbbaeSAndreas Gohr 'PETST' => 46800, 497*2afbbbaeSAndreas Gohr 'PETT' => 43200, 498*2afbbbaeSAndreas Gohr 'PGT' => 36000, 499*2afbbbaeSAndreas Gohr 'PHOT' => 46800, 500*2afbbbaeSAndreas Gohr 'PHT' => 28800, 501*2afbbbaeSAndreas Gohr 'PKT' => 18000, 502*2afbbbaeSAndreas Gohr 'PMDT' => -7200, 503*2afbbbaeSAndreas Gohr 'PMST' => -10800, 504*2afbbbaeSAndreas Gohr 'PONT' => 39600, 505*2afbbbaeSAndreas Gohr 'PST' => -28800, 506*2afbbbaeSAndreas Gohr 'PWT' => 32400, 507*2afbbbaeSAndreas Gohr 'PYST' => -10800, 508*2afbbbaeSAndreas Gohr 'PYT' => -14400, 509*2afbbbaeSAndreas Gohr 'RET' => 14400, 510*2afbbbaeSAndreas Gohr 'ROTT' => -10800, 511*2afbbbaeSAndreas Gohr 'SAMST' => 18000, 512*2afbbbaeSAndreas Gohr 'SAMT' => 14400, 513*2afbbbaeSAndreas Gohr 'SAST' => 7200, 514*2afbbbaeSAndreas Gohr 'SBT' => 39600, 515*2afbbbaeSAndreas Gohr 'SCDT' => 46800, 516*2afbbbaeSAndreas Gohr 'SCST' => 43200, 517*2afbbbaeSAndreas Gohr 'SCT' => 14400, 518*2afbbbaeSAndreas Gohr 'SEST' => 3600, 519*2afbbbaeSAndreas Gohr 'SGT' => 28800, 520*2afbbbaeSAndreas Gohr 'SIT' => 28800, 521*2afbbbaeSAndreas Gohr 'SRT' => -10800, 522*2afbbbaeSAndreas Gohr 'SST' => -39600, 523*2afbbbaeSAndreas Gohr 'SYST' => 10800, 524*2afbbbaeSAndreas Gohr 'SYT' => 7200, 525*2afbbbaeSAndreas Gohr 'TFT' => 18000, 526*2afbbbaeSAndreas Gohr 'THAT' => -36000, 527*2afbbbaeSAndreas Gohr 'TJT' => 18000, 528*2afbbbaeSAndreas Gohr 'TKT' => -36000, 529*2afbbbaeSAndreas Gohr 'TMT' => 18000, 530*2afbbbaeSAndreas Gohr 'TOT' => 46800, 531*2afbbbaeSAndreas Gohr 'TPT' => 32400, 532*2afbbbaeSAndreas Gohr 'TRUT' => 36000, 533*2afbbbaeSAndreas Gohr 'TVT' => 43200, 534*2afbbbaeSAndreas Gohr 'TWT' => 28800, 535*2afbbbaeSAndreas Gohr 'UYST' => -7200, 536*2afbbbaeSAndreas Gohr 'UYT' => -10800, 537*2afbbbaeSAndreas Gohr 'UZT' => 18000, 538*2afbbbaeSAndreas Gohr 'VET' => -14400, 539*2afbbbaeSAndreas Gohr 'VLAST' => 39600, 540*2afbbbaeSAndreas Gohr 'VLAT' => 36000, 541*2afbbbaeSAndreas Gohr 'VOST' => 21600, 542*2afbbbaeSAndreas Gohr 'VUT' => 39600, 543*2afbbbaeSAndreas Gohr 'WAST' => 7200, 544*2afbbbaeSAndreas Gohr 'WAT' => 3600, 545*2afbbbaeSAndreas Gohr 'WDT' => 32400, 546*2afbbbaeSAndreas Gohr 'WEST' => 3600, 547*2afbbbaeSAndreas Gohr 'WFT' => 43200, 548*2afbbbaeSAndreas Gohr 'WIB' => 25200, 549*2afbbbaeSAndreas Gohr 'WIT' => 32400, 550*2afbbbaeSAndreas Gohr 'WITA' => 28800, 551*2afbbbaeSAndreas Gohr 'WKST' => 18000, 552*2afbbbaeSAndreas Gohr 'WST' => 28800, 553*2afbbbaeSAndreas Gohr 'YAKST' => 36000, 554*2afbbbaeSAndreas Gohr 'YAKT' => 32400, 555*2afbbbaeSAndreas Gohr 'YAPT' => 36000, 556*2afbbbaeSAndreas Gohr 'YEKST' => 21600, 557*2afbbbaeSAndreas Gohr 'YEKT' => 18000, 558*2afbbbaeSAndreas Gohr ]; 559*2afbbbaeSAndreas Gohr 560*2afbbbaeSAndreas Gohr /** 561*2afbbbaeSAndreas Gohr * Cached PCRE for Date::$day 562*2afbbbaeSAndreas Gohr * 563*2afbbbaeSAndreas Gohr * @access protected 564*2afbbbaeSAndreas Gohr * @var string 565*2afbbbaeSAndreas Gohr */ 566*2afbbbaeSAndreas Gohr public $day_pcre; 567*2afbbbaeSAndreas Gohr 568*2afbbbaeSAndreas Gohr /** 569*2afbbbaeSAndreas Gohr * Cached PCRE for Date::$month 570*2afbbbaeSAndreas Gohr * 571*2afbbbaeSAndreas Gohr * @access protected 572*2afbbbaeSAndreas Gohr * @var string 573*2afbbbaeSAndreas Gohr */ 574*2afbbbaeSAndreas Gohr public $month_pcre; 575*2afbbbaeSAndreas Gohr 576*2afbbbaeSAndreas Gohr /** 577*2afbbbaeSAndreas Gohr * Array of user-added callback methods 578*2afbbbaeSAndreas Gohr * 579*2afbbbaeSAndreas Gohr * @access private 580*2afbbbaeSAndreas Gohr * @var array 581*2afbbbaeSAndreas Gohr */ 582*2afbbbaeSAndreas Gohr public $built_in = []; 583*2afbbbaeSAndreas Gohr 584*2afbbbaeSAndreas Gohr /** 585*2afbbbaeSAndreas Gohr * Array of user-added callback methods 586*2afbbbaeSAndreas Gohr * 587*2afbbbaeSAndreas Gohr * @access private 588*2afbbbaeSAndreas Gohr * @var array 589*2afbbbaeSAndreas Gohr */ 590*2afbbbaeSAndreas Gohr public $user = []; 591*2afbbbaeSAndreas Gohr 592*2afbbbaeSAndreas Gohr /** 593*2afbbbaeSAndreas Gohr * Create new Date object, and set self::day_pcre, 594*2afbbbaeSAndreas Gohr * self::month_pcre, and self::built_in 595*2afbbbaeSAndreas Gohr * 596*2afbbbaeSAndreas Gohr * @access private 597*2afbbbaeSAndreas Gohr */ 598*2afbbbaeSAndreas Gohr public function __construct() 599*2afbbbaeSAndreas Gohr { 600*2afbbbaeSAndreas Gohr $this->day_pcre = '(' . implode('|', array_keys($this->day)) . ')'; 601*2afbbbaeSAndreas Gohr $this->month_pcre = '(' . implode('|', array_keys($this->month)) . ')'; 602*2afbbbaeSAndreas Gohr 603*2afbbbaeSAndreas Gohr static $cache; 604*2afbbbaeSAndreas Gohr if (!isset($cache[get_class($this)])) { 605*2afbbbaeSAndreas Gohr $all_methods = get_class_methods($this); 606*2afbbbaeSAndreas Gohr 607*2afbbbaeSAndreas Gohr foreach ($all_methods as $method) { 608*2afbbbaeSAndreas Gohr if (strtolower(substr($method, 0, 5)) === 'date_') { 609*2afbbbaeSAndreas Gohr $cache[get_class($this)][] = $method; 610*2afbbbaeSAndreas Gohr } 611*2afbbbaeSAndreas Gohr } 612*2afbbbaeSAndreas Gohr } 613*2afbbbaeSAndreas Gohr 614*2afbbbaeSAndreas Gohr foreach ($cache[get_class($this)] as $method) { 615*2afbbbaeSAndreas Gohr $this->built_in[] = $method; 616*2afbbbaeSAndreas Gohr } 617*2afbbbaeSAndreas Gohr } 618*2afbbbaeSAndreas Gohr 619*2afbbbaeSAndreas Gohr /** 620*2afbbbaeSAndreas Gohr * Get the object 621*2afbbbaeSAndreas Gohr * 622*2afbbbaeSAndreas Gohr * @access public 623*2afbbbaeSAndreas Gohr */ 624*2afbbbaeSAndreas Gohr public static function get() 625*2afbbbaeSAndreas Gohr { 626*2afbbbaeSAndreas Gohr static $object; 627*2afbbbaeSAndreas Gohr if (!$object) { 628*2afbbbaeSAndreas Gohr $object = new Date(); 629*2afbbbaeSAndreas Gohr } 630*2afbbbaeSAndreas Gohr return $object; 631*2afbbbaeSAndreas Gohr } 632*2afbbbaeSAndreas Gohr 633*2afbbbaeSAndreas Gohr /** 634*2afbbbaeSAndreas Gohr * Parse a date 635*2afbbbaeSAndreas Gohr * 636*2afbbbaeSAndreas Gohr * @final 637*2afbbbaeSAndreas Gohr * @access public 638*2afbbbaeSAndreas Gohr * @param string $date Date to parse 639*2afbbbaeSAndreas Gohr * @return int Timestamp corresponding to date string, or false on failure 640*2afbbbaeSAndreas Gohr */ 641*2afbbbaeSAndreas Gohr public function parse($date) 642*2afbbbaeSAndreas Gohr { 643*2afbbbaeSAndreas Gohr foreach ($this->user as $method) { 644*2afbbbaeSAndreas Gohr if (($returned = call_user_func($method, $date)) !== false) { 645*2afbbbaeSAndreas Gohr return $returned; 646*2afbbbaeSAndreas Gohr } 647*2afbbbaeSAndreas Gohr } 648*2afbbbaeSAndreas Gohr 649*2afbbbaeSAndreas Gohr foreach ($this->built_in as $method) { 650*2afbbbaeSAndreas Gohr if (($returned = call_user_func([$this, $method], $date)) !== false) { 651*2afbbbaeSAndreas Gohr return $returned; 652*2afbbbaeSAndreas Gohr } 653*2afbbbaeSAndreas Gohr } 654*2afbbbaeSAndreas Gohr 655*2afbbbaeSAndreas Gohr return false; 656*2afbbbaeSAndreas Gohr } 657*2afbbbaeSAndreas Gohr 658*2afbbbaeSAndreas Gohr /** 659*2afbbbaeSAndreas Gohr * Add a callback method to parse a date 660*2afbbbaeSAndreas Gohr * 661*2afbbbaeSAndreas Gohr * @final 662*2afbbbaeSAndreas Gohr * @access public 663*2afbbbaeSAndreas Gohr * @param callable $callback 664*2afbbbaeSAndreas Gohr */ 665*2afbbbaeSAndreas Gohr public function add_callback($callback) 666*2afbbbaeSAndreas Gohr { 667*2afbbbaeSAndreas Gohr if (is_callable($callback)) { 668*2afbbbaeSAndreas Gohr $this->user[] = $callback; 669*2afbbbaeSAndreas Gohr } else { 670*2afbbbaeSAndreas Gohr trigger_error('User-supplied function must be a valid callback', E_USER_WARNING); 671*2afbbbaeSAndreas Gohr } 672*2afbbbaeSAndreas Gohr } 673*2afbbbaeSAndreas Gohr 674*2afbbbaeSAndreas Gohr /** 675*2afbbbaeSAndreas Gohr * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as 676*2afbbbaeSAndreas Gohr * well as allowing any of upper or lower case "T", horizontal tabs, or 677*2afbbbaeSAndreas Gohr * spaces to be used as the time separator (including more than one)) 678*2afbbbaeSAndreas Gohr * 679*2afbbbaeSAndreas Gohr * @access protected 680*2afbbbaeSAndreas Gohr * @return int Timestamp 681*2afbbbaeSAndreas Gohr */ 682*2afbbbaeSAndreas Gohr public function date_w3cdtf($date) 683*2afbbbaeSAndreas Gohr { 684*2afbbbaeSAndreas Gohr $pcre = <<<'PCRE' 685*2afbbbaeSAndreas Gohr / 686*2afbbbaeSAndreas Gohr ^ 687*2afbbbaeSAndreas Gohr (?P<year>[0-9]{4}) 688*2afbbbaeSAndreas Gohr (?: 689*2afbbbaeSAndreas Gohr -? 690*2afbbbaeSAndreas Gohr (?P<month>[0-9]{2}) 691*2afbbbaeSAndreas Gohr (?: 692*2afbbbaeSAndreas Gohr -? 693*2afbbbaeSAndreas Gohr (?P<day>[0-9]{2}) 694*2afbbbaeSAndreas Gohr (?: 695*2afbbbaeSAndreas Gohr [Tt\x09\x20]+ 696*2afbbbaeSAndreas Gohr (?P<hour>[0-9]{2}) 697*2afbbbaeSAndreas Gohr (?: 698*2afbbbaeSAndreas Gohr :? 699*2afbbbaeSAndreas Gohr (?P<minute>[0-9]{2}) 700*2afbbbaeSAndreas Gohr (?: 701*2afbbbaeSAndreas Gohr :? 702*2afbbbaeSAndreas Gohr (?P<second>[0-9]{2}) 703*2afbbbaeSAndreas Gohr (?: 704*2afbbbaeSAndreas Gohr . 705*2afbbbaeSAndreas Gohr (?P<second_fraction>[0-9]*) 706*2afbbbaeSAndreas Gohr )? 707*2afbbbaeSAndreas Gohr )? 708*2afbbbaeSAndreas Gohr )? 709*2afbbbaeSAndreas Gohr (?: 710*2afbbbaeSAndreas Gohr (?P<zulu>Z) 711*2afbbbaeSAndreas Gohr | (?P<tz_sign>[+\-]) 712*2afbbbaeSAndreas Gohr (?P<tz_hour>[0-9]{1,2}) 713*2afbbbaeSAndreas Gohr :? 714*2afbbbaeSAndreas Gohr (?P<tz_minute>[0-9]{1,2}) 715*2afbbbaeSAndreas Gohr ) 716*2afbbbaeSAndreas Gohr )? 717*2afbbbaeSAndreas Gohr )? 718*2afbbbaeSAndreas Gohr )? 719*2afbbbaeSAndreas Gohr $ 720*2afbbbaeSAndreas Gohr /x 721*2afbbbaeSAndreas GohrPCRE; 722*2afbbbaeSAndreas Gohr if (preg_match($pcre, $date, $match)) { 723*2afbbbaeSAndreas Gohr // Fill in empty matches and convert to proper types. 724*2afbbbaeSAndreas Gohr $year = (int) $match['year']; 725*2afbbbaeSAndreas Gohr $month = isset($match['month']) ? (int) $match['month'] : 1; 726*2afbbbaeSAndreas Gohr $day = isset($match['day']) ? (int) $match['day'] : 1; 727*2afbbbaeSAndreas Gohr $hour = isset($match['hour']) ? (int) $match['hour'] : 0; 728*2afbbbaeSAndreas Gohr $minute = isset($match['minute']) ? (int) $match['minute'] : 0; 729*2afbbbaeSAndreas Gohr $second = isset($match['second']) ? (int) $match['second'] : 0; 730*2afbbbaeSAndreas Gohr $second_fraction = isset($match['second_fraction']) ? ((int) $match['second_fraction']) / (10 ** strlen($match['second_fraction'])) : 0; 731*2afbbbaeSAndreas Gohr $tz_sign = ($match['tz_sign'] ?? '') === '-' ? -1 : 1; 732*2afbbbaeSAndreas Gohr $tz_hour = isset($match['tz_hour']) ? (int) $match['tz_hour'] : 0; 733*2afbbbaeSAndreas Gohr $tz_minute = isset($match['tz_minute']) ? (int) $match['tz_minute'] : 0; 734*2afbbbaeSAndreas Gohr 735*2afbbbaeSAndreas Gohr // Numeric timezone 736*2afbbbaeSAndreas Gohr $timezone = $tz_hour * 3600; 737*2afbbbaeSAndreas Gohr $timezone += $tz_minute * 60; 738*2afbbbaeSAndreas Gohr $timezone *= $tz_sign; 739*2afbbbaeSAndreas Gohr 740*2afbbbaeSAndreas Gohr // Convert the number of seconds to an integer, taking decimals into account 741*2afbbbaeSAndreas Gohr $second = (int) round($second + $second_fraction); 742*2afbbbaeSAndreas Gohr 743*2afbbbaeSAndreas Gohr return gmmktime($hour, $minute, $second, $month, $day, $year) - $timezone; 744*2afbbbaeSAndreas Gohr } 745*2afbbbaeSAndreas Gohr 746*2afbbbaeSAndreas Gohr return false; 747*2afbbbaeSAndreas Gohr } 748*2afbbbaeSAndreas Gohr 749*2afbbbaeSAndreas Gohr /** 750*2afbbbaeSAndreas Gohr * Remove RFC822 comments 751*2afbbbaeSAndreas Gohr * 752*2afbbbaeSAndreas Gohr * @access protected 753*2afbbbaeSAndreas Gohr * @param string $data Data to strip comments from 754*2afbbbaeSAndreas Gohr * @return string Comment stripped string 755*2afbbbaeSAndreas Gohr */ 756*2afbbbaeSAndreas Gohr public function remove_rfc2822_comments($string) 757*2afbbbaeSAndreas Gohr { 758*2afbbbaeSAndreas Gohr $string = (string) $string; 759*2afbbbaeSAndreas Gohr $position = 0; 760*2afbbbaeSAndreas Gohr $length = strlen($string); 761*2afbbbaeSAndreas Gohr $depth = 0; 762*2afbbbaeSAndreas Gohr 763*2afbbbaeSAndreas Gohr $output = ''; 764*2afbbbaeSAndreas Gohr 765*2afbbbaeSAndreas Gohr while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) { 766*2afbbbaeSAndreas Gohr $output .= substr($string, $position, $pos - $position); 767*2afbbbaeSAndreas Gohr $position = $pos + 1; 768*2afbbbaeSAndreas Gohr if ($pos === 0 || $string[$pos - 1] !== '\\') { 769*2afbbbaeSAndreas Gohr $depth++; 770*2afbbbaeSAndreas Gohr while ($depth && $position < $length) { 771*2afbbbaeSAndreas Gohr $position += strcspn($string, '()', $position); 772*2afbbbaeSAndreas Gohr if ($string[$position - 1] === '\\') { 773*2afbbbaeSAndreas Gohr $position++; 774*2afbbbaeSAndreas Gohr continue; 775*2afbbbaeSAndreas Gohr } elseif (isset($string[$position])) { 776*2afbbbaeSAndreas Gohr switch ($string[$position]) { 777*2afbbbaeSAndreas Gohr case '(': 778*2afbbbaeSAndreas Gohr $depth++; 779*2afbbbaeSAndreas Gohr break; 780*2afbbbaeSAndreas Gohr 781*2afbbbaeSAndreas Gohr case ')': 782*2afbbbaeSAndreas Gohr $depth--; 783*2afbbbaeSAndreas Gohr break; 784*2afbbbaeSAndreas Gohr } 785*2afbbbaeSAndreas Gohr $position++; 786*2afbbbaeSAndreas Gohr } else { 787*2afbbbaeSAndreas Gohr break; 788*2afbbbaeSAndreas Gohr } 789*2afbbbaeSAndreas Gohr } 790*2afbbbaeSAndreas Gohr } else { 791*2afbbbaeSAndreas Gohr $output .= '('; 792*2afbbbaeSAndreas Gohr } 793*2afbbbaeSAndreas Gohr } 794*2afbbbaeSAndreas Gohr $output .= substr($string, $position); 795*2afbbbaeSAndreas Gohr 796*2afbbbaeSAndreas Gohr return $output; 797*2afbbbaeSAndreas Gohr } 798*2afbbbaeSAndreas Gohr 799*2afbbbaeSAndreas Gohr /** 800*2afbbbaeSAndreas Gohr * Parse RFC2822's date format 801*2afbbbaeSAndreas Gohr * 802*2afbbbaeSAndreas Gohr * @access protected 803*2afbbbaeSAndreas Gohr * @return int Timestamp 804*2afbbbaeSAndreas Gohr */ 805*2afbbbaeSAndreas Gohr public function date_rfc2822($date) 806*2afbbbaeSAndreas Gohr { 807*2afbbbaeSAndreas Gohr static $pcre; 808*2afbbbaeSAndreas Gohr if (!$pcre) { 809*2afbbbaeSAndreas Gohr $wsp = '[\x09\x20]'; 810*2afbbbaeSAndreas Gohr $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)'; 811*2afbbbaeSAndreas Gohr $optional_fws = $fws . '?'; 812*2afbbbaeSAndreas Gohr $day_name = $this->day_pcre; 813*2afbbbaeSAndreas Gohr $month = $this->month_pcre; 814*2afbbbaeSAndreas Gohr $day = '([0-9]{1,2})'; 815*2afbbbaeSAndreas Gohr $hour = $minute = $second = '([0-9]{2})'; 816*2afbbbaeSAndreas Gohr $year = '([0-9]{2,4})'; 817*2afbbbaeSAndreas Gohr $num_zone = '([+\-])([0-9]{2})([0-9]{2})'; 818*2afbbbaeSAndreas Gohr $character_zone = '([A-Z]{1,5})'; 819*2afbbbaeSAndreas Gohr $zone = '(?:' . $num_zone . '|' . $character_zone . ')'; 820*2afbbbaeSAndreas Gohr $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i'; 821*2afbbbaeSAndreas Gohr } 822*2afbbbaeSAndreas Gohr if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match)) { 823*2afbbbaeSAndreas Gohr /* 824*2afbbbaeSAndreas Gohr Capturing subpatterns: 825*2afbbbaeSAndreas Gohr 1: Day name 826*2afbbbaeSAndreas Gohr 2: Day 827*2afbbbaeSAndreas Gohr 3: Month 828*2afbbbaeSAndreas Gohr 4: Year 829*2afbbbaeSAndreas Gohr 5: Hour 830*2afbbbaeSAndreas Gohr 6: Minute 831*2afbbbaeSAndreas Gohr 7: Second 832*2afbbbaeSAndreas Gohr 8: Timezone ± 833*2afbbbaeSAndreas Gohr 9: Timezone hours 834*2afbbbaeSAndreas Gohr 10: Timezone minutes 835*2afbbbaeSAndreas Gohr 11: Alphabetic timezone 836*2afbbbaeSAndreas Gohr */ 837*2afbbbaeSAndreas Gohr 838*2afbbbaeSAndreas Gohr // Find the month number 839*2afbbbaeSAndreas Gohr $month = $this->month[strtolower($match[3])]; 840*2afbbbaeSAndreas Gohr 841*2afbbbaeSAndreas Gohr // Numeric timezone 842*2afbbbaeSAndreas Gohr if ($match[8] !== '') { 843*2afbbbaeSAndreas Gohr $timezone = $match[9] * 3600; 844*2afbbbaeSAndreas Gohr $timezone += $match[10] * 60; 845*2afbbbaeSAndreas Gohr if ($match[8] === '-') { 846*2afbbbaeSAndreas Gohr $timezone = 0 - $timezone; 847*2afbbbaeSAndreas Gohr } 848*2afbbbaeSAndreas Gohr } 849*2afbbbaeSAndreas Gohr // Character timezone 850*2afbbbaeSAndreas Gohr elseif (isset($this->timezone[strtoupper($match[11])])) { 851*2afbbbaeSAndreas Gohr $timezone = $this->timezone[strtoupper($match[11])]; 852*2afbbbaeSAndreas Gohr } 853*2afbbbaeSAndreas Gohr // Assume everything else to be -0000 854*2afbbbaeSAndreas Gohr else { 855*2afbbbaeSAndreas Gohr $timezone = 0; 856*2afbbbaeSAndreas Gohr } 857*2afbbbaeSAndreas Gohr 858*2afbbbaeSAndreas Gohr // Deal with 2/3 digit years 859*2afbbbaeSAndreas Gohr if ($match[4] < 50) { 860*2afbbbaeSAndreas Gohr $match[4] += 2000; 861*2afbbbaeSAndreas Gohr } elseif ($match[4] < 1000) { 862*2afbbbaeSAndreas Gohr $match[4] += 1900; 863*2afbbbaeSAndreas Gohr } 864*2afbbbaeSAndreas Gohr 865*2afbbbaeSAndreas Gohr // Second is optional, if it is empty set it to zero 866*2afbbbaeSAndreas Gohr if ($match[7] !== '') { 867*2afbbbaeSAndreas Gohr $second = $match[7]; 868*2afbbbaeSAndreas Gohr } else { 869*2afbbbaeSAndreas Gohr $second = 0; 870*2afbbbaeSAndreas Gohr } 871*2afbbbaeSAndreas Gohr 872*2afbbbaeSAndreas Gohr return gmmktime(intval($match[5]), intval($match[6]), intval($second), intval($month), intval($match[2]), intval($match[4])) - $timezone; 873*2afbbbaeSAndreas Gohr } 874*2afbbbaeSAndreas Gohr 875*2afbbbaeSAndreas Gohr return false; 876*2afbbbaeSAndreas Gohr } 877*2afbbbaeSAndreas Gohr 878*2afbbbaeSAndreas Gohr /** 879*2afbbbaeSAndreas Gohr * Parse RFC850's date format 880*2afbbbaeSAndreas Gohr * 881*2afbbbaeSAndreas Gohr * @access protected 882*2afbbbaeSAndreas Gohr * @return int Timestamp 883*2afbbbaeSAndreas Gohr */ 884*2afbbbaeSAndreas Gohr public function date_rfc850($date) 885*2afbbbaeSAndreas Gohr { 886*2afbbbaeSAndreas Gohr static $pcre; 887*2afbbbaeSAndreas Gohr if (!$pcre) { 888*2afbbbaeSAndreas Gohr $space = '[\x09\x20]+'; 889*2afbbbaeSAndreas Gohr $day_name = $this->day_pcre; 890*2afbbbaeSAndreas Gohr $month = $this->month_pcre; 891*2afbbbaeSAndreas Gohr $day = '([0-9]{1,2})'; 892*2afbbbaeSAndreas Gohr $year = $hour = $minute = $second = '([0-9]{2})'; 893*2afbbbaeSAndreas Gohr $zone = '([A-Z]{1,5})'; 894*2afbbbaeSAndreas Gohr $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i'; 895*2afbbbaeSAndreas Gohr } 896*2afbbbaeSAndreas Gohr if (preg_match($pcre, $date, $match)) { 897*2afbbbaeSAndreas Gohr /* 898*2afbbbaeSAndreas Gohr Capturing subpatterns: 899*2afbbbaeSAndreas Gohr 1: Day name 900*2afbbbaeSAndreas Gohr 2: Day 901*2afbbbaeSAndreas Gohr 3: Month 902*2afbbbaeSAndreas Gohr 4: Year 903*2afbbbaeSAndreas Gohr 5: Hour 904*2afbbbaeSAndreas Gohr 6: Minute 905*2afbbbaeSAndreas Gohr 7: Second 906*2afbbbaeSAndreas Gohr 8: Timezone 907*2afbbbaeSAndreas Gohr */ 908*2afbbbaeSAndreas Gohr 909*2afbbbaeSAndreas Gohr // Month 910*2afbbbaeSAndreas Gohr $month = $this->month[strtolower($match[3])]; 911*2afbbbaeSAndreas Gohr 912*2afbbbaeSAndreas Gohr // Character timezone 913*2afbbbaeSAndreas Gohr if (isset($this->timezone[strtoupper($match[8])])) { 914*2afbbbaeSAndreas Gohr $timezone = $this->timezone[strtoupper($match[8])]; 915*2afbbbaeSAndreas Gohr } 916*2afbbbaeSAndreas Gohr // Assume everything else to be -0000 917*2afbbbaeSAndreas Gohr else { 918*2afbbbaeSAndreas Gohr $timezone = 0; 919*2afbbbaeSAndreas Gohr } 920*2afbbbaeSAndreas Gohr 921*2afbbbaeSAndreas Gohr // Deal with 2 digit year 922*2afbbbaeSAndreas Gohr if ($match[4] < 50) { 923*2afbbbaeSAndreas Gohr $match[4] += 2000; 924*2afbbbaeSAndreas Gohr } else { 925*2afbbbaeSAndreas Gohr $match[4] += 1900; 926*2afbbbaeSAndreas Gohr } 927*2afbbbaeSAndreas Gohr 928*2afbbbaeSAndreas Gohr return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone; 929*2afbbbaeSAndreas Gohr } 930*2afbbbaeSAndreas Gohr 931*2afbbbaeSAndreas Gohr return false; 932*2afbbbaeSAndreas Gohr } 933*2afbbbaeSAndreas Gohr 934*2afbbbaeSAndreas Gohr /** 935*2afbbbaeSAndreas Gohr * Parse C99's asctime()'s date format 936*2afbbbaeSAndreas Gohr * 937*2afbbbaeSAndreas Gohr * @access protected 938*2afbbbaeSAndreas Gohr * @return int Timestamp 939*2afbbbaeSAndreas Gohr */ 940*2afbbbaeSAndreas Gohr public function date_asctime($date) 941*2afbbbaeSAndreas Gohr { 942*2afbbbaeSAndreas Gohr static $pcre; 943*2afbbbaeSAndreas Gohr if (!$pcre) { 944*2afbbbaeSAndreas Gohr $space = '[\x09\x20]+'; 945*2afbbbaeSAndreas Gohr $wday_name = $this->day_pcre; 946*2afbbbaeSAndreas Gohr $mon_name = $this->month_pcre; 947*2afbbbaeSAndreas Gohr $day = '([0-9]{1,2})'; 948*2afbbbaeSAndreas Gohr $hour = $sec = $min = '([0-9]{2})'; 949*2afbbbaeSAndreas Gohr $year = '([0-9]{4})'; 950*2afbbbaeSAndreas Gohr $terminator = '\x0A?\x00?'; 951*2afbbbaeSAndreas Gohr $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i'; 952*2afbbbaeSAndreas Gohr } 953*2afbbbaeSAndreas Gohr if (preg_match($pcre, $date, $match)) { 954*2afbbbaeSAndreas Gohr /* 955*2afbbbaeSAndreas Gohr Capturing subpatterns: 956*2afbbbaeSAndreas Gohr 1: Day name 957*2afbbbaeSAndreas Gohr 2: Month 958*2afbbbaeSAndreas Gohr 3: Day 959*2afbbbaeSAndreas Gohr 4: Hour 960*2afbbbaeSAndreas Gohr 5: Minute 961*2afbbbaeSAndreas Gohr 6: Second 962*2afbbbaeSAndreas Gohr 7: Year 963*2afbbbaeSAndreas Gohr */ 964*2afbbbaeSAndreas Gohr 965*2afbbbaeSAndreas Gohr $month = $this->month[strtolower($match[2])]; 966*2afbbbaeSAndreas Gohr return gmmktime((int) $match[4], (int) $match[5], (int) $match[6], $month, (int) $match[3], (int) $match[7]); 967*2afbbbaeSAndreas Gohr } 968*2afbbbaeSAndreas Gohr 969*2afbbbaeSAndreas Gohr return false; 970*2afbbbaeSAndreas Gohr } 971*2afbbbaeSAndreas Gohr 972*2afbbbaeSAndreas Gohr /** 973*2afbbbaeSAndreas Gohr * Parse dates using strtotime() 974*2afbbbaeSAndreas Gohr * 975*2afbbbaeSAndreas Gohr * @access protected 976*2afbbbaeSAndreas Gohr * @return int Timestamp 977*2afbbbaeSAndreas Gohr */ 978*2afbbbaeSAndreas Gohr public function date_strtotime($date) 979*2afbbbaeSAndreas Gohr { 980*2afbbbaeSAndreas Gohr $strtotime = strtotime($date); 981*2afbbbaeSAndreas Gohr if ($strtotime === -1 || $strtotime === false) { 982*2afbbbaeSAndreas Gohr return false; 983*2afbbbaeSAndreas Gohr } 984*2afbbbaeSAndreas Gohr 985*2afbbbaeSAndreas Gohr return $strtotime; 986*2afbbbaeSAndreas Gohr } 987*2afbbbaeSAndreas Gohr} 988*2afbbbaeSAndreas Gohr 989*2afbbbaeSAndreas Gohrclass_alias('SimplePie\Parse\Date', 'SimplePie_Parse_Date'); 990