-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Closed
Description
Note
Using Vatican time zone as an example.
Steps to Reproduce
- Turn off NTP time synchronization for linux
sudo timedatectl set-ntp off
- Turn off any other network time synchronization services that may be active
- Set the time zone on the server to the Vatican time zone
sudo timedatectl set-timezone Europe/Vatican
- Set the time of the OS to 1 hour and 1 minute before the reported DST Exit datetime of 10/28/2018 3:00:00 AM
sudo date 102801592018.00
- Run a mono application that prints the time.
- Wait for an 1 hour and compare the application's time to the OS's time
Current Behavior
The mono application will not transition out of DST for two hours past DST exit.
OS Linux Run Output
$ date
Sun Oct 28 02:59:55 CEST 2018
$ date
Sun Oct 28 02:59:57 CEST 2018
$ date
Sun Oct 28 02:00:00 CET 2018 << System Time correctly drops out of DST
$ date
Sun Oct 28 02:00:02 CET 2018
Mono application run:
Before transition
-----------------------------------------------
DateTime.Now: 10/28/2018 2:59:58 AM
Cleared: DateTime.Now: 10/28/2018 2:59:58 AM
UTC+Offset: 10/28/2018 2:59:58 AM
636762923986794550 - Start: 3/25/2018 2:00:00 AM:636575400000000000 - End: 10/28/2018 3:00:00 AM:636762924000000000 - True
In DST
UTC: 10/28/2018 00:59:58 - Offset: 02:00:00
-----------------------------------------------
After transition
-----------------------------------------------
DateTime.Now: 10/28/2018 3:00:03 AM
Cleared: DateTime.Now: 10/28/2018 3:00:03 AM
UTC+Offset: 10/28/2018 3:00:03 AM
636762924036831780 - Start: 3/25/2018 2:00:00 AM:636575400000000000 - End: 10/28/2018 3:00:00 AM:636762924000000000 - True
Not in DST
UTC: 10/28/2018 01:00:03 - Offset: 02:00:00
-----------------------------------------------
The current time is still reporting that we are in DST. 3AM instead of 2AM The print "Not in DST" is from the application calculating that we have exited DST based on the ticks of the system.
If the application is allowed to run for another hour, mono will partially transition.
The UTC+Offset calculation will be correct, but the DateTime.Now will still return the incorrect information.
-----------------------------------------------
DateTime.Now: 10/28/2018 4:14:01 AM
Cleared: DateTime.Now: 10/28/2018 4:14:01 AM
UTC+Offset: 10/28/2018 3:14:01 AM
636762968419149760 - Start: 3/25/2018 2:00:00 AM:636575400000000000 - End: 10/28/2018 3:00:00 AM:636762924000000000 - False
Not in DST
UTC: 10/28/2018 02:14:01 - Offset: 01:00:00
-----------------------------------------------
Waiting one more hour, the mono application's DateTime.Now will be in sync with the system time
-----------------------------------------------
DateTime.Now: 10/28/2018 4:18:39 AM
Cleared: DateTime.Now: 10/28/2018 4:18:39 AM
UTC+Offset: 10/28/2018 4:18:39 AM
636762971197489090 - Start: 3/25/2018 2:00:00 AM:636575400000000000 - End: 10/28/2018 3:00:00 AM:636762924000000000 - False
Not in DST
UTC: 10/28/2018 03:18:39 - Offset: 01:00:00
-----------------------------------------------
Platforms
Ubuntu 16.04.4 LTS
Mono JIT compiler version 5.4.0.201 (tarball Tue Mar 13 14:55:42 UTC 2018)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS: __thread
SIGSEGV: altstack
Notifications: epoll
Architecture: x86
Disabled: profiler
Misc: softdebug
LLVM: supported, not enabled.
GC: sgen (concurrent by default)
Mono application's code
using System;
using System.Globalization;
using System.Threading;
namespace NowTest
{
class Program
{
static void Main(string[] args)
{
//run forever
while (true)
{
Console.WriteLine("-----------------------------------------------");
//Print some DateTime.Net information
Console.WriteLine("DateTime.Now: {0}", DateTime.Now);
CultureInfo.CurrentCulture.ClearCachedData();
Console.WriteLine("Cleared: DateTime.Now: {0}", DateTime.Now);
Console.WriteLine("UTC+Offset: {0}", GetLocalTime());
var currTimeZone = TimeZone.CurrentTimeZone;
var now = DateTime.Now;
var dstInfo = currTimeZone.GetDaylightChanges(now.Year);
var inDST = currTimeZone.IsDaylightSavingTime(now);
var offset = currTimeZone.GetUtcOffset(now);
var utcDateTime = DateTime.UtcNow;
//Print some more information for fun
Console.WriteLine("{0} - Start: {1}:{2} - End: {3}:{4} - {5}", now.Ticks, dstInfo.Start, dstInfo.Start.Ticks, dstInfo.End, dstInfo.End.Ticks, inDST);
//If I do the match for the ticks, let's see if we are following everything correctly
if (now.Ticks > dstInfo.Start.Ticks)
{
Console.WriteLine(now.Ticks > dstInfo.End.Ticks ? "Not in DST" : "In DST");
}
Console.WriteLine("UTC: {0} - Offset: {1}", utcDateTime.ToString(CultureInfo.InvariantCulture), offset.ToString());
Console.WriteLine("-----------------------------------------------{0}", Environment.NewLine);
//Print every 5 seconds for kicks
Thread.Sleep(5000);
}
}
//return the local time using UTC offset and UTC Now
static DateTime GetLocalTime()
{
//Try to clear the cache and see if that helps...
System.Globalization.CultureInfo.CurrentCulture.ClearCachedData();
return (DateTime.UtcNow + TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now));
}
}
}lewurm