SetLocalTime fails when compiled in Release

I can’t find information on the web, so I don’t know if this can be a specific problem related to Toradex CE 6 image.

Function SetLocalTime works when the application is built in Debug, but it fails when it’s built in Release.

When it fails, it returns 0; calling GetLastError() returns 57 (which is quite strange because this error should be ERROR_ADAP_HDW_ERR - A network adapter hardware error occurred).

The issue it’s quite easy to reproduce with the following code:

SYSTEMTIME lt;
lt.wDay = 1;
lt.wMonth = 6;
lt.wYear = 2018;
lt.wHour = 12;
lt.wMinute = 0;
lt.wSecond = 0;

if(!SetLocalTime(&lt)) {
printf("SetLocalTime error %x\r\n", GetLastError());
}

In this way I can’t set the device datetime from my application.

Dear @vix

There are two additional fields in the struct, which you should define:

 lt.wDayOfWeek = 0;
 lt.wMilliseconds = 0;

It looks like wDayOfWeek is ingored, but if wMilliseconds is set to a higher value than 999, SetLocalTime() returns with an error.

I assume the LastError does not properly get set, so it is just a random value from any previous error that occured anywhere in the system (In my case GetLastError() returns 6).

In debug mode, the whole struct ltgets initialized, while in release mode the content is undefined. This explains why you don’t see the problem in debug mode.

Regards, Andy

Hi @andy.tx

I tried to initialize both wDayOfWeek and wMilliseconds to 0, but this didn’t help.

I found that I did a mistake with the error code from GetLastError; it is 0x57 (i.e. 87 as a decimal number, which is ERROR_INVALID_PARAMETER - The parameter is incorrect).
The error code has sense, but I can’t find the reason (and how to fix).

Hi @vix
I cannot reproduce the problem. Please try to run the following executable:

I built it using the following source:

 SYSTEMTIME lt;

 lt.wDay            = 1;
 lt.wMonth          = 6;
 lt.wYear           = 2018;
 lt.wHour           = 12;
 lt.wMinute         = 00;
 lt.wSecond         = 00;
 lt.wDayOfWeek      = 0;
 lt.wMilliseconds   = 000;
 if(SetLocalTime(&lt)) 
     printf("SetLocalTime successful 0x%x\r\n", GetLastError());
 else
     printf("SetLocalTime error 0x%x\r\n", GetLastError());
 getchar();
 return GetLastError();

Regards, Andy

Dear @vix

Somwhere I’ve read, that the SYSTEMTIME structure needs to be set completely (as @andy.tx already indicated.
Therfore I retrieve the current time first and then just update the necessary datafileds:

        SYSTEMTIME localTime;
        GetLocalTime(&localTime);
        localTime.wDay = newDate.day();
        localTime.wMonth = newDate.month();
        localTime.wYear = newDate.year();

        if (SetLocalTime(&localTime)){
            success = true;
        }

Kind regards,

Thomas

Hi @andy.tx

I confirm that you example works, so I investigated deeper and I found the reason for my issue.
I set SYSTEMTIME members from a string using sscanf(), but I used the wrong format specifiers.

They are WORD (i.e. unsigned short) and the right format specifier is %hu. Using the wrong one %d (which is for 32-bit integers) is undefined behavior.

So the right way to populate SYSTEMTIME fields from a string is

sscanf(dateString, "%hu/%hu/%hu", &lt.wDay, &lt.wMonth, &lt.wYear);
sscanf(timeString, "%hu:%hu:%hu", &lt.wHour, &lt.wMinute, &lt.wSecond);