Beispiel #1
0
        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);
        }