Отримати поточну дату з урахуванням часового поясу в PHP?


76

Я хочу отримати сьогоднішню дату із заданим часовим поясом у форматі Пола Еггерта ( America/New_York) у PHP?


Ви обов’язково повинні прийняти відповідь DesignerGuy або змінити заголовок свого запитання на щось на зразок "встановити часовий пояс за замовчуванням" ...
Аксель

1
@Axel Done, я вже не розробник PHP, але сподіваюся, це допоможе.
Ейнштейн

Молодці! Це було правильне рішення ІМХО ...
Аксель

Відповіді:


198

Інші відповіді встановлюють часовий пояс для всіх дат у вашій системі. Це не завжди працює добре, якщо ви хочете підтримувати кілька часових поясів для своїх користувачів.

Ось коротка версія:

<?php
$date = new DateTime("now", new DateTimeZone('America/New_York') );
echo $date->format('Y-m-d H:i:s');

Працює в PHP> = 5.2.0

Список підтримуваних часових поясів: php.net/manual/en/timezones.php


Ось версія із наявним часом та встановленням часового поясу за налаштуваннями користувача

<?php

$usersTimezone = 'America/New_York';
$date = new DateTime( 'Thu, 31 Mar 2011 02:05:59 GMT', new DateTimeZone($usersTimezone) );
echo $date->format('Y-m-d H:i:s');

Ось більш детальна версія, щоб трохи чіткіше показати процес

<?php

// Date for a specific date/time:
$date = new DateTime('Thu, 31 Mar 2011 02:05:59 GMT');

// Output date (as-is)
echo $date->format('l, F j Y g:i:s A');     

// Output line break (for testing)
echo "\n<br />\n";

// Example user timezone (to show it can be used dynamically)
$usersTimezone = 'America/New_York';

// Convert timezone
$tz = new DateTimeZone($usersTimezone);
$date->setTimeZone($tz);

// Output date after 
echo $date->format('l, F j Y g:i:s A');

Бібліотеки

  • Вуглець - Дуже популярна бібліотека побачень.
  • Chronos - заміна заміни Carbon, орієнтована на незмінність. Дивіться нижче, чому це важливо.
  • jenssegers / date - розширення Carbon, яке додає багатомовну підтримку.

Я впевнений, що існує низка інших бібліотек, але я знайомий із кількома з них.


Бонусний урок: незмінні об’єкти дати

Поки ви тут, дозвольте мені позбавити вас майбутнього головного болю. Скажімо, ви хочете обчислити 1 тиждень з сьогоднішнього дня та 2 тижні з сьогоднішнього. Ви можете написати такий код, як:

<?php

// Create a datetime (now, in this case 2017-Feb-11)
$today = new DateTime();

echo $today->format('Y-m-d') . "\n<br>";
echo "---\n<br>";

$oneWeekFromToday = $today->add(DateInterval::createFromDateString('7 days'));
$twoWeeksFromToday = $today->add(DateInterval::createFromDateString('14 days'));

echo $today->format('Y-m-d') . "\n<br>";
echo $oneWeekFromToday->format('Y-m-d') . "\n<br>";
echo $twoWeeksFromToday->format('Y-m-d') . "\n<br>";
echo "\n<br>";

Вихід:

2017-02-11 
--- 
2017-03-04 
2017-03-04 
2017-03-04

Хмммм ... Це не зовсім те, що ми хотіли. Модифікація традиційного DateTimeоб'єкта в PHP не тільки повертає оновлену дату, але також змінює оригінальний об'єкт.

Це де DateTimeImmutableвходить.

$today = new DateTimeImmutable();

echo $today->format('Y-m-d') . "\n<br>";
echo "---\n<br>";

$oneWeekFromToday = $today->add(DateInterval::createFromDateString('7 days'));
$twoWeeksFromToday = $today->add(DateInterval::createFromDateString('14 days'));

echo $today->format('Y-m-d') . "\n<br>";
echo $oneWeekFromToday->format('Y-m-d') . "\n<br>";
echo $twoWeeksFromToday->format('Y-m-d') . "\n<br>";

Вихід:

2017-02-11 
--- 
2017-02-11 
2017-02-18 
2017-02-25 

У цьому другому прикладі ми отримуємо дати, які очікували назад. Використовуючи DateTimeImmutableзамість DateTime, ми запобігаємо випадкові мутації стану та запобігаємо потенційним помилкам.


Оцініть відповідь @DesignerGuy, але ось правильний список підтримуваних часових поясів: php.net/manual/en/timezones.php
Кріс Гаррісон,

1
Це повинна бути прийнята відповідь, і якраз те, що я шукав. Дякую!
Бретт

Іноді коментування допомагає :)
Аксель,

54

Спершу встановіть часовий пояс за замовчуванням і отримайте дату, потім дата буде у вказаному часовому поясі:

<?php 
 date_default_timezone_set('America/New_York');
 $date= date('m-d-Y') ;
 ?>

http://php.net/manual/en/function.date-default-timezone-set.php


11
Зверніть увагу, що використання date_default_timezone_set()встановлює його для всього використання date()після цієї точки. Див. Мою відповідь для прикладу того, як керувати кількома часовими поясами.
Енді Флемінг

9
Наразі погана практика, якщо ви просто хочете отримати 1 дату в цьому часовому поясі, див. Відповідь DesignerGuy нижче для більш детального рішення.
Ward DS

Було б непогано мати загальний спосіб вибору часового поясу.
Зан

4

Якщо у вас є доступ до PHP 5.3, розширення intl дуже зручно робити подібні речі.

Ось приклад з посібника:

$fmt = new IntlDateFormatter( "en_US" ,IntlDateFormatter::FULL, IntlDateFormatter::FULL,
    'America/Los_Angeles',IntlDateFormatter::GREGORIAN  );
$fmt->format(0); //0 for current time/date

У вашому випадку ви можете зробити:

$fmt = new IntlDateFormatter( "en_US" ,IntlDateFormatter::FULL, IntlDateFormatter::FULL,
        'America/New_York');
 $fmt->format($datetime); //where $datetime may be a DateTime object, an integer representing a Unix timestamp value (seconds since epoch, UTC) or an array in the format output by localtime(). 

Оскільки ви можете встановити такий часовий пояс, як America/New_York, це набагато краще, ніж використання зміщення GMT або UTC, оскільки це враховує також періоди світлового дня.

Нарешті, оскільки розширення intl використовує дані ICU, що містить багато дуже корисних функцій, коли мова йде про створення власних форматів дати / часу.


4

Я створив просту функцію, яку можна використовувати для перетворення часу в будь-який часовий пояс:

function convertTimeToLocal($datetime,$timezone='Europe/Dublin') {
        $given = new DateTime($datetime, new DateTimeZone("UTC"));
        $given->setTimezone(new DateTimeZone($timezone));
        $output = $given->format("Y-m-d"); //can change as per your requirement
        return $output;
}

1
<?php
date_default_timezone_set('GMT-5');//Set New York timezone
$today = date("F j, Y")
?>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.