Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TimeZone class #108

Merged
merged 6 commits into from
Mar 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions source/icu.net.tests/TimeZoneTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using NUnit.Framework;

namespace Icu.Tests
{
[TestFixture]
class TimeZoneTests
{

[Test]
public void GetDstSavingsTest()
{
var timezone = new TimeZone("Europe/Warsaw");

var savings = timezone.GetDstSavings();

Assert.AreEqual(3600 * 1000, savings);
}

[Test]
public void GetTimeZonesTest()
{
var timezones = TimeZone.GetTimeZones();

Assert.GreaterOrEqual(timezones.Count(), 400);
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Asia/Seoul"));
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Europe/London"));
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Etc/GMT-10"));
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Etc/GMT+3"));
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Etc/UTC"));
}

[Test]
public void GetRegionTimeZonesTest()
{
var timezones = TimeZone.GetTimeZones(USystemTimeZoneType.Any, "PL");

Assert.AreEqual(2, timezones.Count());
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Poland"));
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Europe/Warsaw"));
}

[Test]
public void GetCountryTimeZonesTest()
{
var timezones = TimeZone.GetCountryTimeZones("PL");

Assert.AreEqual(2, timezones.Count());
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Poland"));
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Europe/Warsaw"));
}

[Test]
public void GetOffsetTimeZonesTest()
{
var timezones = TimeZone.GetTimeZones(USystemTimeZoneType.Any, null, -1 * 3600 * 1000);

Assert.GreaterOrEqual(timezones.Count(), 4);
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Atlantic/Azores"));
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "America/Scoresbysund"));
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Atlantic/Cape_Verde"));
Assert.AreEqual(1, timezones.Count(tz => tz.Id == "Etc/GMT+1"));
}

[Test]
public void GetDefaultTimeZoneTest()
{
var expected = System.TimeZoneInfo.Local;

var result = TimeZone.GetDefault();
var resultWinId = TimeZone.GetWindowsId(result.Id);

Assert.Contains(expected.Id, new List<string>() { result.Id, resultWinId });
}

[Test]
public void SetDefaultTimeZoneTest()
{
var toSet = new TimeZone("AST");

TimeZone.SetDefault(toSet);
var def = TimeZone.GetDefault();

Assert.AreEqual(toSet.Id, def.Id);
}

[Test]
public void TimeZoneIdFromWinIdTest()
{
var winId = "Central European Standard Time";
var expected = "Europe/Zagreb";

var id = TimeZone.GetIdForWindowsId(winId, "HR");

Assert.AreEqual(expected, id);
}

[Test]
public void GetTZVersionTest()
{
var version = TimeZone.GetTZDataVersion();

Assert.True(Regex.IsMatch(version, "[0-9]{4}[a-z]"));
}

[Test]
public void TimeZoneWinIdFromIdTest()
{
var id = "Europe/Zagreb";
var expected = "Central European Standard Time";

var winId = TimeZone.GetWindowsId(id);

Assert.AreEqual(expected, winId);
}
}
}
187 changes: 187 additions & 0 deletions source/icu.net/NativeMethods/NativeMethods_TimeZone.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Icu
{
internal static partial class NativeMethods
{
private class TimeZoneMethodsContainer
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate SafeEnumeratorHandle ucal_openTimeZoneIDEnumerationDelegate(
USystemTimeZoneType zoneType,
[MarshalAs(UnmanagedType.LPStr)] string region,
ref int rawOffset,
out ErrorCode ec);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate SafeEnumeratorHandle ucal_openTimeZoneIDEnumerationPtrDelegate(
USystemTimeZoneType zoneType,
[MarshalAs(UnmanagedType.LPStr)] string region,
IntPtr rawOffset,
out ErrorCode ec);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate SafeEnumeratorHandle ucal_openTimeZonesDelegate(
out ErrorCode ec);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate SafeEnumeratorHandle ucal_openCountryTimeZonesDelegate(
[MarshalAs(UnmanagedType.LPStr)] string country,
out ErrorCode ec);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate int ucal_getDefaultTimeZoneDelegate(
IntPtr result,
int resultCapacity,
out ErrorCode ec);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate void ucal_setDefaultTimeZoneDelegate(
[MarshalAs(UnmanagedType.LPWStr)] string zoneID,
out ErrorCode ec);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate int ucal_getDSTSavingsDelegate(
[MarshalAs(UnmanagedType.LPWStr)] string zoneID,
out ErrorCode ec);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate IntPtr ucal_getTZDataVersionDelegate(
out ErrorCode ec);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate int ucal_getWindowsTimeZoneIdDelegate(
[MarshalAs(UnmanagedType.LPWStr)] string id,
int len,
IntPtr winid,
int winidCapacity,
out ErrorCode status);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
internal delegate int ucal_getTimeZoneIDForWindowsIdDelegate(
[MarshalAs(UnmanagedType.LPWStr)] string winid,
int len,
[MarshalAs(UnmanagedType.LPStr)] string region,
IntPtr id,
int idCapacity,
out ErrorCode status);

internal ucal_openTimeZoneIDEnumerationDelegate ucal_openTimeZoneIDEnumeration;
internal ucal_openTimeZoneIDEnumerationPtrDelegate ucal_openTimeZoneIDEnumerationPtr;
internal ucal_openTimeZonesDelegate ucal_openTimeZones;
internal ucal_openCountryTimeZonesDelegate ucal_openCountryTimeZones;
internal ucal_getDefaultTimeZoneDelegate ucal_getDefaultTimeZone;
internal ucal_setDefaultTimeZoneDelegate ucal_setDefaultTimeZone;
internal ucal_getDSTSavingsDelegate ucal_getDSTSavings;
internal ucal_getTZDataVersionDelegate ucal_getTZDataVersion;
internal ucal_getWindowsTimeZoneIdDelegate ucal_getWindowsTimeZoneId;
internal ucal_getTimeZoneIDForWindowsIdDelegate ucal_getTimeZoneIDForWindowsId;
}


private static TimeZoneMethodsContainer _TimeZoneMethods;

private static TimeZoneMethodsContainer TimeZoneMethods =>
_TimeZoneMethods ??
(_TimeZoneMethods = new TimeZoneMethodsContainer());

public static SafeEnumeratorHandle ucal_openTimeZoneIDEnumeration(
USystemTimeZoneType zoneType,
string region,
out ErrorCode ec)
{
if (TimeZoneMethods.ucal_openTimeZoneIDEnumerationPtr == null)
TimeZoneMethods.ucal_openTimeZoneIDEnumerationPtr = GetMethod<TimeZoneMethodsContainer.ucal_openTimeZoneIDEnumerationPtrDelegate>(IcuI18NLibHandle, "ucal_openTimeZoneIDEnumeration");
return TimeZoneMethods.ucal_openTimeZoneIDEnumerationPtr(zoneType, region, IntPtr.Zero, out ec);
}

public static SafeEnumeratorHandle ucal_openTimeZoneIDEnumeration(
USystemTimeZoneType zoneType,
string region,
ref int rawOffset,
out ErrorCode ec)
{
if (TimeZoneMethods.ucal_openTimeZoneIDEnumeration == null)
TimeZoneMethods.ucal_openTimeZoneIDEnumeration = GetMethod<TimeZoneMethodsContainer.ucal_openTimeZoneIDEnumerationDelegate>(IcuI18NLibHandle, "ucal_openTimeZoneIDEnumeration");
return TimeZoneMethods.ucal_openTimeZoneIDEnumeration(zoneType, region, ref rawOffset, out ec);
}

public static SafeEnumeratorHandle ucal_openTimeZones(out ErrorCode ec)
{
if (TimeZoneMethods.ucal_openTimeZones == null)
TimeZoneMethods.ucal_openTimeZones = GetMethod<TimeZoneMethodsContainer.ucal_openTimeZonesDelegate>(IcuI18NLibHandle, "ucal_openTimeZones");
return TimeZoneMethods.ucal_openTimeZones(out ec);
}

public static SafeEnumeratorHandle ucal_openCountryTimeZones(
string country,
out ErrorCode ec)
{
if (TimeZoneMethods.ucal_openCountryTimeZones == null)
TimeZoneMethods.ucal_openCountryTimeZones = GetMethod<TimeZoneMethodsContainer.ucal_openCountryTimeZonesDelegate>(IcuI18NLibHandle, "ucal_openCountryTimeZones");
return TimeZoneMethods.ucal_openCountryTimeZones(country, out ec);
}

public static int ucal_getDefaultTimeZone(
IntPtr result,
int resultCapacity,
out ErrorCode ec)
{
if (TimeZoneMethods.ucal_getDefaultTimeZone == null)
TimeZoneMethods.ucal_getDefaultTimeZone = GetMethod<TimeZoneMethodsContainer.ucal_getDefaultTimeZoneDelegate>(IcuI18NLibHandle, "ucal_getDefaultTimeZone");
return TimeZoneMethods.ucal_getDefaultTimeZone(result, resultCapacity, out ec);
}

public static void ucal_setDefaultTimeZone(
string zoneID,
out ErrorCode ec)
{
if (TimeZoneMethods.ucal_setDefaultTimeZone == null)
TimeZoneMethods.ucal_setDefaultTimeZone = GetMethod<TimeZoneMethodsContainer.ucal_setDefaultTimeZoneDelegate>(IcuI18NLibHandle, "ucal_setDefaultTimeZone");
TimeZoneMethods.ucal_setDefaultTimeZone(zoneID, out ec);
}

public static int ucal_getDSTSavings(
string zoneID,
out ErrorCode ec)
{
if (TimeZoneMethods.ucal_getDSTSavings == null)
TimeZoneMethods.ucal_getDSTSavings = GetMethod<TimeZoneMethodsContainer.ucal_getDSTSavingsDelegate>(IcuI18NLibHandle, "ucal_getDSTSavings");
return TimeZoneMethods.ucal_getDSTSavings(zoneID, out ec);
}

public static IntPtr ucal_getTZDataVersion(out ErrorCode ec)
{
if (TimeZoneMethods.ucal_getTZDataVersion == null)
TimeZoneMethods.ucal_getTZDataVersion = GetMethod<TimeZoneMethodsContainer.ucal_getTZDataVersionDelegate>(IcuI18NLibHandle, "ucal_getTZDataVersion");
return TimeZoneMethods.ucal_getTZDataVersion(out ec);
}

public static int ucal_getWindowsTimeZoneId(
string id,
IntPtr winid,
int winidCapacity,
out ErrorCode status)
{
if (TimeZoneMethods.ucal_getWindowsTimeZoneId == null)
TimeZoneMethods.ucal_getWindowsTimeZoneId = GetMethod<TimeZoneMethodsContainer.ucal_getWindowsTimeZoneIdDelegate>(IcuI18NLibHandle, "ucal_getWindowsTimeZoneID");
return TimeZoneMethods.ucal_getWindowsTimeZoneId(id, id.Length, winid, winidCapacity, out status);
}

public static int ucal_getTimeZoneIDForWindowsId(
string winid,
string region,
IntPtr id,
int idCapacity,
out ErrorCode status)
{
if (TimeZoneMethods.ucal_getTimeZoneIDForWindowsId == null)
TimeZoneMethods.ucal_getTimeZoneIDForWindowsId = GetMethod<TimeZoneMethodsContainer.ucal_getTimeZoneIDForWindowsIdDelegate>(IcuI18NLibHandle, "ucal_getTimeZoneIDForWindowsID");
return TimeZoneMethods.ucal_getTimeZoneIDForWindowsId(winid, winid.Length, region, id, idCapacity, out status);
}
}
}
Loading