2016-05-11 5 views
1

У меня есть приложение, которое получает данные из нескольких точек сбора данных, которые могут быть развернуты в любой точке мира. Они отправляются в очередь на Azure Service Bus, а приложение Console считывает из очереди и сохраняет эти данные с отметкой времени UTC и идентификатором, представляющим местоположение, из которого он пришел.Преобразование UTC в локальное время - Как сохранить/вывести локальное время моего сбора данных

У меня есть служба, которая проходит реакционные события на основе входных данных, освежающий каждые 20 секунд, и поэтому он смотрит в окно данных:

var window = DateTime.UtcNow.AddSeconds(-20); 

var events = context.MyTable.Where(x => x.Timestamp >= window).ToList(); 

//Process the events 

Это прекрасно работает, как время стандартизированы UTC ,

я, однако, также должны быть в состоянии утверждать статистические данные об этих данных по отношению к местному времени, а также, принимая во внимание летнее время (DST), например:

«Среднее время суток, этот тип события - 09:30:00 ».

В этом примере 09:30:00 означает местное время, независимо от того, произошло оно в PST, GMT или что-то еще, с учетом DST.

Как я сказал, что события сохраняются с ID местоположения, которая относится к объекту, который представляет Locations, что данные поступают от:

public class Location 
{ 
    public int id { get; set; } 
    public string name { get; set; } 
    public Organisation organisation { get; set; } 
} 

После установки эти места являются постоянными, то есть они не» t перейдите в разные часовые пояса, но их местное время может измениться с помощью DST.

В каком поле (и в каком формате) необходимо добавить объект моего местоположения, чтобы вывести локальное время, в котором произошли мои стандартизованные события UTC, и как я буду использовать его для преобразования UTC в местное время во время мероприятия.

например. если у меня есть 3 события из Испании (+1), GMT (+0) и PST (-8), которые произошли в 12 часов по местному времени. Они в основном хранятся как 1pm, 12pm и 4am. Мне нужно уметь утверждать, что в среднем было 9 утра.

ответ

-1

Я думаю, что вы сможете просто сохранить даты, которые вы собираете в качестве времени UTC, а затем использовать DateTime.ToLocalTime(), чтобы изменить их в локальное время, когда/где они вам понадобятся.

+0

Но где будет познанием часовой пояс? напримересли у меня есть 3 события из испания (+1), GMT (+0) и PST (-8), которые произошли в 12 часов по местному времени. они в основном хранятся как 1pm, 12pm и 4am. Мне нужно уметь утверждать, что в среднем было 9 утра. – JonnyKnottsvill

+0

Зачем вам это нужно? Я серьезно - вся идея хранения в UTC - это не иметь дело с часовыми поясами. Что такое специальный случай использования, в котором вам нужен часовой пояс, в котором он был перекодирован? Если вам нужен часовой пояс, который имеет значение, сохраните его за пределами времени (местоположение записи устройства или что-то еще, зависит от структуры данных). – TomTom

+0

Я не совсем понимаю, откуда именно вы хотите получить среднее значение. Вы хотите, чтобы в среднем по местному времени? Или среднее время централизованного времени UTC? Если это последний, мой подход должен работать, я думаю. Кроме того, вы можете изменить объект Event? Или это создаст проблемы? –

2

Вы должны добавить к своему Location запись строкового значения, которое называется TimeZone. Вам нужно будет заполнить его идентификатором часового пояса, который будет либо идентификатором часового пояса Windows, либо идентификатором часового пояса IANA. См. the timezone tag wiki для объяснения различий. Затем вы используете этот часовой пояс для определения местного времени, которое применяется для соответствующего времени UTC.

Моя рекомендация - использовать часовые пояса IANA, поскольку они доступны на разных платформах и языках, а не просто заблокированы до Windows и .NET. Это фактический стандарт для часовых поясов. Для того, чтобы использовать их в .NET, используйте Noda Time библиотеку:

using NodaTime; 
... 
DateTimeZone tz = DateTimeZoneProviders.Tzdb[location.TimeZone]; 
Instant instant = Instant.FromDateTimeUtc(theUtcDateTime); 
LocalTime localTime = instant.InZone(tz).TimeOfDay; 

Альтернативой является использование часовых поясов для Windows с TimeZoneInfo объекта, который поставляется с .NET:

TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(location.TimeZone); 
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(theUtcDateTime, tz); 
TimeSpan localTime = localDateTime.TimeOfDay;