How to set system time in Windows 10 IoT?
Asked Answered
P

8

16

Is there a way to set system time from my app running on a Raspberry Pi 2 in Windows 10 IoT Core Insider Preview?

This doesn't work for lack of kernel32.dll

    [DllImport("kernel32.dll", EntryPoint = "SetSystemTime", SetLastError = true)]
    extern static bool Win32SetSystemTime(ref SystemTime sysTime);
Pidgin answered 2/6, 2015 at 1:28 Comment(9)
I don't see any "capability" that would allow you to do that from inside the sandbox -- msdn.microsoft.com/en-us/library/windows/apps/hh464936.aspxStarbuck
Outside of program code, you should be able to open a PowerShell on an IOT device and run the Set-Date command.Chronic
Mm yes powershell works, that's how I have been doing it but that, combined with no system ui effectively would mean there's no way to have accurate time on it as an independent device. Hope they fix that by release time. The clock seems to drift significantly especially if the device is powered off then powered on again. (eg Being powered off over night caused nearly a 10 minute error)Pidgin
The Pi doesn't have an RTC so will be getting the time from NTP servers on every boot. If your not happy with this you can get RTC add-ons for the Pi such as the one here: thepihut.com/products/mini-rtc-module-for-raspberry-piNinanincompoop
@Ninanincompoop From empirical testing it appears that it either does not or usually does not get data from NTP automatically... The last half dozen or so boots it consistently started at the same time a month ago and stayed there.Pidgin
I would suggest this is a Windows 10 specific issue then. The raspberry pi 2 running on linux does get the time from NTP.Ninanincompoop
@Ninanincompoop yes it is, specific to Windows 10 IoT with Universal AppsPidgin
By that I mean an actual bug/issue with Windows 10 not acting as it should rather than it being something your application should look to solve. Obviously that doesn't help you right now unfortunately and I am not 100% sure a sandboxed app such as a Windows 10 universal app will ever really be allowed to make a system wide change like changing the time. A temporary workaround might be possible with powershell and scheduled tasks? ms-iot.github.io/content/en-US/win10/tools/CommandLineUtils.htmNinanincompoop
@Ninanincompoop I came up with a work around I'll post in a momentPidgin
F
11

First, connect to your Pi 2 using PowerShell.

Use the command set-date to set the time. For example, if you want to set the date to Saturday, October 3, 2015, 2:00PM, you would type set-date 10/3/2015 2:00PM.

The command tzutil sets the time zone. Type tzutil /? for usage

Foretop answered 3/10, 2015 at 18:2 Comment(4)
The question was how to set it from an app. As mentioned in the comments I understand how to set it from powershell. It is however impractical to connect to powershell to set the time every time the device is turned on. The device would then be only usable if always tethered to a computer,Pidgin
The date should be between quotes: set-date "10/3/2015 2:00PM"Housebroken
I set the datetime using -> set-date "8/25/2017 2:32PM", but after a while it resets / changes. So, the tzutil is needed to correctly set the timezone, as the Pi will automatically try to update the current datetime based on a time server.Increate
This "best answer" is outdated. Just uses the API windows now provides with DateTimeSettings.SetSystemDateSeagrave
S
8

1-New Universal Project
2-Add Reference>Extensions>Windows IOT Extensions for UWP
3- Put a button, a datepicker and a timepicer control on your MainPage.xaml
and

private void buttonSetSystemDatetime_Click(object sender, RoutedEventArgs e)
        {
            DateTimeOffset dto = datePicker1.Date+ timePicker1.Time;
            Windows.System.DateTimeSettings.SetSystemDateTime(dto);
        }

4- in poject settings> set your target version and min version 10.0; build 16299
5- double click appxmanifest > Capabilities > check ON "System Management"

6- run app in IOT and press button. than return to default app. voila! system datetime changed.

note: rather to set it everytime. I offer you buy a cheap rtc (real time clock) module. (also needs extra coding)

Subglacial answered 19/12, 2017 at 9:30 Comment(1)
I used this answer with https://mcmap.net/q/161684/-how-to-query-an-ntp-server-using-c to force a time sync when connectivity to IoT Hub fails due to SAS token expiryMcbroom
H
4

You can call any PowerShell routine from C# on UWP/IoT-Core systems. As such, the PowerShell commands are always available in/to your App.

For an example, see the ProcessLauncher sample on GitHub.

ALTERNATIVE, schedule a startup PS script as follows:

Run PowerShell as an Administrator on the board (Press the Windows button, and start typing PowerShell, right click on the icon and select “Run as Administrator”).

Set-ExecutionPolicy RemoteSigned

PuTTy to RPi as admin and:

setx PATH "%PATH%;C:\Windows\System32"

schtasks /create /tn "StartupPowerShell" /tr c:\Startup.bat /sc onstart /ru SYSTEM

Startup.bat

powershell -command "C:\IotCoreStartup.ps1"

IotCoreStartup.ps

$logFile = 'C:\StartupLog.txt'

get-date > $logFile

tzutil /s "UTC" >> $logFile

# set alternate time servers
"Setting additional time servers" >> $logFile
w32tm /config /syncfromflags:manual /manualpeerlist:"0.windows.time.com 1.pool.ntp.org" >> $logFile

Deleting a scheduled task if required:

schtasks /Delete /TN "StartupPowerShell"

Running a scheduled task if to test:

schtasks /Run /tn "StartupPowerShell"

Had answered 24/11, 2015 at 19:23 Comment(2)
No, you can't call PowerShell commands in a UWP app. According to : social.msdn.microsoft.com/Forums/sqlserver/en-US/…Bufflehead
It works via the ProcessLauncher (ms-iot.github.io/content/en-US/win10/samples/…). Just call a script.cmd that then uses PowerShell. A bit convoluted, but works. I'll take a look at your link, thanks.Had
P
3

Seemingly as of now there appears to be no way to actually edit the system time, but here is a work around I came up with to get correct time in your app at least. I created a TimeManager class, the important parts are as follows.

Get the correct time how ever you want (e.g. NTP, other network time, user input, etc) and input into the UpdateOffset method.

In the rest of the App use TimeManager.Now instead of DateTime.Now

    static TimeSpan _offset = new TimeSpan(0,0,0);
    public static TimeSpan CurrentOffset //Doesn't have to be public, it is for me because I'm presenting it on the UI for my information
    {
        get { return _offset; }
        private set { _offset = value; }
    }

    public static DateTime Now
    {
        get
        {
            return DateTime.Now - CurrentOffset;
        }
    }

    static void UpdateOffset(DateTime currentCorrectTime) //May need to be public if you're getting the correct time outside of this class
    {
        CurrentOffset = DateTime.UtcNow - currentCorrectTime;
        //Note that I'm getting network time which is in UTC, if you're getting local time use DateTime.Now instead of DateTime.UtcNow. 
    }

I also suggest adding things like tracking the last update time, and flag to indicate whether the time has ever been updated, just didn't want to clutter up the code sample.

Pidgin answered 4/6, 2015 at 14:48 Comment(0)
L
3

I used a RTC to set the time on my Raspberry Pi. While Windows-iot doesn't have native support for initializing the Raspberry Pi's software clock from a real time clock after several hours of considering options I found something that works for me.

I made a console program that can either save the system time to the RTC or read the time in the RTC and print it as a string. I made a power shell script that will run this program at the time of system startup to get the time from the real time clock and pass the string to the set-date command.

Details are here: http://www.codeproject.com/Articles/1113626/Adding-the-Missing-Real-Time-Clock-to-Windows-IoT

Landreth answered 21/7, 2016 at 2:59 Comment(0)
G
2

Use Renci SSH shell to sign back into the device as an administrator and then use powershell command to set date and time.

public static int SshCommand(string command, out string dataOut, out string error)
    {

        dataOut = "";
        error = "";

        try
        {

            using (var client = new SshClient("127.0.0.1", USER_NAME, PASSWORD))
            {
                client.Connect();
                //command = "powershell -Command " + "\u0022" + "set-date -date '8/10/2017 8:30:00 AM'" + "\u0022";
                //command = "netsh interface ip show config";
                var cmd = client.RunCommand(command);
                var output = cmd.Result;
                client.Disconnect();
            }

            return 1;
        }
        catch (Exception ex)
        {
            error = ex.Message;
            return 0;
        }

    }


public static int SSHSetDateTime(DateTime dateTime)
    {

        // Variables
        int returnValue = 0;
        string command;
        string error;
        string dataOut;

        // Build date
        command = String.Format("powershell -Command \u0022set-date -date '{0:M/d/yyyy H:mm:ss tt}'\u0022", dateTime);

        //Build date
        if (SystemEx.SshCommand(command, out dataOut, out error) == 1)
        {
            // Ok
            returnValue = 1;
        }

        // Return
        return returnValue;

    }
Gorse answered 19/1, 2017 at 8:6 Comment(0)
P
1

I realize you are asking how to do this programmatically, however, the following should provide enough information to create a PS script to run at startup.

Remote Access Raspberry Pi via Powershell

1.) Run the Windows 10 IoT Core Watcher utility (C:\Program Files (x86)\Microsoft IoT\WindowsIoTCoreWatcher.exe) on your development PC and copy your Raspberry Pi IP address by right-clicking on the detected device and selecting Copy IP Address.

◦Click the windows "Start" button

◦Type "WindowsIoTCoreWatcher" to pull it up in the search results

◦You may want to right click on the program name and select "Pin to Start" to pin it to your start screen for easy access

◦Press Enter to run it

◦Your device should appear in the list within 5 seconds or so. If it does not, close the Windows 10 IoT Core Watcher, and relaunch it again

Windows IoT Core Watcher

2.) Launch an administrator PowerShell console on your local PC. The easiest way to do this is to type "powershell" in the Search the web and Windows textbox near the Windows Start Menu. Windows will find PowerShell on your machine. Right-click the Windows PowerShell entry and select Run as administrator. The PS console will show.

Running Powershell as Administrator

3.) You may need to start the WinRM service on your desktop to enable remote connections. From the PS console type the following command:

 net start WinRM 

4.) From the PS console, type the following command, substituting '' with the IP value copied in prev:

 Set-Item WSMan:\localhost\Client\TrustedHosts -Value <machine-name or IP Address>

5.Type Y and press Enter to confirm the change.

6.Now you can start a session with you Windows IoT Core device. From you administrator PS console, type:

Enter-PSSession -ComputerName <IP Address> -Credential localhost\Administrator

7.In the credential dialog enter the following default password:

p@ssw0rd

Note: The connection process is not immediate and can take up to 30 seconds.

If you successfully connected to the device, you should see the IP address of your device before the prompt.

Connected to the Raspberry using PS

Renaming your Device and Setting the Date and Time

1.To change the computer name, use the setcomputername utility. In PowerShell, type the following command.

setcomputername

2.The date and time on the Pi must be correct for the security tokens used to publish to Azure later in the lab to be valid. To check the current time zone setting on the Pi, type:

tzutil /g

3.If the time zone reported is not correct, you can find a list of valid time zones using (you may need to increase the buffer size on your powershell window):

tzutil /l

4.To set the time zone, locate the id of the time zone you want from the step above, then use:

tzutil /s "Your TimeZone Name"

For example, for "Pacific Standard Time"

tzutil /s "Pacific Standard Time"

5.To check the date on the Raspberry Pi, type

Get-Date

6.If the date or time is incorrect, use the Set-Date utility

Set-Date "mm/dd/yy hh:mm:ss AM/PM"

For Example, if it was 12:15 pm on January 3rd, 2016:

Set-Date "01/03/16 12:15 PM"

7.Reboot the device for the change to take effect. You can use the shutdown command as follows:

shutdown /r /t 0

Phosphorus answered 11/3, 2016 at 16:13 Comment(1)
interestingly set-date doesnt working at all in win IOTSubglacial
T
1

refer to Microsoft API Reference Docs and in the Windows.System namespace you can sets the system date and time with SetSystemDateTime method.

but you must know it`s available in

  • Windows IoT Extension SDK (introduced v10.0.16225.0) and above

you can use DateTimeSettings static class

public static class DateTimeSettings

then call SetSystemDateTime static method and send your object of DateTimeOffset type for setting date and time on Windows Iot.

public static void SetSystemDateTime(DateTimeOffset utcDateTime)

https://learn.microsoft.com/en-us/uwp/api/windows.system.datetimesettings

Torsibility answered 1/8, 2017 at 5:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.