15 private const FIELD_CLASS =
'mw-htmlform-timezone-field';
18 private $msgFormatter;
26 if ( isset( $params[
'options'] ) ) {
27 throw new InvalidArgumentException(
"Options should not be provided to " . __CLASS__ );
29 $params[
'placeholder-message'] ??=
'timezone-useoffset-placeholder';
30 $params[
'options'] = [];
31 parent::__construct( $params );
32 $lang = $this->mParent ? $this->mParent->getLanguage() : RequestContext::getMain()->getLanguage();
33 $langCode =
$lang->getCode();
34 $this->msgFormatter = MediaWikiServices::getInstance()->getMessageFormatterFactory()
35 ->getTextFormatter( $langCode );
36 $this->mOptions = $this->getTimezoneOptions();
42 private function getTimezoneOptions(): array {
45 $localTZoffset = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::LocalTZoffset );
46 $timeZoneList = $this->getTimeZoneList();
48 $timestamp = MWTimestamp::getLocalInstance();
50 if ( $localTZoffset === (
int)$timestamp->format(
'Z' ) / 60 ) {
51 $timezoneName = $timestamp->getTimezone()->getName();
53 if ( isset( $timeZoneList[$timezoneName] ) ) {
54 $timezoneName = $timeZoneList[$timezoneName][
'name'];
56 $server_tz_msg = $this->msgFormatter->format(
57 MessageValue::new(
'timezoneuseserverdefault', [ $timezoneName ] )
60 $tzstring = UserTimeCorrection::formatTimezoneOffset( $localTZoffset );
61 $server_tz_msg = $this->msgFormatter->format(
62 MessageValue::new(
'timezoneuseserverdefault', [ $tzstring ] )
65 $opt[$server_tz_msg] =
"System|$localTZoffset";
66 $opt[$this->msgFormatter->format( MessageValue::new(
'timezoneuseoffset' ) )] =
'other';
67 $opt[$this->msgFormatter->format( MessageValue::new(
'guesstimezone' ) )] =
'guess';
69 foreach ( $timeZoneList as $timeZoneInfo ) {
70 $region = $timeZoneInfo[
'region'];
71 if ( !isset( $opt[$region] ) ) {
74 $opt[$region][$timeZoneInfo[
'name']] = $timeZoneInfo[
'timecorrection'];
85 private function getTimeZoneList(): array {
86 $identifiers = DateTimeZone::listIdentifiers();
87 '@phan-var array|false $identifiers';
88 if ( $identifiers ===
false ) {
94 'Africa' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-africa' ) ),
95 'America' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-america' ) ),
96 'Antarctica' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-antarctica' ) ),
97 'Arctic' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-arctic' ) ),
98 'Asia' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-asia' ) ),
99 'Atlantic' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-atlantic' ) ),
100 'Australia' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-australia' ) ),
101 'Europe' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-europe' ) ),
102 'Indian' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-indian' ) ),
103 'Pacific' => $this->msgFormatter->format( MessageValue::new(
'timezoneregion-pacific' ) ),
109 $now =
new DateTime();
111 foreach ( $identifiers as $identifier ) {
112 $parts = explode(
'/', $identifier, 2 );
117 if ( count( $parts ) !== 2 || !array_key_exists( $parts[0], $tzRegions ) ) {
122 $parts[0] = $tzRegions[$parts[0]];
124 $dateTimeZone =
new DateTimeZone( $identifier );
125 $minDiff = floor( $dateTimeZone->getOffset( $now ) / 60 );
127 $display = str_replace(
'_',
' ', $parts[0] .
'/' . $parts[1] );
128 $value =
"ZoneInfo|$minDiff|$identifier";
130 $timeZoneList[$identifier] = [
132 'timecorrection' => $value,
133 'region' => $parts[0],
137 return $timeZoneList;
144 $p = parent::validate( $value, $alldata );
150 return $this->mParent->msg(
'timezone-invalid' )->escaped();
160 $classes = parent::getFieldClasses();
161 $classes[] = self::FIELD_CLASS;