Beispiel #1
0
        private static int Main(string[] args)
        {
            Options            options = new Options();
            ICommandLineParser parser  = new CommandLineParser(new CommandLineParserSettings(Console.Error)
            {
                MutuallyExclusive = true
            });

            if (!parser.ParseArguments(args, options))
            {
                return(1);
            }
            TzdbDateTimeZoneSource source = LoadSource(options.Source);
            var dumper = new ZoneDumper(source, options);

            try
            {
                using (var writer = options.OutputFile == null ? Console.Out : File.CreateText(options.OutputFile))
                {
                    dumper.Dump(writer);
                }
            }
            catch (UserErrorException e)
            {
                Console.Error.WriteLine($"Error: {e.Message}");
                return(1);
            }

            return(0);
        }
Beispiel #2
0
        private static List <DateTimeZone> LoadSource(Options options, out string version)
        {
            var source = options.Source;

            if (source == null)
            {
                var tzdbSource = TzdbDateTimeZoneSource.Default;
                version = tzdbSource.TzdbVersion;
                return(tzdbSource.GetIds().Select(id => tzdbSource.ForId(id)).ToList());
            }
            if (source.EndsWith(".nzd"))
            {
                var data       = LoadFileOrUrl(source);
                var tzdbSource = TzdbDateTimeZoneSource.FromStream(new MemoryStream(data));
                version = tzdbSource.TzdbVersion;
                return(tzdbSource.GetIds().Select(id => tzdbSource.ForId(id)).ToList());
            }
            else
            {
                var compiler = new TzdbZoneInfoCompiler(log: null);
                var database = compiler.Compile(source);
                version = database.Version;
                return(database.GenerateDateTimeZones()
                       .Concat(database.Aliases.Keys.Select(database.GenerateDateTimeZone))
                       .ToList());
            }
        }
Beispiel #3
0
        public TimeZoneController(
            IClock clock,
            IDateTimeZoneProvider dateTimeZoneProvider,
            TzdbDateTimeZoneSource dateTimeZoneSource)
            : base(clock, dateTimeZoneProvider)
        {
            var now = clock.GetCurrentInstant();

            foreach (var temp in dateTimeZoneSource.ZoneLocations)
            {
                var timeZone     = dateTimeZoneProvider.GetZoneOrNull(temp.ZoneId);
                var zoneInterval = timeZone.GetZoneInterval(now);
                var offset       = zoneInterval.WallOffset;

                if (timeZone != null)
                {
                    timeZones.Add(new TimeZoneInformation
                    {
                        Id     = timeZone.Id,
                        Name   = zoneInterval.Name,
                        Offset = offset.ToTimeSpan().Hours
                    });
                }
            }
        }
Beispiel #4
0
        private static int Main(string[] args)
        {
            Options            options = new Options();
            ICommandLineParser parser  = new CommandLineParser(new CommandLineParserSettings(Console.Error));

            if (!parser.ParseArguments(args, options))
            {
                return(1);
            }
            var data = FileUtility.LoadFileOrUrl(options.Source);
            TzdbDateTimeZoneSource source = TzdbDateTimeZoneSource.FromStream(new MemoryStream(data));
            var dumper = new ZoneDumper(source, options);

            try
            {
                using (var writer = options.OutputFile is null ? Console.Out : File.CreateText(options.OutputFile))
                {
                    dumper.Dump(writer);
                }
            }
            catch (UserErrorException e)
            {
                Console.Error.WriteLine($"Error: {e.Message}");
                return(1);
            }

            return(0);
        }
        public void CanLoadNodaTimeResourceFromOnePointZeroRelease()
        {
#pragma warning disable 0618
            var source = new TzdbDateTimeZoneSource("NodaTime.Test.TestData.Tzdb2012iFromNodaTime1.0",
                                                    Assembly.GetExecutingAssembly());
#pragma warning restore 0618
            Assert.AreEqual("TZDB: 2012i (mapping: 6356)", source.VersionId);

            var utc = Instant.FromUtc(2007, 8, 24, 9, 30, 0);

            // Test a regular zone with rules.
            var london        = source.ForId("Europe/London");
            var inLondon      = new ZonedDateTime(utc, london);
            var expectedLocal = new LocalDateTime(2007, 8, 24, 10, 30);
            Assert.AreEqual(expectedLocal, inLondon.LocalDateTime);

            // Test a fixed-offset zone.
            var utcFixed   = source.ForId("Etc/UTC");
            var inUtcFixed = new ZonedDateTime(utc, utcFixed);
            expectedLocal = new LocalDateTime(2007, 8, 24, 9, 30);
            Assert.AreEqual(expectedLocal, inUtcFixed.LocalDateTime);

            // Test an alias.
            var jersey   = source.ForId("Japan"); // Asia/Tokyo
            var inJersey = new ZonedDateTime(utc, jersey);
            expectedLocal = new LocalDateTime(2007, 8, 24, 18, 30);
            Assert.AreEqual(expectedLocal, inJersey.LocalDateTime);

            // Can't ask for ZoneLocations
            Assert.Throws <InvalidOperationException>(() => source.ZoneLocations.GetHashCode());
        }
Beispiel #6
0
        private static async Task <int> Main(string[] args)
        {
            Options            options = new Options();
            ICommandLineParser parser  = new CommandLineParser(new CommandLineParserSettings(Console.Error));

            if (!parser.ParseArguments(args, options))
            {
                return(1);
            }
            // Not null after we've parsed the arguments.
            TzdbDateTimeZoneSource source = await LoadSourceAsync(options.Source);

            var dumper = new ZoneDumper(source, options);

            try
            {
                using (var writer = options.OutputFile is null ? Console.Out : File.CreateText(options.OutputFile))
                {
                    dumper.Dump(writer);
                }
            }
            catch (UserErrorException e)
            {
                Console.Error.WriteLine($"Error: {e.Message}");
                return(1);
            }

            return(0);
        }
Beispiel #7
0
        public IActionResult TimeZones(string?version = null, string?format = null)
        {
            var source = TzdbDateTimeZoneSource.Default;

            if (version != null)
            {
                var release = repository.GetRelease($"tzdb{version}.nzd");
                if (release == null)
                {
                    return(BadRequest("Unknown version"));
                }
                source = TzdbDateTimeZoneSource.FromStream(release.GetContent());
            }
            var releaseModel = IanaRelease.FromTzdbDateTimeZoneSource(source);

            if (format == "json")
            {
                return(Json(releaseModel));
            }

            var releases = repository.GetReleases()
                           .Select(release => NzdNamePattern.Match(release.Name))
                           .Where(m => m.Success)
                           .Select(m => m.Groups[1].Value)
                           .ToList();
            var model = (releases, releaseModel);

            return(View(model));
        }
Beispiel #8
0
        private void LoadData()
        {
            // init noda time
            using (var stream = File.OpenRead(Directory.GetFiles(_nzdPath)[0]))
            {
                _tzdbSource   = TzdbDateTimeZoneSource.FromStream(stream);
                _tzdbProvider = new DateTimeZoneCache(_tzdbSource);
            }

            // this has to be loaded first
            LoadMetaZones();

            // these can be loaded in parallel
            var actions = new Action[]
            {
                LoadZoneCountries,
                LoadZoneAliases,
                LoadWindowsMappings,
                LoadLanguages
            };

            Task.WhenAll(actions.Select(Task.Run)).Wait();

            // patch the data for any known issues
            PatchData();

            // this has to come last, as it relies on patched data
            LoadSelectionZones();
        }
Beispiel #9
0
        private static async Task <CurrentTzdbProvider> DownloadAsync()
        {
            using (var client = new HttpClient())
            {
                var latest   = new Uri((await client.GetStringAsync("http://nodatime.org/tzdb/latest.txt")).TrimEnd());
                var fileName = latest.Segments.Last();
                var path     = Path.Combine(Path.GetTempPath(), fileName);

                if (!File.Exists(path))
                {
                    using (var httpStream = await client.GetStreamAsync(latest))
                        using (var fileStream = File.Create(path))
                        {
                            await httpStream.CopyToAsync(fileStream);
                        }
                }

                using (var fileStream = File.OpenRead(path))
                {
                    var source   = TzdbDateTimeZoneSource.FromStream(fileStream);
                    var provider = new DateTimeZoneCache(source);
                    return(new CurrentTzdbProvider(provider, source.Aliases));
                }
            }
        }
        public void GuessZoneIdByTransitionsUncached(NamedWrapper <TimeZoneInfo> bclZoneWrapper)
        {
            var bclZone = bclZoneWrapper.Value;

            // As of November 21st 2019, the Windows time zone database hasn't caught up
            // with the Morocco change in TZDB 2019a. Skip it for now.
            if (bclZone.Id == "Morocco Standard Time")
            {
                return;
            }

            string?id = TzdbDateTimeZoneSource.GuessZoneIdByTransitionsUncached(bclZone, TzdbDefaultZonesForIdGuessZoneIdByTransitionsUncached);

            // Unmappable zones may not be mapped, or may be mapped to something reasonably accurate.
            // We don't mind either way.
            if (!TzdbDateTimeZoneSource.Default.WindowsMapping.PrimaryMapping.ContainsKey(bclZone.Id))
            {
                return;
            }

            Assert.IsNotNull(id, $"Unable to guess time zone for {bclZone.Id}");
            var tzdbZone = TzdbDateTimeZoneSource.Default.ForId(id !);

            var       thisYear                = SystemClock.Instance.GetCurrentInstant().InUtc().Year;
            LocalDate?lastIncorrectDate       = null;
            Offset?   lastIncorrectBclOffset  = null;
            Offset?   lastIncorrectTzdbOffset = null;

            int total   = 0;
            int correct = 0;

            // From the start of this year to the end of next year, we should have an 80% hit rate or better.
            // That's stronger than the 70% we limit to in the code, because if it starts going between 70% and 80% we
            // should have another look at the algorithm. (And this is dealing with 80% of days, not 80% of transitions,
            // so it's not quite equivalent anyway.)
            for (var date = new LocalDate(thisYear, 1, 1); date.Year < thisYear + 2; date = date.PlusDays(1))
            {
                Instant startOfUtcDay = date.AtMidnight().InUtc().ToInstant();
                Offset  tzdbOffset    = tzdbZone.GetUtcOffset(startOfUtcDay);
                Offset  bclOffset     = Offset.FromTimeSpan(bclZone.GetUtcOffset(startOfUtcDay.ToDateTimeOffset()));
                if (tzdbOffset == bclOffset)
                {
                    correct++;
                }
                else
                {
                    // Useful for debugging (by having somewhere to put a breakpoint) as well as for the message.
                    lastIncorrectDate       = date;
                    lastIncorrectBclOffset  = bclOffset;
                    lastIncorrectTzdbOffset = tzdbOffset;
                }
                total++;
            }
            Assert.That(correct * 100.0 / total, Is.GreaterThanOrEqualTo(75.0),
                        "Last incorrect date for {0} vs {1}: {2} (BCL: {3}; TZDB: {4})",
                        bclZone.Id,
                        id,
                        lastIncorrectDate, lastIncorrectBclOffset, lastIncorrectTzdbOffset);
        }
Beispiel #11
0
 protected virtual void LoadTimeZoneData()
 {
     using (Stream stream = File.Open(Path.Combine(SharpIrcBotUtil.AppDirectory, Config.TimeZoneDatabaseFile), FileMode.Open, FileAccess.Read, FileShare.Read))
     {
         TzdbDateTimeZoneSource timeZoneSource = TzdbDateTimeZoneSource.FromStream(stream);
         TimeZoneProvider = new DateTimeZoneCache(timeZoneSource);
     }
 }
        public static TzdbZoneLocation ParseLocation(string locationString)
        {
            TzdbDateTimeZoneSource timeZoneSource = TzdbDateTimeZoneSource.Default;

            return
                (timeZoneSource.ZoneLocations.First(
                     location => location.CountryCode.Equals(locationString, StringComparison.OrdinalIgnoreCase)));
        }
Beispiel #13
0
        private static void CreateTextDump(TzdbDateTimeZoneSource source, string file)
        {
            var provider = new DateTimeZoneCache(source);

            using (var writer = File.CreateText(file))
            {
                provider.Dump(writer);
            }
        }
Beispiel #14
0
        private static TzdbDateTimeZoneSource Read(CompilerOptions options)
        {
            string file = Path.ChangeExtension(options.OutputFileName, "nzd");

            using (var stream = File.OpenRead(file))
            {
                return(TzdbDateTimeZoneSource.FromStream(stream));
            }
        }
Beispiel #15
0
        /// <summary>
        /// Returns the data in this database as a <see cref="TzdbDateTimeZoneSource"/> with no
        /// Windows mappings.
        /// </summary>
        public TzdbDateTimeZoneSource ToTzdbDateTimeZoneSource()
        {
            var ms     = new MemoryStream();
            var writer = new TzdbStreamWriter(ms);

            writer.Write(this, new WindowsZones("n/a", Version, "n/a", new MapZone[0]));
            ms.Position = 0;
            return(TzdbDateTimeZoneSource.FromStream(ms));
        }
Beispiel #16
0
 private TimezoneDB()
 {
     try {
         using (Stream stream = File.OpenRead(tzdbFilename)) {
             source = TzdbDateTimeZoneSource.FromStream(stream);
         }
     } catch {
         log.Warn("Custom TZDB source failed. Falling back to NodaTime.dll");
         source = TzdbDateTimeZoneSource.Default;
     }
     log.Info("Using NodaTime " + source.VersionId);
 }
Beispiel #17
0
        private IanaRelease(TzdbDateTimeZoneSource source)
        {
            this.source = source;
            var locations = source.ZoneLocations?.ToDictionary(location => location.ZoneId) ?? new Dictionary <string, TzdbZoneLocation>();

            Zones = source
                    .GetIds()
                    .Where(x => source.CanonicalIdMap[x] == x)
                    .OrderBy(x => x)
                    .Select(id => new Zone(source, locations, id))
                    .ToList();
        }
Beispiel #18
0
        /// <summary>
        /// Returns the data in this database as a <see cref="TzdbDateTimeZoneSource"/> with no
        /// Windows mappings.
        /// </summary>
        public TzdbDateTimeZoneSource ToTzdbDateTimeZoneSource()
        {
            var ms     = new MemoryStream();
            var writer = new TzdbStreamWriter();

            writer.Write(this,
                         new WindowsZones("n/a", Version, "n/a", new MapZone[0]), // No Windows mappings,
                         new Dictionary <string, string>(),                       // No additional name-to-id mappings
                         ms);
            ms.Position = 0;
            return(TzdbDateTimeZoneSource.FromStream(ms));
        }
        private TimezoneDB()
        {
            try {
                using (Stream stream = File.OpenRead(tzdbFile)) {
                    source = TzdbDateTimeZoneSource.FromStream(stream);
                }
            } catch {
                log.Warn("Custom TZDB source failed. Falling back to NodaTime.dll");
                source = TzdbDateTimeZoneSource.Default;
            }
            log.Info("Using NodaTime " + source.VersionId);

            Microsoft.Win32.SystemEvents.TimeChanged += SystemEvents_TimeChanged;
        }
Beispiel #20
0
            internal Zone(TzdbDateTimeZoneSource source, Dictionary <string, TzdbZoneLocation> locations, string id)
            {
                Id      = id;
                Aliases = source.Aliases[id];
                locations.TryGetValue(id, out var location);
                Location = location == null ? null : new Location(location);
                var zone = source.ForId(id);

                Offsets = zone.GetZoneIntervals(StartOfModernEra, EndOfModernEra)
                          .Select(zi => zi.WallOffset)
                          .Distinct()
                          .OrderBy(x => x)
                          .Select(o => OffsetPattern.GeneralInvariant.Format(o));
            }
Beispiel #21
0
        private static async Task <bool> ValidateAsync(HttpClient httpClient, string url)
        {
            try
            {
                Console.WriteLine($"Validating {url}");
                byte[] data = await httpClient.GetByteArrayAsync(url);

                var source = TzdbDateTimeZoneSource.FromStream(new MemoryStream(data));
                source.Validate();
                return(true);
            }
            catch (Exception e)
            {
                Console.WriteLine($"{e.GetType().Name}: {e.Message}");
                return(false);
            }
        }
Beispiel #22
0
        private static int Main(string[] args)
        {
            Options            options = new Options();
            ICommandLineParser parser  = new CommandLineParser(new CommandLineParserSettings(Console.Error));

            if (!parser.ParseArguments(args, options))
            {
                return(1);
            }
            if (options.FromYear > options.ToYear)
            {
                Console.WriteLine("Error: 'from' year must be not be later than 'to' year");
                return(1);
            }
            IDateTimeZoneSource source = TzdbDateTimeZoneSource.Default;

            if (options.File != null)
            {
                using (var stream = File.OpenRead(options.File))
                {
                    source = TzdbDateTimeZoneSource.FromStream(stream);
                }
            }
            Console.WriteLine("TZDB version: {0}", source.VersionId);

            var provider = new DateTimeZoneCache(source);

            if (options.Zone != null)
            {
                var zone = provider.GetZoneOrNull(options.Zone);
                if (zone == null)
                {
                    Console.WriteLine("Unknown time zone: {0}", options.Zone);
                    return(1);
                }
                DumpZone(zone, Console.Out, options.FromYear, options.ToYear);
            }
            else
            {
                foreach (var id in provider.Ids)
                {
                    DumpZone(provider[id], Console.Out, options.FromYear, options.ToYear);
                }
            }
            return(0);
        }
Beispiel #23
0
 private static TzdbDateTimeZoneSource LoadSource(string source)
 {
     if (source == null)
     {
         return(TzdbDateTimeZoneSource.Default);
     }
     if (source.EndsWith(".nzd"))
     {
         var data = LoadFileOrUrl(source);
         return(TzdbDateTimeZoneSource.FromStream(new MemoryStream(data)));
     }
     else
     {
         var compiler = new TzdbZoneInfoCompiler(log: null);
         var database = compiler.Compile(source);
         return(database.ToTzdbDateTimeZoneSource());
     }
 }
        public void CanLoadNodaTimeResourceFromOnePointOneRelease()
        {
            var assembly = typeof(TzdbDateTimeZoneSourceTest).Assembly;
            TzdbDateTimeZoneSource source;

            using (Stream stream = assembly.GetManifestResourceStream("NodaTime.Test.TestData.Tzdb2013bFromNodaTime1.1.nzd"))
            {
                source = TzdbDateTimeZoneSource.FromStream(stream);
            }
            Assert.AreEqual("TZDB: 2013b (mapping: 8274)", source.VersionId);

            var utc = Instant.FromUtc(2007, 8, 24, 9, 30, 0);

            // Test a regular zone with rules.
            var london        = source.ForId("Europe/London");
            var inLondon      = new ZonedDateTime(utc, london);
            var expectedLocal = new LocalDateTime(2007, 8, 24, 10, 30);

            Assert.AreEqual(expectedLocal, inLondon.LocalDateTime);

            // Test a fixed-offset zone.
            var utcFixed   = source.ForId("Etc/UTC");
            var inUtcFixed = new ZonedDateTime(utc, utcFixed);

            expectedLocal = new LocalDateTime(2007, 8, 24, 9, 30);
            Assert.AreEqual(expectedLocal, inUtcFixed.LocalDateTime);

            // Test an alias.
            var jersey   = source.ForId("Japan"); // Asia/Tokyo
            var inJersey = new ZonedDateTime(utc, jersey);

            expectedLocal = new LocalDateTime(2007, 8, 24, 18, 30);
            Assert.AreEqual(expectedLocal, inJersey.LocalDateTime);

            // Test ZoneLocations.
            var france = source.ZoneLocations.Single(g => g.CountryName == "France");

            // Tolerance of about 2 seconds
            Assert.AreEqual(48.86666, france.Latitude, 0.00055);
            Assert.AreEqual(2.3333, france.Longitude, 0.00055);
            Assert.AreEqual("Europe/Paris", france.ZoneId);
            Assert.AreEqual("FR", france.CountryCode);
            Assert.AreEqual("", france.Comment);
        }
Beispiel #25
0
        private static string GetOffset(string timezone)
        {
            var result = "0";

            if (_tzdbDateTimeZoneSource == null)
            {
                using (var stream = File.OpenRead($"{AppDomain.CurrentDomain.BaseDirectory}GeoDb\\tzdb2019c.nzd"))
                {
                    _tzdbDateTimeZoneSource = TzdbDateTimeZoneSource.FromStream(stream);
                }
            }

            var zonedDateTime = _tzdbDateTimeZoneSource.ForId(timezone)
                                .AtStrictly(new LocalDateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute));

            result = TimeSpan.FromMilliseconds(zonedDateTime.Offset.Milliseconds).TotalHours.ToString();

            return(result);
        }
        public void ResourceZoneEquivalence()
        {
            var streamSource = TzdbDateTimeZoneSource.Default;

#pragma warning disable 0618
            var resourceSource = new TzdbDateTimeZoneSource("NodaTime.Test.TestData.Tzdb",
                                                            Assembly.GetExecutingAssembly());
#pragma warning restore 0618
            Assert.AreEqual(streamSource.VersionId, resourceSource.VersionId);
            CollectionAssert.AreEquivalent(streamSource.GetIds(), resourceSource.GetIds());

            var interval = new Interval(Instant.FromUtc(1850, 1, 1, 0, 0), Instant.FromUtc(2050, 1, 1, 0, 0));
            var comparer = ZoneEqualityComparer.ForInterval(interval).WithOptions(ZoneEqualityComparer.Options.StrictestMatch);
            foreach (var id in streamSource.GetIds())
            {
                Assert.IsTrue(comparer.Equals(streamSource.ForId(id), resourceSource.ForId(id)),
                              "Zone {0} is equal under stream and resource formats", id);
            }
        }
Beispiel #27
0
        private static async Task <TzdbDateTimeZoneSource> LoadSourceAsync(string?source)
        {
            if (source is null)
            {
                return(TzdbDateTimeZoneSource.Default);
            }
            if (source.EndsWith(".nzd"))
            {
                var data = await FileUtility.LoadFileOrUrlAsync(source);

                return(TzdbDateTimeZoneSource.FromStream(new MemoryStream(data)));
            }
            else
            {
                var compiler = new TzdbZoneInfoCompiler(log: null);
                var database = await compiler.CompileAsync(source);

                return(database.ToTzdbDateTimeZoneSource());
            }
        }
        private static ICollection <string> GetIanaTimeZoneIds()
        {
            var tempDir = Path.GetTempPath() + Path.GetRandomFileName().Substring(0, 8);

            try
            {
                TestHelpers.DownloadLatestNodaTimeDataAsync(tempDir).Wait();

                using (var stream = File.OpenRead(Directory.GetFiles(tempDir, "*.nzd")[0]))
                {
                    var source   = TzdbDateTimeZoneSource.FromStream(stream);
                    var provider = new DateTimeZoneCache(source);

                    return(provider.Ids.OrderBy(x => x).ToArray());
                }
            }
            finally
            {
                Directory.Delete(tempDir, true);
            }
        }
Beispiel #29
0
        private static TzdbDateTimeZoneSource Read(CompilerOptions options)
        {
#pragma warning disable 0618
            string file = Path.ChangeExtension(options.OutputFileName, Extensions[options.OutputType]);
            switch (options.OutputType)
            {
            case OutputType.ResX:
                return(new TzdbDateTimeZoneSource(new ResourceSet(new ResXResourceReader(file))));

            case OutputType.Resource:
                return(new TzdbDateTimeZoneSource(new ResourceSet(new ResourceReader(file))));

            case OutputType.NodaZoneData:
                using (var stream = File.OpenRead(file))
                {
                    return(TzdbDateTimeZoneSource.FromStream(stream));
                }

            default:
                throw new ArgumentException("Invalid output type: " + options.OutputType, "options");
            }
#pragma warning restore 0618
        }
Beispiel #30
0
        private static List <DateTimeZone> LoadSource(Options options)
        {
            var source = options.Source;

            if (source == null)
            {
                var provider = DateTimeZoneProviders.Tzdb;
                return(provider.Ids.Select(id => provider[id]).ToList());
            }
            if (source.EndsWith(".nzd"))
            {
                var data       = LoadFileOrUrl(source);
                var tzdbSource = TzdbDateTimeZoneSource.FromStream(new MemoryStream(data));
                return(tzdbSource.GetIds().Select(id => tzdbSource.ForId(id)).ToList());
            }
            else
            {
                var compiler = new TzdbZoneInfoCompiler(log: null);
                var database = compiler.Compile(source);
                return(database.GenerateDateTimeZones()
                       .Concat(database.Aliases.Keys.Select(database.GenerateDateTimeZone))
                       .ToList());
            }
        }