Это похоже на часовой пояс Windows, как и у вас с TimeZoneInfo
, но сервис дал вам свойство DisplayName
, а не Id
. Это делает его немного громоздким. Тем более, что отображаемые имена локализованы - у вас есть английское имя. Это будет выглядеть по-другому на компьютере с разными настройками культуры.
Вы не можете просто принять смещение оттуда либо потому, что имена дисплеев Windows всегда показывают смещение , даже если зона находится в летнее время.
Основываясь на том, что он говорит «GMT», а не «UTC», я бы предположил, что они были получены от более старого компьютера, такого как Windows XP, Windows Server 2003 или, возможно, Windows Embedded. Например, вы найдете его на this list.
Вы действительно должны вернуться к владельцам этой службы и попросить их дать вам значение TimeZoneInfo.Id
, а не TimeZoneInfo.DisplayName
. Предполагая, что вы не можете сделать это, вот один из способов вы можете идти о получении этого работать с тем, что у вас есть:
// Look up the time zone. This won't work on non-English language computers!
// (setting an English CultureInfo won't help you here)
var shippedTZ = TimeZoneInfo.GetSystemTimeZones()
.FirstOrDefault(x => x.DisplayName == shippedTimeZone.Replace("GMT", "UTC"));
if (shippedTZ == null)
throw new Exception("Time Zone Not Found!");
// You may want to handle the exception by hardcoding some specific time zones
// Let's turn your date/time strings into an actual DateTime
var shippedDT = DateTime.ParseExact(shippedDate + " " + shippedTime,
"MM/dd/yyyy hh:mm tt", CultureInfo.InvariantCulture);
// Then we'll use the time zone to get a DateTimeOffset.
var shippedDTO = new DateTimeOffset(shippedDT,
shippedTZ.GetUtcOffset(shippedDT));
// And the same thing for the received date...
var receivedTZ = TimeZoneInfo.Local;
var receivedDT = DateTime.ParseExact(receievedDate + " " + receivedTime,
"MM/dd/yyyy hh:mm tt", CultureInfo.InvariantCulture);
var receivedDTO = new DateTimeOffset(receivedDT,
receivedTZ.GetUtcOffset(receivedDT));
// Now you can subtract them
TimeSpan elapsed = receivedDTO - shippedDTO;
Другая вещь, которую вы должны знать, отсюда - если ни один из даты/времени значения неоднозначны, вы не можете получить правильный результат. Это произойдет во время перехода «спада», связанного с летним временем сбережения. Вы ничего не можете с этим поделать, потому что у вас нет какой-либо квалифицирующей информации в исходных данных.
NodaTime - в то время как выдающийся библиотека, не может сделать намного лучше, чем это для вашей конкретной проблемы. У вас все еще будут проблемы с разрешением часового пояса без правильного идентификатора и отображения неоднозначного локального дат-времени. Но только для хорошей мерой, здесь то же самое, используя NodaTime:
// Try to locate the time zone
var bclZoneProvider = DateTimeZoneProviders.Bcl;
var zoneShipped = bclZoneProvider.Ids
.Select(x => bclZoneProvider[x])
.Cast<BclDateTimeZone>()
.FirstOrDefault(x => x.DisplayName == shippedTimeZone.Replace("GMT", "UTC"));
if (zoneShipped == null)
throw new Exception("Time Zone Not Found!");
// You wanted the system time zone
var zoneReceived = bclZoneProvider.GetSystemDefault();
// Parse the date/time values as a LocalDateTime
var pattern = LocalDateTimePattern
.CreateWithInvariantCulture("MM/dd/yyyy hh:mm tt");
var ldtShipped = pattern.Parse(shippedDate + " " + shippedTime).Value;
var ldtReceived = pattern.Parse(receievedDate + " " + receivedTime).Value;
// Assign them to the zones.
// "Leniently" means to use the standard offset when there is an ambiguity.
var zdtShipped = ldtShipped.InZoneLeniently(zoneShipped);
var zdtReceived = ldtReceived.InZoneLeniently(zoneReceived);
// Subtract them to get the Duration you are looking for.
Duration elapsed = zdtReceived.ToInstant() - zdtShipped.ToInstant();
вы пробовали 'DateTime.Parse + некоторая строка tricks' или [NodaTime] (https://code.google.com/p/noda -time /), прежде чем задавать этот вопрос? – I4V
Возможно, вы захотите взглянуть на [Noda Time] (http://code.google.com/p/noda-time/) ([и его блог] (http://noda-time.blogspot.com/))) для конверсий и правильного дневного света. Я не думаю, что Noda Time проанализирует хрупкую строку Time Zone. – Jesse
+1 для просмотра Noda Time. Конверсии часовых поясов могут выглядеть обманчиво простыми ... пока вы не начнете смотреть на крайние случаи. –