MediaWiki  1.23.2
MWTimestamp.php
Go to the documentation of this file.
1 <?php
31 class MWTimestamp {
35  private static $formats = array(
36  TS_UNIX => 'U',
37  TS_MW => 'YmdHis',
38  TS_DB => 'Y-m-d H:i:s',
39  TS_ISO_8601 => 'Y-m-d\TH:i:s\Z',
40  TS_ISO_8601_BASIC => 'Ymd\THis\Z',
41  TS_EXIF => 'Y:m:d H:i:s', // This shouldn't ever be used, but is included for completeness
42  TS_RFC2822 => 'D, d M Y H:i:s',
43  TS_ORACLE => 'd-m-Y H:i:s.000000', // Was 'd-M-y h.i.s A' . ' +00:00' before r51500
44  TS_POSTGRES => 'Y-m-d H:i:s',
45  );
46 
51  public $timestamp;
52 
61  public function __construct( $timestamp = false ) {
62  $this->setTimestamp( $timestamp );
63  }
64 
76  public function setTimestamp( $ts = false ) {
77  $da = array();
78  $strtime = '';
79 
80  if ( !$ts || $ts === "\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ) { // We want to catch 0, '', null... but not date strings starting with a letter.
81  $uts = time();
82  $strtime = "@$uts";
83  } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
84  # TS_DB
85  } elseif ( preg_match( '/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
86  # TS_EXIF
87  } elseif ( preg_match( '/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/D', $ts, $da ) ) {
88  # TS_MW
89  } elseif ( preg_match( '/^-?\d{1,13}$/D', $ts ) ) {
90  # TS_UNIX
91  $strtime = "@$ts"; // http://php.net/manual/en/datetime.formats.compound.php
92  } elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
93  # TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
94  $strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
95  str_replace( '+00:00', 'UTC', $ts ) );
96  } elseif ( preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z?$/', $ts, $da ) ) {
97  # TS_ISO_8601
98  } elseif ( preg_match( '/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(?:\.*\d*)?Z?$/', $ts, $da ) ) {
99  #TS_ISO_8601_BASIC
100  } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d*[\+\- ](\d\d)$/', $ts, $da ) ) {
101  # TS_POSTGRES
102  } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d* GMT$/', $ts, $da ) ) {
103  # TS_POSTGRES
104  } elseif ( preg_match( '/^[ \t\r\n]*([A-Z][a-z]{2},[ \t\r\n]*)?' . # Day of week
105  '\d\d?[ \t\r\n]*[A-Z][a-z]{2}[ \t\r\n]*\d{2}(?:\d{2})?' . # dd Mon yyyy
106  '[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d/S', $ts ) ) { # hh:mm:ss
107  # TS_RFC2822, accepting a trailing comment. See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html / r77171
108  # The regex is a superset of rfc2822 for readability
109  $strtime = strtok( $ts, ';' );
110  } elseif ( preg_match( '/^[A-Z][a-z]{5,8}, \d\d-[A-Z][a-z]{2}-\d{2} \d\d:\d\d:\d\d/', $ts ) ) {
111  # TS_RFC850
112  $strtime = $ts;
113  } elseif ( preg_match( '/^[A-Z][a-z]{2} [A-Z][a-z]{2} +\d{1,2} \d\d:\d\d:\d\d \d{4}/', $ts ) ) {
114  # asctime
115  $strtime = $ts;
116  } else {
117  throw new TimestampException( __METHOD__ . ": Invalid timestamp - $ts" );
118  }
119 
120  if ( !$strtime ) {
121  $da = array_map( 'intval', $da );
122  $da[0] = "%04d-%02d-%02dT%02d:%02d:%02d.00+00:00";
123  $strtime = call_user_func_array( "sprintf", $da );
124  }
125 
126  try {
127  $final = new DateTime( $strtime, new DateTimeZone( 'GMT' ) );
128  } catch ( Exception $e ) {
129  throw new TimestampException( __METHOD__ . ': Invalid timestamp format.', $e->getCode(), $e );
130  }
131 
132  if ( $final === false ) {
133  throw new TimestampException( __METHOD__ . ': Invalid timestamp format.' );
134  }
135  $this->timestamp = $final;
136  }
137 
150  public function getTimestamp( $style = TS_UNIX ) {
151  if ( !isset( self::$formats[$style] ) ) {
152  throw new TimestampException( __METHOD__ . ': Illegal timestamp output type.' );
153  }
154 
155  $output = $this->timestamp->format( self::$formats[$style] );
156 
157  if ( ( $style == TS_RFC2822 ) || ( $style == TS_POSTGRES ) ) {
158  $output .= ' GMT';
159  }
160 
161  return $output;
162  }
163 
179  public function getHumanTimestamp( MWTimestamp $relativeTo = null, User $user = null, Language $lang = null ) {
180  if ( $relativeTo === null ) {
181  $relativeTo = new self();
182  }
183  if ( $user === null ) {
184  $user = RequestContext::getMain()->getUser();
185  }
186  if ( $lang === null ) {
187  $lang = RequestContext::getMain()->getLanguage();
188  }
189 
190  // Adjust for the user's timezone.
191  $offsetThis = $this->offsetForUser( $user );
192  $offsetRel = $relativeTo->offsetForUser( $user );
193 
194  $ts = '';
195  if ( wfRunHooks( 'GetHumanTimestamp', array( &$ts, $this, $relativeTo, $user, $lang ) ) ) {
196  $ts = $lang->getHumanTimestamp( $this, $relativeTo, $user );
197  }
198 
199  // Reset the timezone on the objects.
200  $this->timestamp->sub( $offsetThis );
201  $relativeTo->timestamp->sub( $offsetRel );
202 
203  return $ts;
204  }
205 
215  public function offsetForUser( User $user ) {
216  global $wgLocalTZoffset;
217 
218  $option = $user->getOption( 'timecorrection' );
219  $data = explode( '|', $option, 3 );
220 
221  // First handle the case of an actual timezone being specified.
222  if ( $data[0] == 'ZoneInfo' ) {
223  try {
224  $tz = new DateTimeZone( $data[2] );
225  } catch ( Exception $e ) {
226  $tz = false;
227  }
228 
229  if ( $tz ) {
230  $this->timestamp->setTimezone( $tz );
231  return new DateInterval( 'P0Y' );
232  } else {
233  $data[0] = 'Offset';
234  }
235  }
236 
237  $diff = 0;
238  // If $option is in fact a pipe-separated value, check the
239  // first value.
240  if ( $data[0] == 'System' ) {
241  // First value is System, so use the system offset.
242  if ( isset( $wgLocalTZoffset ) ) {
243  $diff = $wgLocalTZoffset;
244  }
245  } elseif ( $data[0] == 'Offset' ) {
246  // First value is Offset, so use the specified offset
247  $diff = (int)$data[1];
248  } else {
249  // $option actually isn't a pipe separated value, but instead
250  // a comma separated value. Isn't MediaWiki fun?
251  $data = explode( ':', $option );
252  if ( count( $data ) >= 2 ) {
253  // Combination hours and minutes.
254  $diff = abs( (int)$data[0] ) * 60 + (int)$data[1];
255  if ( (int)$data[0] < 0 ) {
256  $diff *= -1;
257  }
258  } else {
259  // Just hours.
260  $diff = (int)$data[0] * 60;
261  }
262  }
263 
264  $interval = new DateInterval( 'PT' . abs( $diff ) . 'M' );
265  if ( $diff < 1 ) {
266  $interval->invert = 1;
267  }
268 
269  $this->timestamp->add( $interval );
270  return $interval;
271  }
272 
283  public function getRelativeTimestamp(
284  MWTimestamp $relativeTo = null,
285  User $user = null,
286  Language $lang = null,
287  array $chosenIntervals = array()
288  ) {
289  if ( $relativeTo === null ) {
290  $relativeTo = new self;
291  }
292  if ( $user === null ) {
293  $user = RequestContext::getMain()->getUser();
294  }
295  if ( $lang === null ) {
296  $lang = RequestContext::getMain()->getLanguage();
297  }
298 
299  $ts = '';
300  $diff = $this->diff( $relativeTo );
301  if ( wfRunHooks( 'GetRelativeTimestamp', array( &$ts, &$diff, $this, $relativeTo, $user, $lang ) ) ) {
302  $seconds = ( ( ( $diff->days * 24 + $diff->h ) * 60 + $diff->i ) * 60 + $diff->s );
303  $ts = wfMessage( 'ago', $lang->formatDuration( $seconds, $chosenIntervals ) )
304  ->inLanguage( $lang )
305  ->text();
306  }
307 
308  return $ts;
309  }
310 
316  public function __toString() {
317  return $this->getTimestamp();
318  }
319 
327  public function diff( MWTimestamp $relativeTo ) {
328  return $this->timestamp->diff( $relativeTo->timestamp );
329  }
330 
338  public function setTimezone( $timezone ) {
339  try {
340  $this->timestamp->setTimezone( new DateTimeZone( $timezone ) );
341  } catch ( Exception $e ) {
342  throw new TimestampException( __METHOD__ . ': Invalid timezone.', $e->getCode(), $e );
343  }
344  }
345 
352  public function getTimezone() {
353  return $this->timestamp->getTimezone();
354  }
355 
363  public function format( $format ) {
364  return $this->timestamp->format( $format );
365  }
366 
374  public static function getLocalInstance( $ts = false ) {
375  global $wgLocaltimezone;
376  $timestamp = new self( $ts );
377  $timestamp->setTimezone( $wgLocaltimezone );
378  return $timestamp;
379  }
380 
388  public static function getInstance( $ts = false ) {
389  return new self( $ts );
390  }
391 }
MWTimestamp
Library for creating and parsing MW-style timestamps.
Definition: MWTimestamp.php:31
MWTimestamp\getRelativeTimestamp
getRelativeTimestamp(MWTimestamp $relativeTo=null, User $user=null, Language $lang=null, array $chosenIntervals=array())
Generate a purely relative timestamp, i.e., represent the time elapsed between the given base timesta...
Definition: MWTimestamp.php:282
of
globals txt Globals are evil The original MediaWiki code relied on globals for processing context far too often MediaWiki development since then has been a story of slowly moving context out of global variables and into objects Storing processing context in object member variables allows those objects to be reused in a much more flexible way Consider the elegance of
Definition: globals.txt:10
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
TS_EXIF
const TS_EXIF
An Exif timestamp (YYYY:MM:DD HH:MM:SS)
Definition: GlobalFunctions.php:2457
TS_DB
const TS_DB
MySQL DATETIME (YYYY-MM-DD HH:MM:SS)
Definition: GlobalFunctions.php:2436
MWTimestamp\getTimezone
getTimezone()
Get the timezone of this timestamp.
Definition: MWTimestamp.php:351
MWTimestamp\__construct
__construct( $timestamp=false)
Make a new timestamp and set it to the specified time, or the current time if unspecified.
Definition: MWTimestamp.php:60
TS_ORACLE
const TS_ORACLE
Oracle format time.
Definition: GlobalFunctions.php:2462
MWTimestamp\format
format( $format)
Format the timestamp in a given format.
Definition: MWTimestamp.php:362
MWTimestamp\offsetForUser
offsetForUser(User $user)
Adjust the timestamp depending on the given user's preferences.
Definition: MWTimestamp.php:214
TS_ISO_8601
const TS_ISO_8601
ISO 8601 format with no timezone: 1986-02-09T20:00:00Z.
Definition: GlobalFunctions.php:2448
wfMessage
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing after in associative array form externallinks including delete and has completed for all link tables default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt
wfRunHooks
wfRunHooks( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in $wgHooks.
Definition: GlobalFunctions.php:4001
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
MWTimestamp\getInstance
static getInstance( $ts=false)
Get a timestamp instance in GMT.
Definition: MWTimestamp.php:387
MWTimestamp\getTimestamp
getTimestamp( $style=TS_UNIX)
Get the timestamp represented by this object in a certain form.
Definition: MWTimestamp.php:149
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
MWTimestamp\setTimezone
setTimezone( $timezone)
Set the timezone of this timestamp to the specified timezone.
Definition: MWTimestamp.php:337
TS_MW
const TS_MW
MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
Definition: GlobalFunctions.php:2431
TS_ISO_8601_BASIC
const TS_ISO_8601_BASIC
ISO 8601 basic format with no timezone: 19860209T200000Z.
Definition: GlobalFunctions.php:2472
MWTimestamp\__toString
__toString()
Definition: MWTimestamp.php:315
MWTimestamp\$formats
static $formats
Standard gmdate() formats for the different timestamp types.
Definition: MWTimestamp.php:35
TimestampException
Definition: TimestampException.php:6
RequestContext\getMain
static getMain()
Static methods.
Definition: RequestContext.php:420
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:237
TS_UNIX
const TS_UNIX
Unix time - the number of seconds since 1970-01-01 00:00:00 UTC.
Definition: GlobalFunctions.php:2426
$output
& $output
Definition: hooks.txt:375
MWTimestamp\setTimestamp
setTimestamp( $ts=false)
Set the timestamp to the specified time, or the current time if unspecified.
Definition: MWTimestamp.php:75
TS_POSTGRES
const TS_POSTGRES
Postgres format time.
Definition: GlobalFunctions.php:2467
MWTimestamp\diff
diff(MWTimestamp $relativeTo)
Calculate the difference between two MWTimestamp objects.
Definition: MWTimestamp.php:326
$e
if( $useReadline) $e
Definition: eval.php:66
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:59
MWTimestamp\getLocalInstance
static getLocalInstance( $ts=false)
Get a timestamp instance in the server local timezone ($wgLocaltimezone)
Definition: MWTimestamp.php:373
MWTimestamp\getHumanTimestamp
getHumanTimestamp(MWTimestamp $relativeTo=null, User $user=null, Language $lang=null)
Get the timestamp in a human-friendly relative format, e.g., "3 days ago".
Definition: MWTimestamp.php:178
TS_RFC2822
const TS_RFC2822
RFC 2822 format, for E-mail and HTTP headers.
Definition: GlobalFunctions.php:2441
Language
Internationalisation code.
Definition: Language.php:74
MWTimestamp\$timestamp
DateTime $timestamp
The actual timestamp being wrapped (DateTime object).
Definition: MWTimestamp.php:50