datetimezone.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <?php
  2. /**
  3. * @author Joas Schilling <nickvergessen@owncloud.com>
  4. * @author Morris Jobke <hey@morrisjobke.de>
  5. *
  6. * @copyright Copyright (c) 2015, ownCloud, Inc.
  7. * @license AGPL-3.0
  8. *
  9. * This code is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License, version 3,
  11. * as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License, version 3,
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>
  20. *
  21. */
  22. namespace OC;
  23. use OCP\IConfig;
  24. use OCP\IDateTimeZone;
  25. use OCP\ISession;
  26. class DateTimeZone implements IDateTimeZone {
  27. /** @var IConfig */
  28. protected $config;
  29. /** @var ISession */
  30. protected $session;
  31. /**
  32. * Constructor
  33. *
  34. * @param IConfig $config
  35. * @param ISession $session
  36. */
  37. public function __construct(IConfig $config, ISession $session) {
  38. $this->config = $config;
  39. $this->session = $session;
  40. }
  41. /**
  42. * Get the timezone of the current user, based on his session information and config data
  43. *
  44. * @param bool|int $timestamp
  45. * @return \DateTimeZone
  46. */
  47. public function getTimeZone($timestamp = false) {
  48. $timeZone = $this->config->getUserValue($this->session->get('user_id'), 'core', 'timezone', null);
  49. if ($timeZone === null) {
  50. if ($this->session->exists('timezone')) {
  51. return $this->guessTimeZoneFromOffset($this->session->get('timezone'), $timestamp);
  52. }
  53. $timeZone = $this->getDefaultTimeZone();
  54. }
  55. try {
  56. return new \DateTimeZone($timeZone);
  57. } catch (\Exception $e) {
  58. \OCP\Util::writeLog('datetimezone', 'Failed to created DateTimeZone "' . $timeZone . "'", \OCP\Util::DEBUG);
  59. return new \DateTimeZone($this->getDefaultTimeZone());
  60. }
  61. }
  62. /**
  63. * Guess the DateTimeZone for a given offset
  64. *
  65. * We first try to find a Etc/GMT* timezone, if that does not exist,
  66. * we try to find it manually, before falling back to UTC.
  67. *
  68. * @param mixed $offset
  69. * @param bool|int $timestamp
  70. * @return \DateTimeZone
  71. */
  72. protected function guessTimeZoneFromOffset($offset, $timestamp) {
  73. try {
  74. // Note: the timeZone name is the inverse to the offset,
  75. // so a positive offset means negative timeZone
  76. // and the other way around.
  77. if ($offset > 0) {
  78. $timeZone = 'Etc/GMT-' . $offset;
  79. } else {
  80. $timeZone = 'Etc/GMT+' . abs($offset);
  81. }
  82. return new \DateTimeZone($timeZone);
  83. } catch (\Exception $e) {
  84. // If the offset has no Etc/GMT* timezone,
  85. // we try to guess one timezone that has the same offset
  86. foreach (\DateTimeZone::listIdentifiers() as $timeZone) {
  87. $dtz = new \DateTimeZone($timeZone);
  88. $dateTime = new \DateTime();
  89. if ($timestamp !== false) {
  90. $dateTime->setTimestamp($timestamp);
  91. }
  92. $dtOffset = $dtz->getOffset($dateTime);
  93. if ($dtOffset == 3600 * $offset) {
  94. return $dtz;
  95. }
  96. }
  97. // No timezone found, fallback to UTC
  98. \OCP\Util::writeLog('datetimezone', 'Failed to find DateTimeZone for offset "' . $offset . "'", \OCP\Util::DEBUG);
  99. return new \DateTimeZone($this->getDefaultTimeZone());
  100. }
  101. }
  102. /**
  103. * Get the default timezone of the server
  104. *
  105. * Falls back to UTC if it is not yet set.
  106. *
  107. * @return string
  108. */
  109. protected function getDefaultTimeZone() {
  110. $serverTimeZone = date_default_timezone_get();
  111. return $serverTimeZone ?: 'UTC';
  112. }
  113. }