private DateTime WindowsTimeZone(EventDateTime time) { DateTime theDate = time.DateTime ?? DateTime.Parse(time.Date); if (time.TimeZone == null) { return(theDate); } LocalDateTime local = new LocalDateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute); DateTimeZone zone = DateTimeZoneProviders.Tzdb[TimezoneDB.FixAlexa(time.TimeZone)]; ZonedDateTime zonedTime = local.InZoneLeniently(zone); DateTime zonedUTC = zonedTime.ToDateTimeUtc(); log.Fine("IANA Timezone \"" + time.TimeZone + "\" mapped to \"" + zone.Id.ToString() + "\" with a UTC of " + zonedUTC.ToString("dd/MM/yyyy HH:mm:ss")); return(zonedUTC); }
private Microsoft.Office.Interop.Outlook.TimeZone WindowsTimeZone(string ianaZoneId) { ianaZoneId = TimezoneDB.FixAlexa(ianaZoneId); Microsoft.Office.Interop.Outlook.TimeZones tzs = oApp.TimeZones; var utcZones = new[] { "Etc/UTC", "Etc/UCT", "UTC", "Etc/GMT" }; if (utcZones.Contains(ianaZoneId, StringComparer.OrdinalIgnoreCase)) { log.Fine("Timezone \"" + ianaZoneId + "\" mapped to \"UTC\""); return(tzs["UTC"]); } NodaTime.TimeZones.TzdbDateTimeZoneSource tzDBsource = TimezoneDB.Instance.Source; // resolve any link, since the CLDR doesn't necessarily use canonical IDs var links = tzDBsource.CanonicalIdMap .Where(x => x.Value.Equals(ianaZoneId, StringComparison.OrdinalIgnoreCase)) .Select(x => x.Key); // resolve canonical zones, and include original zone as well var possibleZones = tzDBsource.CanonicalIdMap.ContainsKey(ianaZoneId) ? links.Concat(new[] { tzDBsource.CanonicalIdMap[ianaZoneId], ianaZoneId }) : links; // map the windows zone var mappings = tzDBsource.WindowsMapping.MapZones; var item = mappings.FirstOrDefault(x => x.TzdbIds.Any(possibleZones.Contains)); if (item == null) { throw new System.ApplicationException("Timezone \"" + ianaZoneId + "\" has no mapping."); } log.Fine("Timezone \"" + ianaZoneId + "\" mapped to \"" + item.WindowsId + "\""); return(tzs[item.WindowsId]); }
private TimeZoneInfo getWindowsTimezoneFromDescription(String tzDescription) { try { System.Collections.ObjectModel.ReadOnlyCollection <TimeZoneInfo> sysTZ = TimeZoneInfo.GetSystemTimeZones(); //First let's just search with what we've got TimeZoneInfo tzi = sysTZ.FirstOrDefault(t => t.DisplayName == tzDescription || t.StandardName == tzDescription || t.Id == tzDescription); if (tzi != null) { return(tzi); } log.Warn("Could not find timezone ID based on given description. Attempting some fuzzy logic..."); if (tzDescription.StartsWith("(GMT")) { log.Fine("Replace GMT with UTC"); String modTzDescription = tzDescription.Replace("(GMT", "(UTC"); tzi = sysTZ.FirstOrDefault(t => t.DisplayName == modTzDescription || t.StandardName == modTzDescription || t.Id == modTzDescription); if (tzi != null) { return(tzi); } log.Fine("Removing offset prefix"); modTzDescription = System.Text.RegularExpressions.Regex.Replace(modTzDescription, @"^\(UTC[+-]\d{1,2}:\d{0,2}\)\s+", "").Trim(); tzi = sysTZ.FirstOrDefault(t => t.StandardName == modTzDescription || t.Id == modTzDescription); if (tzi != null) { return(tzi); } } //Try searching just by timezone offset. This would at least get the right time for the appointment, eg if the tzDescription doesn't match //because they it is in a different language that the user's system data. Int16?offset = null; offset = TimezoneDB.GetTimezoneOffset(tzDescription); if (offset != null) { List <TimeZoneInfo> tzis = sysTZ.Where(t => t.BaseUtcOffset.Hours == offset).ToList(); if (tzis.Count == 0) { log.Warn("No timezone ID exists for organiser's GMT offset timezone " + tzDescription); } else if (tzis.Count == 1) { return(tzis.First()); } else { String tzCountry = tzDescription.Substring(tzDescription.LastIndexOf("/") + 1); if (string.IsNullOrEmpty(tzCountry)) { log.Warn("Could not determine country; and multiple timezones exist with same GMT offset of " + offset + ". Picking the first."); return(tzis.FirstOrDefault()); } else { List <TimeZoneInfo> countryTzis = tzis.Where(t => t.DisplayName.Contains(tzCountry)).ToList(); if (countryTzis.Count == 0) { log.Warn("Could not find timezone with GMT offset of " + offset + " for country " + tzCountry + ". Picking the first offset match regardless of country."); return(tzis.FirstOrDefault()); } else if (countryTzis.Count == 1) { return(countryTzis.First()); } else { log.Warn("Could not find unique timezone with GMT offset of " + offset + " for country " + tzCountry + ". Picking the first."); return(countryTzis.FirstOrDefault()); } } } } else { //Check if it's already an IANA value NodaTime.TimeZones.TzdbDateTimeZoneSource tzDBsource = TimezoneDB.Instance.Source; IEnumerable <NodaTime.TimeZones.TzdbZoneLocation> a = tzDBsource.ZoneLocations.Where(l => l.ZoneId == tzDescription); if (a.Count() >= 1) { log.Debug("It appears to be an IANA timezone already!"); Microsoft.Office.Interop.Outlook.TimeZone tz = WindowsTimeZone(tzDescription); if (tz != null) { return(TimeZoneInfo.FindSystemTimeZoneById(tz.ID)); } } } } catch (System.Exception ex) { log.Warn("Failed to get the organiser's timezone ID for " + tzDescription); OGCSexception.Analyse(ex); } return(null); }