Show / Hide Table of Contents

TimeZoneCalculator

Api specification links

The TimeZoneCalculator class helps you to:

  • Access fast, utilities for converting values between timezones
  • Convert DateTime and DateTimeOffset values to TimeStamp and vice-versa.

Basic usage

The static TimeZoneCalculator.Convert method allows you to convert times directly from one timezone to another. This is the slowest utility method available in the library (but much faster than you can find anywhere else), and you would use it in situations where its either not used in a critical hot path, or where you don't know in advance which timezones will be converted.

TimeZoneCalculator.GetSegment

The TimeZoneCalculator.TimeZoneSegment class is returned by the TimeZoneCalculator.GetSegment(TimeStamp time) method and the TimeZoneCalculator.GetSegment(long ticks, TimeKind ticksKind) method.

It provides you with a lot of helpful information about a specific period of time in which a timezone's offset remains constant. By obtaining and caching a TimeZoneCalculator.TimeZoneSegment you can speed up your code and create more sophisticated logic.

  • The IsInvalid property tells you if the current period of time is actually skipped over by the timezone clock as it flies forward. Typically this happens as Daylight Savings starts.
  • The IsAmbiguous property tells you if the current period of time happens twice, as the clock flies backward and then repeats the time period again. Typically this happens when Daylights Savings comes to an end.
  • The OffsetTicks property tells you the timezone's offset from Utc timezone during the current period.
  • The Next and Previous properties allow you to access the next and previous periods of time without accessing the TimeZoneCalculator.GetSegment method again - this can make your code a lot faster!
  • The StartTicks and EndTicks property tells you the start and end of the time period, expressed in ticks in either Utc timezone, or the specific timezone.
  • The SegmentKind property tells you which timezone is being used by the StartTicks and EndTicks properties.
Tip

The period of time represented by the TimeZoneSegment is EXCLUSIVE of the TimeZoneSegment.EndTicks. In fact, TimeZoneSegment.EndTicks is actually the same as the TimeZoneSegment.StartTicks of the next segment!

Basic examples

// Copyright (c) True Goodwill. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace FFT.TimeStamps.Examples
{
  using System;
  using System.Diagnostics;
  using static FFT.TimeStamps.Examples.TimeZones;

  internal class TimeZoneCalculatorExamples : IExample
  {
    public void Run()
    {
      DemonstrateSimpleConversion();
      DemonstrateSegments();
    }

    /// <summary>
    /// Demonstrates a conversion from one timezone to another timezone using the simplest calculator
    /// feature available. This is also the slowest method available.
    /// </summary>
    private void DemonstrateSimpleConversion()
    {
      // get the current time in new york expressed in ticks.
      long ticksNewYorkTimeZone = TimeStamp.Now.AsTicks(NewYork); // this operation used TimeZoneOffsetCalculator internally.

      // use the calculator to find the equivalent time in sydney expressed in ticks.
      long ticksSydneyTimeZone = TimeZoneCalculator.Convert(NewYork, Sydney, ticksNewYorkTimeZone);
    }

    /// <summary>
    /// Demonstrates use of the "GetSegment" method in the time zone calculator.
    /// </summary>
    /// <remarks>
    /// You can make your code very very fast at timezone conversions by caching and
    /// reusing the segments avoiding calling the "GetSegment" method over and over again.
    /// See the conversion iterators for examples of how this is done.
    /// </remarks>
    private void DemonstrateSegments()
    {
      TimeStamp now = TimeStamp.Now;

      // get current time ticks in UTC timezone
      long utcTicks = now.TicksUtc;

      // get a reference to the calculator for the EST timezone.
      TimeZoneCalculator calculator = TimeZoneCalculator.Get(NewYork);

      // get a segment with StartTicks and EndTicks expressed in UTC timezone.
      TimeZoneCalculator.TimeZoneSegment utcSeg = calculator.GetSegment(utcTicks, TimeKind.Utc);

      // use the segment information to perform a conversion from UTC timezone to EST timezone.
      long estTicks = utcTicks + utcSeg.OffsetTicks;

      // get a segment with StartTicks and EndTicks expressed in EST timezone.
      TimeZoneCalculator.TimeZoneSegment estSeg = calculator.GetSegment(estTicks, TimeKind.TimeZone);

      Debug.Assert(utcSeg.OffsetTicks == estSeg.OffsetTicks, "The offset tick values should be the same.");
    }
  }
}

Advanced examples

Checkout the code for the ToUtcIterator class for an example of advanced TimeZoneCalculator.TimeZoneSegment usage.

Benchmarking

The slowest possible conversion methods in TimeZoneCalculator allows you to perform timezone conversion calculations twice as fast as the in-built methods supplied by the .net framework.

However, you can also use the same techniques as the Converstion iterators to achieve results more than 32 times faster.

Method Mean Error StdDev
WithTimeZoneInfo 379.9 ns 3.10 ns 2.75 ns
WithTimeZoneCalculator 125.5 ns 1.46 ns 1.36 ns
// Copyright (c) True Goodwill. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace FFT.TimeStamps.Benchmarks
{
  using System;
  using System.Linq;
  using BenchmarkDotNet.Attributes;
  using static FFT.TimeStamps.Benchmarks.TimeZones;

  public class SimpleConversions
  {
    private static readonly DateTime[] _newYorkTimes;

    static SimpleConversions()
    {
      _newYorkTimes = ExampleFeed.ChronologicalUnspecifiedDateTimes().ToArray();
    }

    /// <summary>
    /// Performs test using built-in .net framework feature.
    /// </summary>
    [Benchmark]
    public void With_System_TimeZoneInfo()
    {
      foreach (DateTime newYorkTime in _newYorkTimes)
      {
        DateTime sydneyTime = TimeZoneInfo.ConvertTime(newYorkTime, NewYork, Sydney);
      }
    }

    /// <summary>
    /// Performs test using FFT.TimeStamps simplest and slowest conversion method.
    /// </summary>
    [Benchmark]
    public void With_TimeStamps_TimeZoneCalculator()
    {
      foreach (DateTime newYorkTime in _newYorkTimes)
      {
        long sydneyTicks = TimeZoneCalculator.Convert(NewYork, Sydney, newYorkTime.Ticks);
        DateTime sydneyTime = new DateTime(sydneyTicks, DateTimeKind.Unspecified);
      }
    }
  }
}
  • Improve this Doc
In This Article
Back to top Generated by DocFX