Asp.Net, SQL и часовые пояса
Это'Меня спрашивают, но я пытаюсь понять концепцию обработки часовых поясов в веб-приложении. У меня есть система, которая отслеживает прогресс проектов. У меня есть ProjectStartDate DATE в моей базе данных SQL Server. (Там'Еще несколько полей и таблиц, но давайте сосредоточимся на одном).
Сервер находится где-то в Соединенных Штатах. Я живу в Австралии.
призваниеSELECT GETDATE()
возвращается2013-08-11 14: 40: 50.630 " Мои системные часы показывают "2013-08-12 07:40 "
В моей базе данных естьCreateDateTime» столбцы на всех таблицах. Когда я храню это, в моем коде C #, я используюCreateDate = DateTime.UtcNow
Я использую это, поскольку я слышал, что было лучше использовать UTC.
Но когда пользователю предоставляется элемент управления календаря, и он выбирает начальную дату для проекта, я сохраняю то, что когда-либо выбрал пользователь. Без преобразования ... И, как я уже сказал, StartDate - это тип DATE в базе данных.
Проблема в том, что если проект стартовал сегодня - мой клиент говорит, что текущий проект - «Не запущен», потому что сервер все еще находится во вчерашнем дне.
Я думаю, что даты должны храниться так, как я их храню. Но, может быть, мне нужно как-то получить часовой пояс пользователя и применить его на уровне пользовательского интерфейса?
Проблемы, которые я вижу:
Я неНе знаю часовой пояс пользователя. Добавить что-нибудь, чтобы позволить им выбрать это?Статус проекта может быть определен в хранимой процедуре, так когда я могу применить преобразование? В процедуре он может выполнить проверку и вернуть VARCHAR с указанием "Не начато" если StartDate <= DateTime.Now?Я использую EntityFramework и Linq для получения данных большую часть времени. Мне нужна стратегия для вставки и извлечения данных, как в смысле SQL, так и в смысле .Net.
Я добавил код, чтобы пользователь мог выбрать свой часовой пояс на основе этого:
public List GetTimeZones()
{
var zones = TimeZoneInfo.GetSystemTimeZones();
var result = zones.Select(tz => new TimeZoneDto
{
Id = tz.Id,
Description = tz.DisplayName
}).ToList();
return result;
}
То есть потом сохранилось в их профиле.
Все даты хранятся в формате UTC, как указано в ответах ниже.
Я все еще не понимаю, как обрабатывать даты, когда они поступают в базу данных и из нее, к клиенту. Вот пример того, как я храню запись:
public int SaveNonAvailibility(PersonNonAvailibilityDto n)
{
person_non_availibility o;
if (n.Id == 0)
{
o = new person_non_availibility
{
PersonId = n.PersonId,
Reason = n.Reason,
StartDate = n.StartDate,
EndDate = n.EndDate,
NonAvailibilityTypeId = n.NonAvailibilityTypeId,
CreateUser = _userId,
CreateDate = DateTime.UtcNow
};
_context.person_non_availibility.Add(o);
}
else
{
o = (from c in _context.person_non_availibility where c.Id == n.Id select c).FirstOrDefault();
o.StartDate = n.StartDate;
o.EndDate = n.EndDate;
o.Reason = n.Reason;
o.NonAvailibilityTypeId = n.NonAvailibilityTypeId;
o.LastUpdateDate = DateTime.UtcNow;
o.LastUpdateUser = _userId;
o.Deleted = n.Deleted ? DateTime.UtcNow : (DateTime?)null;
}
_context.SaveChanges();
return o.Id;
}
Этот метод в основном экономит, когда человек недоступен для работы. Обратите внимание, как я храню LastUpdateDate. Так же 'Начните' а также 'Конец' даты. Эти даты большеБизнес' даты.
При выборе, а затем проверке даты, у меня есть проблемы. В этом примере я получаю плату за людей, основанную на СЕЙЧАС.
public decimal CurrentRate
{
get
{
if (ResourceCosts != null)
{
var i = ResourceCosts.FirstOrDefault(t => DateTime.UtcNow = t.StartDate);
if (i != null) return i.Cost;
return 0;
}
return 0;
}
}
Итак, что я хочу здесь сделать, так это то, что, исходя из текущей даты, я хочу увидеть его курс (поскольку его начисление может составлять 100 долларов с 1 января по 15 января, а затем 110 долларов с 16 до 31 января. Итак, я смотрю на ставку, применимую сегодня (если есть).работать в разных часовых поясах, и этоМожет быть, здесь, где мне нужно сделать некоторые манипуляции с датами на основеDateTime.UTCNow?
Обратите внимание, я теперь знаю часовой пояс пользователя, основываясь на приведенном выше коде, где я храню его часовой пояс. Я могу использовать это как-то здесь? Возможно, когда пользователь входит в систему, извлекает информацию о дате из его профиля (информация Zimezone), а затем имеет глобальную общую функцию, которая возвращает дату и время пользователя, основываясь на добавлении или удалении часов из даты UTC ... и используя это где я делаю DateTime.UTCNow?
Надеюсь, кто-то может направить меня.