Как я должен хранить метку времени, полученную от JS на стороне сервера, таким образом, чтобы я мог надежно использовать ее для преобразования в другие часовые пояса? - PullRequest
3 голосов
/ 28 октября 2011

У меня есть веб-сайт, на котором я настраиваю встречи для спа-центра, расположенного в западной части США, например, время PST.

Когда пользователь выбирает место, скажем, 10:00 AM @ 20 марта 2010 г.объект date, который создается со стороны клиента на моем рабочем столе и использует время EDT:

отметка времени: 1395324000000
utc строка: чт 20 марта 2014 10:00:00 GMT-0400 (EDT)

Мне нужно сохранить это на стороне сервера.В настоящее время я передаю метку времени из JS в PHP через XHR и делю на 1000:

URL-адрес ajax: ajax.php? Timestamp = 1395324000000
код php:

$time = $_GET['timestamp'] / 1000;

Поскольку мой часовой пояс по умолчанию установлен вручную на America/New_York, а мое время на стороне клиента указано в EDT, они согласованы и поэтому отображается правильное время:

echo date('M d Y H:i:s', $time); // Mar 20 2014 10:00:00

Но в идеале я думал, что долженна самом деле нужно установить дату на стороне сервера как America / Los_Angeles .. однако это заставит echo date отображать неправильную дату, так как это будет PST, а не EDT больше:

date_default_timezone_set('America/Los_Angeles');
Mar 20 2014 07:00:00

Теперь стало 7:00, когда пользователь первоначально выбрал 10:00, и это, очевидно, приводит к путанице ... Мне нужно, чтобы оно было 10:00, если пользователь выбрал 10:00.

Еще одно мое беспокойство заключается в том, что если пользовательское время пользователя не соответствует EDT?Разве это не будет соответствовать America/New_York или America/Los_Angeles?

Должен ли я делать что-то вроде сохранения строки UTC через .toUTCString в Javascript, а затем сохранения времени в UTC, и установить часовой пояс по умолчанию на UTC, а затем преобразовать его в время PST, когда мне нужно отобразитьВремя PST?

Кстати , я не могу использовать DateTimeZone или DateTime, так как я имею дело с php <5.3 </p>

Ответы [ 3 ]

1 голос
/ 29 октября 2011

Я сделал эту встречу. Это сбивает с толку.

Моим решением было (как вы предложили) хранить все как UTC, а при необходимости конвертировать это в часовой пояс пользователя.

Я сделал основную кодировку JS с date.js: http://www.datejs.com/.

Преобразование даты UTC с сервера в локальную для пользователя

var d = new Date();
var offset = d.getTimezoneOffset();
var hours =  parseInt(offset / -60);
var minutes = (offset % 60) * -1;

appointment_date = Date.parse(utc_date).add({minutes: minutes, hours:hours})

Конечно, utc_date должен быть в правильном формате - но это должно быть легко с функцией mysql date_format.

Я бы всегда сохранял дату UTC и версию этой даты в базе данных - поэтому, когда я отправляю им электронное письмо, мне не нужно вычислять их на основе их TZ

appointment_id   utc_date           user_date
1                2011-10-01 10:00   2011-10-01 16:00

Я уверен, что вы поняли.

Надеюсь, это поможет.

0 голосов
/ 08 мая 2013

Помните, что этот совет был протестирован только с веб-службой Microsoft и сгенерированным прокси-сервером и может не применяться к другим соглашениям.

Я обнаружил, что значения даты и времени интерпретируются JS в часовом поясе браузера.

В следующем примере boundsResult - это набор данных, полученный обработчиком успеха вызова веб-метода. START и END - это значения даты и времени, которые покинули сервер как UTC.

var offset_milliseconds = boundsResult[0].START.getTimezoneOffset() * 60000;
var startTime = new Date(boundsResult[0].START.getTime() - offset_milliseconds);
var endTime = new Date(boundsResult[0].END.getTime() - offset_milliseconds);

Это исправление зависит от значений, всегда оставляющих сервер как UTC. Это не необоснованное ожидание; универсальный таймфрейм - это единственный простой способ справиться с несколькими клиентскими часовыми поясами. Хранение локализованных значений вызывает проблемы.

По какой-то причине преобразование в другую сторону кажется автоматическим.

Вы можете обернуть это так:

function utcDate(date) {
  return new Date(date.getTime() - 60000 * date.getTimezoneOffset());
}

и тогда образец будет выглядеть так

var startTime = utcDate(boundsResult[0].START);
var endTime = utcDate(boundsResult[0].END);
0 голосов
/ 20 декабря 2011

Вы всегда должны хранить временные метки на сервере.Единственный раз, когда вам нужно заботиться о часовом поясе, это когда вы вводите или выводите дату в / из строки, сначала вызывая date_default_timezone_set с часовым поясом, в который дата была введена (или будет выведена)

Если вам нужно создать временную строку (или проанализировать) на сервере, вам нужно найти смещение часового пояса клиента и настроить его соответствующим образом.

Если вы отображаете время с JS на клиенте, оно будет автоматически отображаться / вводиться в местном часовом поясе.Невозможно указать браузеру использовать другой часовой пояс.Вы можете использовать только местный часовой пояс (по умолчанию) или вызвать методы getUTCxxxx, чтобы получить время по Гринвичу и настроить его самостоятельно (если вы знаете смещение часового пояса, в котором вы хотите его отобразить).Временная метка всегда одна и та же, независимо от того, какой часовой пояс.

Реальная проблема заключается в том, что вам нужно учитывать летнее время.Это большая проблема для другого вопроса.

...