Get/Set Windows Mobile 5 date/time using C#.NET
When the backup battery on your Windows Mobile 5 device runs out, there's a good chance the date/time settings of the device will revert to a time in the past. The devices I'm working on (The Symbol MC70), for example, revert back to a date in 2005.
This poses a problem in particular if you are designing an application for inexperienced users that will probably not even notice the change. When correct date settings are vital to your application, you have a recipe for disaster.
Luckily for me I picked this up very early in the testing phase, and without much help from the MSDN article on setting the devices date, I came up with a working solution. The code supplied on the MSDN site did not even compile due to large syntax errors. This was my first time using P/Invoke so there was a bit of trial and error. I got there in the end. Once again to possibly save someone else the headache, here is the working code for C#.NET CompactFramework 2.0.
struct SYSTEMTIME
{
public void LoadDateTime(DateTime dateTime)
{
this.Year = (UInt16)dateTime.Year;
this.Month = (UInt16)dateTime.Month;
this.Day = (UInt16)dateTime.Day;
this.Hour = (UInt16)dateTime.Hour;
this.Minute = (UInt16)dateTime.Minute;
this.Second = (UInt16)dateTime.Second;
this.MilliSecond = (UInt16)dateTime.Millisecond;
}
public UInt16 Year;
public UInt16 Month;
public UInt16 DayOfWeek;
public UInt16 Day;
public UInt16 Hour;
public UInt16 Minute;
public UInt16 Second;
public UInt16 MilliSecond;
}
[DllImport("Coredll.dll", EntryPoint = "SetSystemTime")]
private static extern bool SetSystemTime(ref SYSTEMTIME st);
public void CorrectTime()
{
if (DateTime.Now.Year <2007)
{
try
{
Thread thread = new Thread(new ThreadStart(UpdateSystemTime));
thread.Start();
}
catch
{
MessageBox.Show("Please adjust the time and date settings", "URGENT");
}
}
}
public void UpdateSystemTime()
{
DateTime serverTime = GetServerHeaders.GetServerTime("http://www.google.com");
serverTime = serverTime.ToUniversalTime();
SYSTEMTIME sysTime = new SYSTEMTIME();
sysTime.LoadDateTime(serverTime);
bool worked = SetSystemTime(ref sysTime);
}
#endregion CorrectTime
public static string GetHeader(string url, string header)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "HEAD";
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return resp.Headers.Get(header);
}
public static DateTime GetServerTime(string url)
{
string dateHeader = GetHeader(url, "Date");
return DateTime.Parse(dateHeader);
}
What does it do? It queries a web server (in the example I have used google, but you can use any server that you trust to hold accurate time) and gets the servers time. It then sets the time on the local device. It should work correctly even with multiple time zones, as long as you have the the time zone settings correctly set on your device.
Please note that this is not always the best way to set the time (ie getting the time from a public webserver), but it is good if you have strong policies on your devices to stop users accessing general web sites. For my purposes I used the web site that my devices synchronise with anyway. This is good for me for the following reasons...
- Security: I can use the web site which the devices connect to already.
- Reliability: Will work over GPRS, WiFi, or when in a cradle. Can thus work even with Flight Mode turned on.
- Predictable: There was probably a way to use time servers automatically from within the device, but this may have used more data than I wanted to. It could have updated itself multiple times per day. At least with the above method, I know how much data a request uses and that it will only run if the date is obviously reset.
I have chosen 2007 as the year to check, as it is currently 2007 and my devices always set back to 2005. Obviously you need to choose a date between the default date of your device, and the current date.

on July 11th, 2007 at 2:55 am
What is this “GetServerHeaders()” function? It doesn’t compile and there is no reference to it in MSDN.
on July 11th, 2007 at 3:00 am
Never mind … figured it out. You didn’t have a class declaration above. I was thinking you were attempting to use a .NET class and didn’t even look at the possibility that it was one of your own. Sorry for entering the comment above.
on December 14th, 2007 at 4:32 am
Hi,
I have same exact problem, I am going find a fix for it, my users are not very tech savvy, so they encounter this problem quite often..
I am going to get the server time form my server and the server date doesn’t match with device time, I will give a warning, the time from the Google server returns GMT time, that will not help me.. Is there a way to find it from SIM card?
Thanks for the posting!
Susmitha
on December 15th, 2007 at 9:46 am
Hello Susmitha. You are correct that google will return a UTC/GMT time. This should be okay as long as the time zone is set correctly on the device. In fact UTC times are preferable for this reason.
on April 26th, 2008 at 4:39 pm
Hey ,
It is good piece of code works like champ !!! I did test this code on my Pocket PC 2003 and it works perfect.
I am wondering if there is any VC++ / MFC alternative code for the same. It seems that DateTime, HttpWebRequest, Response .. etc are not available for MFC or Win32. I would really appreciate if someone could point me equalent Win32 / MFC API to acheivi this functionality.
on May 17th, 2008 at 5:02 pm
HI,
I am facing the same problem in Intermec CN3 (Windows Mobile 5.0). When battery down, time settings revert to default value.
I tried the code you provide, but it is not working. Sometimes errors are coming…
1. PI invoke failed
2. Specified method not found.
Could you please help me to solve this issue. asap
Thanks and Regards
Ashish
on June 14th, 2008 at 2:31 am
Hi,
I used the same code to change time of my PDA having Windows Moblie 5.0 O/S according to my server but i am only getting time from my server,time is not being set as the method “UpdateSystemTime()” and “SetSystemTime()” are not working.I am giving the code which i have used to to update Date/Time of PDA with our server.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
//using System.Timers;
using System.Runtime.InteropServices;
using System.Threading;
using System.Net;
namespace DeviceApplication1
{
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
struct SYSTEMTIME {
public void LoadDateTime(DateTime dateTime) {
this.Year = (UInt16)dateTime.Year;
this.Month = (UInt16)dateTime.Month;
this.Day = (UInt16)dateTime.Day;
this.Hour = (UInt16)dateTime.Hour;
this.Minute = (UInt16)dateTime.Minute;
this.Second = (UInt16)dateTime.Second;
this.MilliSecond = (UInt16)dateTime.Millisecond;
}
public UInt16 Year;
public UInt16 Month;
public UInt16 Day;
public UInt16 Hour;
public UInt16 Minute;
public UInt16 Second;
public UInt16 MilliSecond;
}
[DllImport(”Coredll.dll”, EntryPoint = “SetSystemTime”)]
private static extern bool SetSystemTime(ref SYSTEMTIME st);
public void UpdateSystemTime() {
textBox1.Text = GetServerTime(”http://www.google.com”).ToString();
DateTime serverTime = GetServerTime(”http://www.google.com”);
serverTime = serverTime.ToUniversalTime();
SYSTEMTIME sysTime = new SYSTEMTIME();
sysTime.LoadDateTime(serverTime);
bool yesno = SetSystemTime(ref sysTime);
if (yesno.Equals(true))
MessageBox.Show(”Success in setting time”);
else
MessageBox.Show(”Failure in setting time”);
}
//#endregion CorrectTime
public static string GetHeader(string url, string header)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = “HEAD”;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return resp.Headers.Get(header);
}
public static DateTime GetServerTime(string url)
{
string dateHeader = GetHeader(url, “Date”);
return DateTime.Parse(dateHeader);
}
private void button1_Click_1(object sender, EventArgs e)
{
string str;
str = “http://www.google.com”;
button1.Text = “DisplayTime1″;
textBox1.Text = GetServerTime(str).ToString();
}
private void BtnOK_Click_1(object sender, EventArgs e)
{
BtnOK.Text = “Clicked1″;
UpdateSystemTime();
}
}
}
Note:I want to use my home server in place of “www.google.com”.
Now kindly guide me why the method “SetSystemTime()” is not working to set the PDA time?? I have used this code in “DeviceApplication” in VC#.NET environment.
Regards:
Nitin Singh
on July 3rd, 2008 at 9:05 pm
Hi all,
in GetHeader you need close HttpWebResponse
resp.Close();
public static string GetHeader(string url, string header)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = “HEAD”;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
string response_str = resp.Headers.Get(header);
resp.Close();
return response_str;
}
from MSDN:
The Close method closes the response stream and releases the connection to the resource for reuse by other requests.
You must call either the Stream..::.Close or the HttpWebResponse..::.Close method to close the stream and release the connection for reuse. It is not necessary to call both Stream..::.Close and HttpWebResponse..::.Close, but doing so does not cause an error. Failure to close the stream can cause your application to run out of connections.
on July 23rd, 2008 at 4:13 pm
Hi,
I used same code to change time of PDA having Windows Mobile 5.0 O/S,it is working well.But this code is not being supporetd by JAVA as our application is in Java and this program is in C#.NET.Finally my purpose to change PDA time having Window Mobile 5.0 is not fullfiled.My problem is that i want to change PDA time having Window Mobile 5.0 using a java program which can be called through our Java aplication.
Can someonne guide me what to do now.?? Can anyone provide me the source code in java or in othere language (so that can be called by java application)
on September 29th, 2008 at 9:13 pm
Any idea how to set the timezone programmatically in c# for windows mobile
Thanks,
http://probedeep.blogspot.com/