$epoch, 'timezone' => $timezone, ); return new PhabricatorTimeGuard(last_key(self::$stack)); } public static function popTime($key) { if ($key !== last_key(self::$stack)) { throw new Exception( pht( '%s with bad key.', __METHOD__)); } array_pop(self::$stack); if (empty(self::$stack)) { date_default_timezone_set(self::$originalZone); } else { $frame = end(self::$stack); date_default_timezone_set($frame['timezone']); } } public static function getNow() { if (self::$stack) { $frame = end(self::$stack); return $frame['epoch']; } return time(); } public static function parseLocalTime($time, PhabricatorUser $user) { $old_zone = date_default_timezone_get(); date_default_timezone_set($user->getTimezoneIdentifier()); $timestamp = (int)strtotime($time, self::getNow()); if ($timestamp <= 0) { $timestamp = null; } date_default_timezone_set($old_zone); return $timestamp; } public static function getTodayMidnightDateTime($viewer) { $timezone = new DateTimeZone($viewer->getTimezoneIdentifier()); $today = new DateTime('@'.time()); $today->setTimezone($timezone); $year = $today->format('Y'); $month = $today->format('m'); $day = $today->format('d'); $today = new DateTime("{$year}-{$month}-{$day}", $timezone); return $today; } public static function getDateTimeFromEpoch($epoch, PhabricatorUser $viewer) { $datetime = new DateTime('@'.$epoch); $datetime->setTimezone($viewer->getTimeZone()); return $datetime; } public static function getTimezoneDisplayName($raw_identifier) { // Internal identifiers have names like "America/Los_Angeles", but this is // just an implementation detail and we can render them in a more human // readable format with spaces. $name = str_replace('_', ' ', $raw_identifier); return $name; } }