TimeZoneCalculator
Api specification links
The TimeZoneCalculator class helps you to:
- Access fast, utilities for converting values between timezones
- Convert
DateTime
andDateTimeOffset
values toTimeStamp
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
andPrevious
properties allow you to access the next and previous periods of time without accessing theTimeZoneCalculator.GetSegment
method again - this can make your code a lot faster! - The
StartTicks
andEndTicks
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 theStartTicks
andEndTicks
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);
}
}
}
}