Skip to content

Commit 3735053

Browse files
Replace TZ4Net by NodaTime.
1 parent 01bf255 commit 3735053

File tree

9 files changed

+325
-17
lines changed

9 files changed

+325
-17
lines changed

dotnet/src/dotnetcore/GxClasses/GxClasses.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFrameworks>net6.0</TargetFrameworks>
55
<OutputType>Library</OutputType>
6-
<DefineConstants>NETCORE</DefineConstants>
6+
<DefineConstants>NETCORE;NODATIME</DefineConstants>
77
<PackageTags>Data Access</PackageTags>
88
<PackageId>GeneXus.Classes.Core</PackageId>
99
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
@@ -159,6 +159,7 @@
159159
<PackageReference Include="MySqlConnector" Version="2.2.3" />
160160
<PackageReference Include="NetTopologySuite" Version="2.0.0" />
161161
<PackageReference Include="NetTopologySuite.Core" Version="1.15.3" />
162+
<PackageReference Include="NodaTime" Version="3.1.9" />
162163
<PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="3.3.1" />
163164
<PackageReference Include="Npgsql" Version="3.2.7" />
164165
<PackageReference Include="Sandwych.GeographicLib" Version="1.49.3" />

dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ namespace GeneXus.Application
4242
#if NETCORE
4343
using Microsoft.AspNetCore.Http.Features;
4444
#endif
45+
using NodaTime;
46+
using NodaTime.TimeZones;
4547
using System.Threading;
4648
using System.Security.Claims;
4749
using System.Security;
@@ -392,6 +394,8 @@ public List<string[]> userStyleSheetFiles {
392394
private bool _isSumbited;
393395
[NonSerialized]
394396
private OlsonTimeZone _currentTimeZone;
397+
[NonSerialized]
398+
private String _currentTimeZoneId;
395399

396400
[NonSerialized]
397401
MessageQueueTransaction _mqTransaction;
@@ -3541,7 +3545,36 @@ public OlsonTimeZone ClientTimeZone
35413545
return _currentTimeZone;
35423546
}
35433547
}
3548+
internal string ClientTimeZoneId
3549+
{
3550+
get
3551+
{
3552+
if (_currentTimeZoneId != null)
3553+
return _currentTimeZoneId;
3554+
string sTZ = _HttpContext == null ? "" : (string)_HttpContext.Request.Headers[GX_REQUEST_TIMEZONE];
3555+
GXLogging.DebugSanitized(log, "ClientTimeZone GX_REQUEST_TIMEZONE header:", sTZ);
3556+
if (String.IsNullOrEmpty(sTZ))
3557+
{
3558+
sTZ = (string)GetCookie(GX_REQUEST_TIMEZONE);
3559+
GXLogging.Debug(log, "ClientTimeZone GX_REQUEST_TIMEZONE cookie:", sTZ);
3560+
}
3561+
try
3562+
{
3563+
_currentTimeZoneId = String.IsNullOrEmpty(sTZ) ? DateTimeZoneProviders.Tzdb.GetSystemDefault().Id : sTZ;
3564+
}
3565+
catch (Exception e1)
3566+
{
3567+
GXLogging.Warn(log, "ClientTimeZone GetInstanceFromWin32Id error", e1);
3568+
Preferences.StorageTimeZonePty storagePty = Preferences.getStorageTimezonePty();
3569+
if (storagePty == Preferences.StorageTimeZonePty.Undefined)
3570+
_currentTimeZoneId = null;
3571+
else
3572+
throw e1;
3573+
}
35443574

3575+
return _currentTimeZoneId;
3576+
}
3577+
}
35453578
public OlsonTimeZone GetOlsonTimeZone()
35463579
{
35473580
return TimeZoneUtil.GetInstanceFromOlsonName(GetTimeZone());
@@ -3554,15 +3587,45 @@ public String GetTimeZone()
35543587
{
35553588
SetTimeZone(sTZ);
35563589
}
3590+
3591+
#if NODATIME
3592+
if (_currentTimeZoneId == null)
3593+
_currentTimeZoneId = ClientTimeZoneId;
3594+
if (_currentTimeZoneId==null)
3595+
_currentTimeZoneId = DateTimeZoneProviders.Tzdb.GetSystemDefault().Id;
3596+
return _currentTimeZoneId;
3597+
#else
35573598
if (_currentTimeZone == null)
35583599
_currentTimeZone = ClientTimeZone;
35593600
return _currentTimeZone == null ? TimeZoneUtil.GetInstanceFromWin32Id(TimeZoneInfo.Local.Id).Name : _currentTimeZone.Name;
3601+
#endif
35603602
}
35613603

35623604
public Boolean SetTimeZone(String sTZ)
35633605
{
35643606
sTZ = StringUtil.RTrim(sTZ);
35653607
Boolean ret = false;
3608+
#if NODATIME
3609+
string tzId;
3610+
try
3611+
{
3612+
if (DateTimeZoneProviders.Tzdb[sTZ] != null)
3613+
{
3614+
tzId = DateTimeZoneProviders.Tzdb[sTZ].Id;
3615+
}
3616+
else
3617+
{
3618+
tzId = DateTimeZoneProviders.Tzdb.GetSystemDefault().Id;
3619+
}
3620+
ret = true;
3621+
}
3622+
catch (Exception)
3623+
{
3624+
tzId = DateTimeZoneProviders.Tzdb.GetSystemDefault().Id;
3625+
}
3626+
SetProperty("GXTimezone", tzId);
3627+
_currentTimeZoneId = tzId;
3628+
#else
35663629
try
35673630
{
35683631
_currentTimeZone = TimeZoneUtil.GetInstanceFromOlsonName(sTZ);
@@ -3581,6 +3644,7 @@ public Boolean SetTimeZone(String sTZ)
35813644
}
35823645
}
35833646
SetProperty("GXTimezone", _currentTimeZone.Name);
3647+
#endif
35843648
return ret;
35853649
}
35863650
private static ConcurrentDictionary<string, HashSet<string>> m_imagesDensity = new ConcurrentDictionary<string, HashSet<string>>();

dotnet/src/dotnetframework/GxClasses/Core/GXUtilsCommon.cs

Lines changed: 136 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
using GxClasses.Helpers;
2020
using System.Net;
2121
#endif
22+
using NodaTime;
23+
using NodaTime.TimeZones;
2224
using NUglify;
2325
using NUglify.Html;
2426
using GeneXus.Web.Security;
@@ -2014,6 +2016,11 @@ enum DateFmt
20142016
DMY
20152017
}
20162018

2019+
internal static string LocalTimeZoneId
2020+
{
2021+
get { return DateTimeZoneProviders.Tzdb.GetSystemDefault().Id; }
2022+
}
2023+
20172024
public DateTimeUtil(CultureInfo culture, AMPMFmt amPmFormat)
20182025
{
20192026
cultureInfo = culture;
@@ -2407,9 +2414,36 @@ static public short CurrentOffset(IGxContext context)
24072414
{
24082415
if (context == null)
24092416
context = GxContext.Current;
2417+
#if NODATIME
2418+
TimeSpan ts = CurrentOffset(context.GetTimeZone());
2419+
#else
24102420
TimeSpan ts = CurrentOffset(context.GetOlsonTimeZone());
2421+
#endif
24112422
return (short)(ts.Hours * 60 + ts.Minutes);
24122423
}
2424+
2425+
static private TimeSpan CurrentOffset(string clientTimeZone)
2426+
{
2427+
DateTimeZone clientTimeZoneObj = DateTimeZoneProviders.Tzdb[clientTimeZone];
2428+
if (clientTimeZoneObj == null)
2429+
clientTimeZoneObj = DateTimeZoneProviders.Tzdb[LocalTimeZoneId];
2430+
Instant now = SystemClock.Instance.GetCurrentInstant();
2431+
2432+
try
2433+
{
2434+
Offset offset = clientTimeZoneObj.GetUtcOffset(now);
2435+
return offset.ToTimeSpan();
2436+
}
2437+
catch (ArgumentOutOfRangeException)
2438+
{
2439+
Duration oneHour = Duration.FromHours(1);
2440+
Instant oneHourAgo = now.Minus(oneHour);
2441+
//Avoid InSpringForwardGap/InFallBackRange condition
2442+
Offset offset = clientTimeZoneObj.GetUtcOffset(oneHourAgo);
2443+
return offset.ToTimeSpan();
2444+
}
2445+
}
2446+
24132447
static private TimeSpan CurrentOffset(OlsonTimeZone clientTimeZone)
24142448
{
24152449
DateTime currentDate = DateTime.Now;
@@ -2447,11 +2481,20 @@ static DateTime CurrentTimeZoneToUniversalTime(DateTime dt)
24472481
return TimeZone.CurrentTimeZone.ToUniversalTime(dt);
24482482
#endif
24492483
}
2450-
2484+
static DateTime ConvertFromLocal(DateTime dt, IGxContext context)
2485+
{
2486+
#if NODATIME
2487+
return ConvertDateTime(DateTime.Now, LocalTimeZoneId, context.GetTimeZone());
2488+
#else
2489+
OlsonTimeZone fromTimezone = TimeZoneUtil.GetInstanceFromWin32Id(TimeZoneInfo.Local.Id);
2490+
OlsonTimeZone toTimezone = context.GetOlsonTimeZone();
2491+
return ConvertDateTime(dt, fromTimezone, toTimezone);
2492+
#endif
2493+
}
24512494
static public DateTime Today(IGxContext context)
24522495
{
24532496
if (Preferences.useTimezoneFix())
2454-
return ResetMillisecondsTicks(ResetTime(ConvertDateTime(DateTime.Now, TimeZoneUtil.GetInstanceFromWin32Id(TimeZoneInfo.Local.Id), context.GetOlsonTimeZone())));
2497+
return ResetMillisecondsTicks(ResetTime(ConvertFromLocal(DateTime.Now, context)));
24552498
return ResetMillisecondsTicks(DateTime.Today);
24562499
}
24572500
static public DateTime Now(IGxContext context)
@@ -2462,7 +2505,7 @@ static public DateTime Now(IGxContext context)
24622505
static public DateTime NowTicks(IGxContext context)
24632506
{
24642507
if (Preferences.useTimezoneFix())
2465-
return ConvertDateTime(DateTime.Now, TimeZoneUtil.GetInstanceFromWin32Id(TimeZoneInfo.Local.Id), context.GetOlsonTimeZone());
2508+
return ConvertFromLocal(DateTime.Now, context);
24662509
return DateTime.Now;
24672510
}
24682511

@@ -2907,15 +2950,15 @@ static public DateTime ServerNowMs(IGxContext context, IDataStoreProvider dataSt
29072950
if (dataStore == null)
29082951
return ServerNowMs(context, new DataStoreHelperBase().getDataStoreName());
29092952
if (Preferences.useTimezoneFix())
2910-
return ResetMicroseconds(ConvertDateTime(dataStore.serverNowMs(), TimeZoneUtil.GetInstanceFromWin32Id(TimeZoneInfo.Local.Id), context.GetOlsonTimeZone()));
2953+
return ResetMicroseconds(ConvertFromLocal(dataStore.serverNowMs(), context));
29112954
return ResetMicroseconds(dataStore.serverNowMs());
29122955
}
29132956
static public DateTime ServerNow(IGxContext context, IDataStoreProvider dataStore)
29142957
{
29152958
if (dataStore == null)
29162959
return ServerNow(context, new DataStoreHelperBase().getDataStoreName());
29172960
if (Preferences.useTimezoneFix())
2918-
return ResetMillisecondsTicks(ConvertDateTime(dataStore.serverNow(), TimeZoneUtil.GetInstanceFromWin32Id(TimeZoneInfo.Local.Id), context.GetOlsonTimeZone()));
2961+
return ResetMillisecondsTicks(ConvertFromLocal(dataStore.serverNow(), context));
29192962
return ResetMillisecondsTicks(dataStore.serverNow());
29202963
}
29212964
#if !NETCORE
@@ -2924,13 +2967,13 @@ static public DateTime ServerNow(IGxContext context, IDataStoreProvider dataStor
29242967
static public DateTime ServerNowMs(IGxContext context, string dataSource)
29252968
{
29262969
if (Preferences.useTimezoneFix())
2927-
return ResetMicroseconds( ConvertDateTime(context.ServerNowMs(dataSource), TimeZoneUtil.GetInstanceFromWin32Id(TimeZoneInfo.Local.Id), context.GetOlsonTimeZone()));
2970+
return ResetMicroseconds( ConvertFromLocal(context.ServerNowMs(dataSource), context));
29282971
return ResetMicroseconds(context.ServerNowMs(dataSource));
29292972
}
29302973
static public DateTime ServerNow(IGxContext context, string dataSource)
29312974
{
29322975
if (Preferences.useTimezoneFix())
2933-
return ResetMillisecondsTicks(ConvertDateTime(context.ServerNow(dataSource), TimeZoneUtil.GetInstanceFromWin32Id(TimeZoneInfo.Local.Id), context.GetOlsonTimeZone()));
2976+
return ResetMillisecondsTicks(ConvertFromLocal(context.ServerNow(dataSource), context));
29342977
return ResetMillisecondsTicks(context.ServerNow(dataSource));
29352978
}
29362979
public static string ServerTime(IGxContext context, IDataStoreProvider dataStore)
@@ -3107,6 +3150,7 @@ public static string getYYYYMMDDHHMMSSnosep(DateTime date, bool hasMilliseconds)
31073150
if (hasMilliseconds) sDate += StringUtil.PadL(StringUtil.Str(MilliSecond(date), 3, 0), 3, '0');
31083151
return (sDate);
31093152
}
3153+
31103154
private static DateTime ConvertDateTime(DateTime dt, OlsonTimeZone FromTimezone, OlsonTimeZone ToTimezone)
31113155
{
31123156
if (isNullDate(dt))
@@ -3181,6 +3225,60 @@ public static DateTime DBserver2local(DateTime dt, OlsonTimeZone ClientTimezone)
31813225
throw ex;
31823226
}
31833227
}
3228+
3229+
private static DateTime ConvertDateTime(DateTime dt, string fromTimezone, string toTimezone)
3230+
{
3231+
if (isNullDate(dt))
3232+
return dt;
3233+
3234+
DateTimeZone toZone;
3235+
3236+
if (string.IsNullOrEmpty(toTimezone) || DateTimeZoneProviders.Tzdb[toTimezone]==null)
3237+
toZone = DateTimeZoneProviders.Tzdb.GetSystemDefault();
3238+
else
3239+
toZone = DateTimeZoneProviders.Tzdb[toTimezone];
3240+
3241+
LocalDateTime dtLocal = LocalDateTime.FromDateTime(dt);
3242+
DateTimeZone fromZone = DateTimeZoneProviders.Tzdb[fromTimezone];
3243+
ZonedDateTime fromZoned = dtLocal.InZoneLeniently(fromZone);
3244+
3245+
ZonedDateTime toZoned = fromZoned.WithZone(toZone);
3246+
return toZoned.LocalDateTime.ToDateTimeUnspecified();
3247+
}
3248+
internal static DateTime Local2DBserver(DateTime dt, string clientTimezone)
3249+
{
3250+
try
3251+
{
3252+
Preferences.StorageTimeZonePty storagePty = Preferences.getStorageTimezonePty();
3253+
if (clientTimezone == null || isNullDate(dt) || storagePty == Preferences.StorageTimeZonePty.Undefined)
3254+
return dt;
3255+
string toTimezone = (storagePty == Preferences.StorageTimeZonePty.Utc) ? DateTimeZone.Utc.Id : LocalTimeZoneId;
3256+
return ConvertDateTime(dt, clientTimezone, toTimezone);
3257+
3258+
}
3259+
catch (Exception ex)
3260+
{
3261+
GXLogging.Error(log, ex, "Local2DBserver error");
3262+
throw ex;
3263+
}
3264+
}
3265+
public static DateTime DBserver2local(DateTime dt, string clientTimezone)
3266+
{
3267+
try
3268+
{
3269+
Preferences.StorageTimeZonePty storagePty = Preferences.getStorageTimezonePty();
3270+
if (clientTimezone == null || isNullDate(dt) || storagePty == Preferences.StorageTimeZonePty.Undefined)
3271+
return dt;
3272+
string fromTimezone = (storagePty == Preferences.StorageTimeZonePty.Utc) ? DateTimeZone.Utc.Id : LocalTimeZoneId;
3273+
return ConvertDateTime(dt, fromTimezone, clientTimezone);
3274+
}
3275+
catch (Exception ex)
3276+
{
3277+
GXLogging.Error(log, ex, "DBserver2local error");
3278+
throw ex;
3279+
}
3280+
}
3281+
31843282
public static string FormatDateTimeParmMS(DateTime date)
31853283
{
31863284
if (date.Equals(nullDate))
@@ -3268,6 +3366,21 @@ public static DateTime getTimeAsDate(long ticks)
32683366
{
32693367
return new DateTime(datetTime1970.Ticks + ticks * timeConversionFactor);
32703368
}
3369+
static private DateTime fromUniversalTime(DateTime dt, string toTimezone)
3370+
{
3371+
DateTimeZone toTimeZone = DateTimeZoneProviders.Tzdb[toTimezone];
3372+
Instant instant = Instant.FromDateTimeUtc(dt);
3373+
ZonedDateTime zonedDateTime = instant.InZone(toTimeZone);
3374+
return zonedDateTime.ToDateTimeUnspecified();
3375+
}
3376+
static private DateTime toUniversalTime(DateTime dt, string fromTimezone)
3377+
{
3378+
DateTimeZone localZone = DateTimeZoneProviders.Tzdb[fromTimezone];
3379+
ZonedDateTime localDateTime = LocalDateTime.FromDateTime(dt).InZoneLeniently(localZone);
3380+
ZonedDateTime utcDateTime = localDateTime.ToInstant().InUtc();
3381+
return utcDateTime.ToDateTimeUtc();
3382+
}
3383+
32713384
static private DateTime fromUniversalTime(DateTime dt, OlsonTimeZone ToTimezone)
32723385
{
32733386

@@ -3354,25 +3467,41 @@ static private bool isNullDateCompatible(DateTime dt)
33543467

33553468
static public DateTime fromUniversalTime(DateTime dt)
33563469
{
3470+
#if NODATIME
3471+
return isNullDateCompatible(dt) ? dt : fromUniversalTime(dt, GxContext.Current.GetTimeZone());
3472+
#else
33573473
return isNullDateCompatible(dt) ? dt : fromUniversalTime(dt, GxContext.Current.GetOlsonTimeZone());
3474+
#endif
33583475
}
33593476

33603477
static public DateTime toUniversalTime(DateTime dt)
33613478
{
3479+
#if NODATIME
3480+
return isNullDateCompatible(dt) ? dt : toUniversalTime(dt, GxContext.Current.GetTimeZone());
3481+
#else
33623482
return isNullDateCompatible(dt) ? dt : toUniversalTime(dt, GxContext.Current.GetOlsonTimeZone());
3483+
#endif
33633484
}
33643485

33653486
static public DateTime toUniversalTime(DateTime dt, IGxContext context)
33663487
{
3488+
#if NODATIME
3489+
return isNullDateCompatible(dt) ? dt : toUniversalTime(dt, context.GetTimeZone());
3490+
#else
33673491
return isNullDateCompatible(dt) ? dt : toUniversalTime(dt, context.GetOlsonTimeZone());
3492+
#endif
33683493
}
33693494

33703495
static public DateTime FromTimeZone(DateTime dt, String sTZ, IGxContext context)
33713496
{
3497+
#if NODATIME
3498+
return ConvertDateTime(dt, sTZ, context.GetTimeZone());
3499+
#else
33723500
OlsonTimeZone fromTimeZone = TimeZoneUtil.GetInstanceFromOlsonName(sTZ);
33733501
if (fromTimeZone != null)
33743502
return ConvertDateTime(dt, fromTimeZone, context.GetOlsonTimeZone());
33753503
return dt;
3504+
#endif
33763505
}
33773506

33783507
}

dotnet/src/dotnetframework/GxClasses/Core/gxconfig.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,10 +1187,10 @@ public static StorageTimeZonePty getStorageTimezonePty()
11871187
if (storageTimezone == -1)
11881188
{
11891189
string sValue;
1190-
storageTimezone = (int)StorageTimeZonePty.Undefined;
1190+
int tz = (int)StorageTimeZonePty.Undefined;
11911191
if (Config.GetValueOf("StorageTimeZone", out sValue))
1192-
int.TryParse(sValue, out storageTimezone);
1193-
1192+
int.TryParse(sValue, out tz);
1193+
storageTimezone= tz;
11941194
}
11951195
return (StorageTimeZonePty)storageTimezone;
11961196
}

0 commit comments

Comments
 (0)