summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/LocalTime.php
blob: 86070a80b5d2558802748cb008c631728b880e0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?php

namespace SMW\MediaWiki;

use DateInterval;
use DateTime;
use DateTimeZone;
use User;

/**
 * @license GNU GPL v2+
 * @since 3.0
 *
 * @author mwjames
 */
class LocalTime {

	/**
	 * @see $GLOBALS['wgLocalTZoffset']
	 * @var integer
	 */
	private static $localTimeOffset = 0;

	/**
	 * @since 3.0
	 *
	 * @param integer $localTimeOffset
	 */
	public static function setLocalTimeOffset( $localTimeOffset ) {
		self::$localTimeOffset = $localTimeOffset;
	}

	/**
	 * @see Language::userAdjust
	 *
	 * Language::userAdjust cannot be used as entirely relies on the timestamp
	 * premises making < 1970 return invalid results hence we copy the relevant
	 * part on work with the DateInterval instead.
	 *
	 * @since 3.0
	 *
	 * @param DateTime $dateTime
	 * @param User|null $user
	 *
	 * @return DateTime
	 */
	public static function getLocalizedTime( DateTime $dateTime, User $user = null ) {

		$tz = $user instanceof User ? $user->getOption( 'timecorrection' ) : false;
		$data = explode( '|', $tz, 3 );

		// DateTime is mutable, keep track of possible changes
		$dateTime->hasLocalTimeCorrection = false;

		if ( $data[0] == 'ZoneInfo' ) {
			try {
				$userTZ = new DateTimeZone( $data[2] );
				$dateTime->setTimezone( $userTZ );
				$dateTime->hasLocalTimeCorrection = true;
				return $dateTime;
			} catch ( \Exception $e ) {
				// Unrecognized timezone, default to 'Offset' with the stored offset.
				$data[0] = 'Offset';
			}
		}

		if ( $data[0] == 'System' || $tz == '' ) {
			# Global offset in minutes.
			$minDiff = self::$localTimeOffset;
		} elseif ( $data[0] == 'Offset' ) {
			$minDiff = intval( $data[1] );
		} else {
			$data = explode( ':', $tz );
			if ( count( $data ) == 2 ) {
				$data[0] = intval( $data[0] );
				$data[1] = intval( $data[1] );
				$minDiff = abs( $data[0] ) * 60 + $data[1];
				if ( $data[0] < 0 ) {
					$minDiff = -$minDiff;
				}
			} else {
				$minDiff = intval( $data[0] ) * 60;
			}
		}

		# No difference ?
		if ( 0 == $minDiff ) {
			return $dateTime;
		}

		$dateInterval = new DateInterval( "PT" . abs( $minDiff ) . "M" );

		if ( $minDiff > 0 ) {
			$dateTime->add( $dateInterval );
		} else {
			$dateTime->sub( $dateInterval );
		}

		$dateTime->hasLocalTimeCorrection = true;

		return $dateTime;
	}

}