I'm pulling the time and date from the internet because when the user turns the Raspberry Pi off, it loses its date and time settings and unfortunately Windows 10 IoT is very slow to correct it.
I have tried to use the DateTime
method, however, I can't seem to work out how to create a Clock
with a custom time and have it tick like as if i was to call DateTime.Now.ToShortTimeString();
(I'm not asking anyone to implement this).
Here is the following code that will scrap the information I need and parse
it. The code works, however, sometimes there is lag (I'm guessing because the RPI isn't all that powerful) resulting in the time sometimes missing a second due to it trying to catch up I guess.
I'm not too worried about it being out by a couple of seconds however if you leave the program running on the Pi for a long period of time, it will end up being out by 20 mins to an hour depending on how long the application has been running.
Here is the code that I have created in a console application to make it a little more neater and to show where I'm guessing the problem is and if there is a better way to complete my task at hand.
class Program
{
struct TimeAndDate
{
public int hour;
public int minute;
public int second;
public DateTime date;
public bool completed;
}
static TimeAndDate timeAndDate;
static Clock clock;
static void Main(string[] args)
{
getTime();
Console.ReadLine();
DateTime.Now.ToShortTimeString();
}
private static async void getTime()
{
Console.WriteLine("Entered getTime");
string time = "";
try
{
string pattern = @"<tr><td colspan=2 align=""center"" bgcolor=""#FFFFFF""><h5>([^>]*)</td></tr>";
Task t = Task.Run(async () =>
{
string website = "http://www.worldtimezone.com/time/wtzresult.php?CiID=1225&forma=Find%20Time";
using (HttpClient client = new HttpClient())
using (HttpResponseMessage response = await client.GetAsync(website))
using (HttpContent content = response.Content)
{
string data = await content.ReadAsStringAsync();
foreach (Match match in (new Regex(pattern).Matches(data)))
{
time = match.Groups[1].Value;
}
}
});
await t;
}
catch
{
Console.WriteLine("getTime Error");
timeAndDate.completed = false;
}
DateTime datetime;
if (DateTime.TryParse(time, out datetime))
{
timeAndDate.hour = datetime.Hour;
timeAndDate.minute = datetime.Minute;
timeAndDate.second = datetime.Second;
Console.WriteLine(datetime.ToString("hh:mm:ss"));
Console.WriteLine(datetime.Date.ToString("dd/MM/yyyy"));
timeAndDate.completed = true;
clock = new Clock(timeAndDate.hour, timeAndDate.minute, timeAndDate.second);
while(true)
{
Console.WriteLine(clock.displayTime());
await Task.Delay(1000);
clock.Tick();
//Console.Clear();
}
}
else
{
Debug.WriteLine("Invalid Format");
timeAndDate.date = DateTime.Now;
timeAndDate.completed = false;
}
}
class Clock
{
private int hour;
private int minute;
private int second;
public Clock(int hh, int mm, int ss)
{
this.hour = hh;
this.minute = mm;
this.second = ss;
}
public void Tick()
{
this.second++;
if(this.second == 60)
{
this.minute++;
this.second = 00;
}
else if(this.minute == 60)
{
this.hour++;
this.minute = 00;
}
else if(this.hour == 24)
{
this.hour = 00;
}
}
public string displayTime()
{
return this.hour.ToString("D2") + ":" + this.minute.ToString("D2") + ":" + this.second.ToString("D2");
}
}
}
If worse comes to worse and I can't do much about it, I could always call the method needed every 10 or so minutes to correct the time. However, I was hoping I wouldn't need to do so.
getTime
is declared as anasync void
rather thanasync Task<T>
. With the very first garbage collection,getTime
will stop working even though there's awhile (true)
that does some console output... \$\endgroup\$