Привет, ребята, этот будет чокнутым:
Итак, какое-то время я работал над продуктом для своего работодателя, и мы близки к запуску.Но мы буквально просто поняли, что нарисовали себя в углу.
Мы никогда не учитывали часовые пояса, когда дело доходит до их отображения.Мы храним время в полях datetime, которые хранятся в нашем местном (EST) часовом поясе.
Предполагается, что мы добавляем поле в таблицу клиентов, чтобы определить, в каком часовом поясе они находятся, как лучше преобразовать это время на уровне отображения и когда мы принимаем временные метки от пользователя (например, поле ввода)преобразуйте его обратно в EST для хранения.
Для нашей архитектуры абстракции базы данных мы используем подход класса таблиц.Я не уверен в причудливом названии этого метода, но в основном каждая таблица, которую мы используем, имеет класс со схемой базы данных в виде PHP-кода, например:
Этот код будет для таблицы с именем L2FU_notification
<?php
class L2FU_notificationbase extends dbobject
{
protected $EmailSentTimestamp;
protected $hasBeenEmailed;
protected $HasBeenViewed;
protected $notificationGeneratedDate;
protected $NotificationID;
protected $notificationText;
protected $notificationTitle;
protected $releaseDate;
protected $xtelelinkTarget;
protected $xtelelinkToBeNotified;
protected $fields = array('EmailSentTimestamp',
'hasBeenEmailed',
'HasBeenViewed',
'notificationGeneratedDate',
'NotificationID'
);
protected $table = "L2FU_notification";
protected $primaryKey = "NotificationID";
function getEmailSentTimestamp()
{
return $this->EmailSentTimestamp;
}
function setEmailSentTimestamp($EmailSentTimestamp)
{
$this->changedFields[] = 'EmailSentTimestamp';
$this->EmailSentTimestamp = $EmailSentTimestamp;
return $this;
}
function gethasBeenEmailed()
{
return $this->hasBeenEmailed;
}
function sethasBeenEmailed($hasBeenEmailed)
{
$this->changedFields[] = 'hasBeenEmailed';
$this->hasBeenEmailed = $hasBeenEmailed;
return $this;
}
function getHasBeenViewed()
{
return $this->HasBeenViewed;
}
function setHasBeenViewed($HasBeenViewed)
{
$this->changedFields[] = 'HasBeenViewed';
$this->HasBeenViewed = $HasBeenViewed;
return $this;
}
function getnotificationGeneratedDate()
{
return $this->notificationGeneratedDate;
}
function setnotificationGeneratedDate($notificationGeneratedDate)
{
$this->changedFields[] = 'notificationGeneratedDate';
$this->notificationGeneratedDate = $notificationGeneratedDate;
return $this;
}
function getNotificationID()
{
return $this->NotificationID;
}
function setNotificationID($NotificationID)
{
$this->changedFields[] = 'NotificationID';
$this->NotificationID = $NotificationID;
return $this;
}
}
?>
Это класс, который был сгенерирован написанным мною приложением, которое просматривает схему таблицы и строит методы получения, установки и т. Д. Для этого класса.
Класс dbobject имеет функцию сохранения и загрузки, которая записывает / извлекает данные в / из базы данных в строку с соответствующим первичным ключом.
В качестве последнего бита справочной информации этопример создания экземпляра класса customer (который расширяет базу клиентов, который расширяет dbobject)
<?php
$customerObj = new customer(1431); //let's say the customer ID we're working on is 1431. the constructor automatically calls load() when a primary key is passed at instantiation
$customerObj->setFirstName("Henry")->setLastName("Ford")->save();
?>
Так что это некоторая основа для архитектуры продукта, над которым я работаю - и он не подлежит изменению сейчас, так какмы уже близки к запуску.
Вот актуальная проблема:
Как мы справляемся с совместимостью временных меток относительно часовых поясов?К сожалению, SQL Server 2000 не имеет возможности преобразовать часовые пояса во время отображения (а затем преобразовать их обратно в местный часовой пояс во время сохранения), что было бы самым простым решением.
Вот идея, которая у меня была, ина самом деле начал работать, но я хотел получить некоторую обратную связь, прежде чем я потратил время на написание ее до конца, и она на самом деле не работает правильно.
Во всех базовых классах у меня есть генератор, добавляющий новое свойство, котороеперечисляет все поля в таблице, которые имеют тип datetime в массиве, например так:
protected $dateFields = array('EmailSentTimestamp',
'notificationGeneratedDate');
Затем в моей функции dbobject :: load (), когда я заполняю все свойства поля в объекте какрезультат запроса SQL, если поле, которое в настоящее время итерируется (через цикл foreach в массиве $ fields в этом классе), находится в массиве $ dateFields, оно преобразует это значение в соответствующий часовой пояс перед установкой его всвойство.
Чтобы инвертировать это для поддержания целостности данных, в функции save (), когда она выполняет итерации по датеЕсли это поле, оно преобразует его обратно в нашу локальную метку времени.
Вот пошаговое руководство по его визуализации.
Запись в таблице содержит поле с отметкой времени 2011-05-20 13: 45: 00
Мы знаем, что пример пользователя из Великобритании и смещение часового пояса +5.
Когда объект создается и вызывается load, он автоматически преобразует эту метку времени в 2011-05-20 18:45:00, поэтому всякий раз, когда вызывается метод получения, он возвращает эту строку.
Пользователь изменяет отметку времени с помощью средства выбора даты на веб-странице.Он выбирает 2011-05-20 20:00:00.Это значение сохраняется в экземпляре объекта как это значение.
Когда вызывается функция сохранения, она берет сохраненную временную метку в экземпляре и преобразует ее 2011-05-20 15:00:00 перед записью вбазы данных.
Готово.
Таким образом, все места, где мы отображаем время, будут автоматически «фиксированы», и когда им нужно будет изменить определенное значение метки времени, оно будет настроено автоматически присэкономьте время.
Итак, коренные вопросы:
A) Это лучший способ (и наиболее эффективный, учитывая наш сжатый срок) справиться с этим B) если нет, то что?C) Какие существуют решения PHP, которые помогут в реальном преобразовании временных меток из одного часового пояса в другой.
У меня строгий CDA, поэтому я стараюсь не публиковать больше кода, чем нужно, но сообщите мне, если потребуется дополнительная информация.
Примечание для уточнения: Изменение способа хранения времени невозможно / не идеально. Эта же база данных используется другими продуктами, в том числе внутренними инструментами контроля качества сотрудников. Использование другой системы времени (независимо от того, насколько привлекательным является UTC) может вызвать проблемы.