Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
36.96% |
17 / 46 |
|
16.67% |
1 / 6 |
CRAP | |
0.00% |
0 / 1 |
| MWTimestamp | |
37.78% |
17 / 45 |
|
16.67% |
1 / 6 |
34.09 | |
0.00% |
0 / 1 |
| getInstance | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| fromMW | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
| offsetForUser | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
6 | |||
| getRelativeTimestamp | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
2 | |||
| getTimezoneMessage | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
| getLocalInstance | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Creation and parsing of MW-style timestamps. |
| 4 | * |
| 5 | * @license GPL-2.0-or-later |
| 6 | * @file |
| 7 | * @since 1.20 |
| 8 | * @author Tyler Romeo, 2012 |
| 9 | */ |
| 10 | |
| 11 | namespace MediaWiki\Utils; |
| 12 | |
| 13 | use DateInterval; |
| 14 | use DateTime; |
| 15 | use DateTimeZone; |
| 16 | use MediaWiki\Context\RequestContext; |
| 17 | use MediaWiki\HookContainer\HookRunner; |
| 18 | use MediaWiki\Language\Language; |
| 19 | use MediaWiki\Language\RawMessage; |
| 20 | use MediaWiki\MainConfigNames; |
| 21 | use MediaWiki\MediaWikiServices; |
| 22 | use MediaWiki\Message\Message; |
| 23 | use MediaWiki\User\User; |
| 24 | use MediaWiki\User\UserIdentity; |
| 25 | use MediaWiki\User\UserTimeCorrection; |
| 26 | use Wikimedia\Timestamp\ConvertibleTimestamp; |
| 27 | |
| 28 | /** |
| 29 | * Library for creating and parsing MW-style timestamps. Based on the JS |
| 30 | * library that does the same thing. |
| 31 | * |
| 32 | * @newable |
| 33 | * |
| 34 | * @since 1.20 |
| 35 | */ |
| 36 | class MWTimestamp extends ConvertibleTimestamp { |
| 37 | /** |
| 38 | * Get a timestamp instance in GMT |
| 39 | * |
| 40 | * @param bool|string $ts Timestamp to set, or false for current time |
| 41 | */ |
| 42 | public static function getInstance( $ts = false ): static { |
| 43 | return new static( $ts ); |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * Convert a TS::MW format string, with optional time zone, to |
| 48 | * a MWTimestamp. |
| 49 | * |
| 50 | * This is more efficient that using the general constructor, |
| 51 | * which has a long list of string formats that it attempts to |
| 52 | * match against. |
| 53 | */ |
| 54 | public static function fromMW( string $ts_mw, ?DateTimeZone $zone = null ): static { |
| 55 | $date = DateTime::createFromFormat( |
| 56 | 'YmdHis', $ts_mw, $zone ?: new DateTimeZone( 'UTC' ) |
| 57 | ); |
| 58 | return new static( $date ); |
| 59 | } |
| 60 | |
| 61 | /** |
| 62 | * Adjust the timestamp depending on the given user's preferences. |
| 63 | * |
| 64 | * @since 1.22 |
| 65 | * |
| 66 | * @param UserIdentity $user User to take preferences from |
| 67 | * @return DateInterval Offset that was applied to the timestamp |
| 68 | */ |
| 69 | public function offsetForUser( UserIdentity $user ) { |
| 70 | $option = MediaWikiServices::getInstance()->getUserOptionsLookup()->getOption( $user, 'timecorrection' ); |
| 71 | |
| 72 | $value = new UserTimeCorrection( |
| 73 | $option, |
| 74 | $this->timestamp, |
| 75 | MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::LocalTZoffset ) |
| 76 | ); |
| 77 | $tz = $value->getTimeZone(); |
| 78 | if ( $tz ) { |
| 79 | $this->timestamp->setTimezone( $tz ); |
| 80 | return new DateInterval( 'P0Y' ); |
| 81 | } |
| 82 | $interval = $value->getTimeOffsetInterval(); |
| 83 | $this->timestamp->add( $interval ); |
| 84 | return $interval; |
| 85 | } |
| 86 | |
| 87 | /** |
| 88 | * Generate a purely relative timestamp, i.e., represent the time elapsed between |
| 89 | * the given base timestamp and this object. |
| 90 | * |
| 91 | * @param MWTimestamp|null $relativeTo Relative base timestamp (defaults to now) |
| 92 | * @param UserIdentity|null $user Use to use offset for |
| 93 | * @param Language|null $lang Language to use |
| 94 | * @param array $chosenIntervals Intervals to use to represent it |
| 95 | * @return string Relative timestamp |
| 96 | */ |
| 97 | public function getRelativeTimestamp( |
| 98 | ?MWTimestamp $relativeTo = null, |
| 99 | ?UserIdentity $user = null, |
| 100 | ?Language $lang = null, |
| 101 | array $chosenIntervals = [] |
| 102 | ) { |
| 103 | $relativeTo ??= new self(); |
| 104 | $user ??= RequestContext::getMain()->getUser(); |
| 105 | $lang ??= RequestContext::getMain()->getLanguage(); |
| 106 | |
| 107 | $ts = ''; |
| 108 | $diff = $this->diff( $relativeTo ); |
| 109 | |
| 110 | $user = User::newFromIdentity( $user ); // For compatibility with the hook signature |
| 111 | if ( ( new HookRunner( MediaWikiServices::getInstance()->getHookContainer() ) )->onGetRelativeTimestamp( |
| 112 | $ts, |
| 113 | $diff, |
| 114 | $this, |
| 115 | $relativeTo, |
| 116 | $user, |
| 117 | $lang |
| 118 | ) ) { |
| 119 | $seconds = ( ( ( $diff->days * 24 + $diff->h ) * 60 + $diff->i ) * 60 + $diff->s ); |
| 120 | $ts = wfMessage( 'ago', $lang->formatDuration( $seconds, $chosenIntervals ) )->inLanguage( $lang )->text(); |
| 121 | } |
| 122 | |
| 123 | return $ts; |
| 124 | } |
| 125 | |
| 126 | /** |
| 127 | * Get the localized timezone message, if available. |
| 128 | * |
| 129 | * Premade translations are not shipped as format() may return whatever the |
| 130 | * system uses, localized or not, so translation must be done through wiki. |
| 131 | * |
| 132 | * @since 1.27 |
| 133 | * @return Message The localized timezone message |
| 134 | */ |
| 135 | public function getTimezoneMessage() { |
| 136 | $tzMsg = $this->format( 'T' ); // might vary on DST changeover! |
| 137 | $key = 'timezone-' . strtolower( trim( $tzMsg ) ); |
| 138 | $msg = wfMessage( $key ); |
| 139 | if ( $msg->exists() ) { |
| 140 | return $msg; |
| 141 | } |
| 142 | |
| 143 | return new RawMessage( $tzMsg ); |
| 144 | } |
| 145 | |
| 146 | /** |
| 147 | * Get a timestamp instance in the server local timezone ($wgLocaltimezone) |
| 148 | * |
| 149 | * @since 1.22 |
| 150 | * @param bool|string $ts Timestamp to set, or false for current time |
| 151 | * @return MWTimestamp The local instance |
| 152 | */ |
| 153 | public static function getLocalInstance( $ts = false ) { |
| 154 | $localtimezone = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::Localtimezone ); |
| 155 | $timestamp = new self( $ts ); |
| 156 | $timestamp->setTimezone( $localtimezone ); |
| 157 | return $timestamp; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | /** @deprecated class alias since 1.41 */ |
| 162 | class_alias( MWTimestamp::class, 'MWTimestamp' ); |