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);
GEOCHET
  • 21,119
  • 15
  • 74
  • 98
raven-ai
  • 253
  • 1
  • 2
  • 11
  • I don't see any "capability" that would allow you to do that from inside the sandbox -- https://msdn.microsoft.com/en-us/library/windows/apps/hh464936.aspx – Ben Voigt Jun 02 '15 at 03:00
  • Outside of program code, you should be able to open a PowerShell on an IOT device and run the `Set-Date` command. – Dai Jun 02 '15 at 05:27
  • 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) – raven-ai Jun 02 '15 at 11:39
  • 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: http://thepihut.com/products/mini-rtc-module-for-raspberry-pi – dannykay1710 Jun 03 '15 at 12:08
  • @dannykay1710 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. – raven-ai Jun 03 '15 at 20:22
  • I would suggest this is a Windows 10 specific issue then. The raspberry pi 2 running on linux does get the time from NTP. – dannykay1710 Jun 04 '15 at 09:15
  • @dannykay1710 yes it is, specific to Windows 10 IoT with Universal Apps – raven-ai Jun 04 '15 at 12:17
  • 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? https://ms-iot.github.io/content/en-US/win10/tools/CommandLineUtils.htm – dannykay1710 Jun 04 '15 at 13:32
  • @dannykay1710 I came up with a work around I'll post in a moment – raven-ai Jun 04 '15 at 14:27

8 Answers8

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

kiran
  • 127
  • 1
  • 4
  • 1
    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, – raven-ai Oct 04 '15 at 21:32
  • 4
    The date should be between quotes: `set-date "10/3/2015 2:00PM"` – Maxence May 30 '16 at 14:15
  • 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. – T.S Aug 25 '17 at 12:33
  • This "best answer" is outdated. Just uses the API windows now provides with DateTimeSettings.SetSystemDate – Dane Bouchie Mar 12 '19 at 12:42
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)

Zen Of Kursat
  • 2,672
  • 1
  • 31
  • 47
  • I used this answer with https://stackoverflow.com/a/33328911/1690217 to force a time sync when connectivity to IoT Hub fails due to SAS token expiry – Chris Schaller May 14 '18 at 00:41
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"

Community
  • 1
  • 1
GGleGrand
  • 1,565
  • 1
  • 20
  • 45
  • No, you can't call PowerShell commands in a UWP app. According to : https://social.msdn.microsoft.com/Forums/sqlserver/en-US/7835e702-7bff-4076-a2da-006e6828d940/uwprun-powershell-commands-inside-of-an-uwa-with-c?forum=wpdevelop – ftes Feb 19 '16 at 09:22
  • 2
    It works via the ProcessLauncher (https://ms-iot.github.io/content/en-US/win10/samples/ProcessLauncherSample.htm). Just call a script.cmd that then uses PowerShell. A bit convoluted, but works. I'll take a look at your link, thanks. – GGleGrand Feb 19 '16 at 09:26
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.

raven-ai
  • 253
  • 1
  • 2
  • 11
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

Joel
  • 2,230
  • 1
  • 20
  • 28
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;

    }
Dipiks
  • 3,818
  • 2
  • 23
  • 39
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

Paul DeCarlo
  • 416
  • 2
  • 10
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

Parsa Karami
  • 702
  • 1
  • 8
  • 30