D
Dave Hall
If the time zone is changed on my CE 4.1 device, or in the VS 2003 emulator
while my application is running, the DateTime class in the .NET CF does not
correctly report the current local time Here's how to reproduce the
problem: Compile & run the code shown below then change the time zone
through the standard date/time control panel applet while the application is
running. Notice that the clock in the system tray is quickly adjusted to
correspond to the new time zone, and the value returned by P/Invoking
GetLocalTime() in my application also reflects the change, but
System.DateTime.Now does not reflect the new time zone unless I stop and
restart the application. I haven't tried to see if a new thread that's
started after the timezone change would show the correct time or not,
although I'm curious about that too. If I change the external dll reference
per the comment, and run the same code on my W2K workstation with the full
..NET framework, I don't have any problem with the DateTime failing to adjust
to a timezone change, so it seems to be a CF bug. Since I am using
Console.WriteLine, the app below won't display on a PPC, so I don't know if
it has the same problem. I haven't bothered to rewrite it for the PPC since
my target is a specific CE device. My CE application needs to be able to
handle changing time zones while running, and I don't want to change every
reference to DateTime.Now to P/Invoke GetLocalTime() if I can help it, so I
have four questions:
1) Can someone try this code on a CE .NET 4.2 CF device and let me know if
it's fixed in 4.2?
2) Does anyone know if this is a known and documented bug in the CF?
2) Does anyone know if any service packs for Version 4.1 of the CF that
specifically mention and resolve this problem?
3) Does anyone know of any simple programatic work arounds other than
replacing DateTime.Now with GetLocalTime()?
Thanks,
Dave
Here's the offending code. It's pretty short.
==============================================================
using System;
using System.Runtime.InteropServices;
namespace RTCTest
{
public class ClockTest
{
static void Main()
{
SYSTEMTIME systemTime = new SYSTEMTIME();
for(int i=0; i<300; i++)
{
SYSTEMTIME.GetLocalTime(ref systemTime);
Console.WriteLine("DateTime = {0} \t GetLocalTime = {1}",
System.DateTime.Now.ToString("G"),
systemTime.ToString());
System.Threading.Thread.Sleep(1000);
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public UInt16 Year;
public UInt16 Month;
public UInt16 DayOfWeek;
public UInt16 Day;
public UInt16 Hour;
public UInt16 Minute;
public UInt16 Second;
public UInt16 Millisecond;
public override string ToString()
{
return String.Format(@"{0}/{1}/{2,44} {3}:{4,22}:{5,22} {6}",
this.Month,
this.Day,
this.Year,
(((this.Hour + 11) % 12) + 1),
this.Minute,
this.Second,
(this.Hour < 12) ? "AM" : "PM");
}
// use Kernel32.dll for full .NET or coredll.dll for .NET CF
// [DllImport("Kernel32.dll", EntryPoint="GetLocalTime",
SetLastError=true)]
[DllImport("coredll.dll", EntryPoint="GetLocalTime", SetLastError=true)]
public extern static void GetLocalTime(ref SYSTEMTIME systemTime);
}
}
while my application is running, the DateTime class in the .NET CF does not
correctly report the current local time Here's how to reproduce the
problem: Compile & run the code shown below then change the time zone
through the standard date/time control panel applet while the application is
running. Notice that the clock in the system tray is quickly adjusted to
correspond to the new time zone, and the value returned by P/Invoking
GetLocalTime() in my application also reflects the change, but
System.DateTime.Now does not reflect the new time zone unless I stop and
restart the application. I haven't tried to see if a new thread that's
started after the timezone change would show the correct time or not,
although I'm curious about that too. If I change the external dll reference
per the comment, and run the same code on my W2K workstation with the full
..NET framework, I don't have any problem with the DateTime failing to adjust
to a timezone change, so it seems to be a CF bug. Since I am using
Console.WriteLine, the app below won't display on a PPC, so I don't know if
it has the same problem. I haven't bothered to rewrite it for the PPC since
my target is a specific CE device. My CE application needs to be able to
handle changing time zones while running, and I don't want to change every
reference to DateTime.Now to P/Invoke GetLocalTime() if I can help it, so I
have four questions:
1) Can someone try this code on a CE .NET 4.2 CF device and let me know if
it's fixed in 4.2?
2) Does anyone know if this is a known and documented bug in the CF?
2) Does anyone know if any service packs for Version 4.1 of the CF that
specifically mention and resolve this problem?
3) Does anyone know of any simple programatic work arounds other than
replacing DateTime.Now with GetLocalTime()?
Thanks,
Dave
Here's the offending code. It's pretty short.
==============================================================
using System;
using System.Runtime.InteropServices;
namespace RTCTest
{
public class ClockTest
{
static void Main()
{
SYSTEMTIME systemTime = new SYSTEMTIME();
for(int i=0; i<300; i++)
{
SYSTEMTIME.GetLocalTime(ref systemTime);
Console.WriteLine("DateTime = {0} \t GetLocalTime = {1}",
System.DateTime.Now.ToString("G"),
systemTime.ToString());
System.Threading.Thread.Sleep(1000);
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public UInt16 Year;
public UInt16 Month;
public UInt16 DayOfWeek;
public UInt16 Day;
public UInt16 Hour;
public UInt16 Minute;
public UInt16 Second;
public UInt16 Millisecond;
public override string ToString()
{
return String.Format(@"{0}/{1}/{2,44} {3}:{4,22}:{5,22} {6}",
this.Month,
this.Day,
this.Year,
(((this.Hour + 11) % 12) + 1),
this.Minute,
this.Second,
(this.Hour < 12) ? "AM" : "PM");
}
// use Kernel32.dll for full .NET or coredll.dll for .NET CF
// [DllImport("Kernel32.dll", EntryPoint="GetLocalTime",
SetLastError=true)]
[DllImport("coredll.dll", EntryPoint="GetLocalTime", SetLastError=true)]
public extern static void GetLocalTime(ref SYSTEMTIME systemTime);
}
}