Converting windows SYSTEMTIME to a standard struct tm

J

jacob navia

Under windows, time is represented as a SYSTEMTIME structure that is
similar but not equivalent to the standard struct tm that is used by the
C language to represent time.

Since strftime uses a structure tm, it is necessary to convert the
Microsoft structure to the standard one.

Here is an attempt to do the conversion that *apparently* works.
I would be grateful if you take a critic look at it since those
apparently "simple" functions can hide an endless reserve of new bugs...

compile with
my_compiler -DTEST to see the conversion

--------------------------------------------cut here
#include <time.h>
#include <windows.h>
typedef struct _SYSTEMTIME {
unsigned short wYear;
unsigned short wMonth;
unsigned short wDayOfWeek;
unsigned short wDay;
unsigned short wHour;
unsigned short wMinute;
unsigned short wSecond;
unsigned short wMilliseconds;
} SYSTEMTIME;
int SystemTime2StructTM(SYSTEMTIME *st,struct tm * ptm)
{

ptm->tm_isdst = -1; /* mktime() computes whether this is */
/* during Standard or Daylight time. */
ptm->tm_sec = (int)st->wSecond;
ptm->tm_min = (int)st->wMinute;
ptm->tm_hour = (int)st->wHour;
ptm->tm_mday = (int)st->wDay;
ptm->tm_mon = (int)st->wMonth - 1;
ptm->tm_year = (int)st->wYear - 1900;
ptm->tm_wday = (int)st->wDayOfWeek;

/* Normalize uninitialized fields */
if ((time_t)mktime(ptm) == (time_t)-1)
return 0;

return 1;
}

int StructTM2SystemTime(struct tm * ptm, SYSTEMTIME *st)
{
/* Normalize uninitialized fields */
if ((time_t)mktime(ptm) == (time_t)-1)
return 0;

st->wYear = (unsigned short)(ptm->tm_year + 1900);
st->wMonth = (unsigned short)(ptm->tm_mon + 1);
st->wDay = (unsigned short)ptm->tm_mday;
st->wHour = (unsigned short)(ptm->tm_hour);
st->wMinute = (unsigned short)ptm->tm_min;
st->wSecond = (unsigned short)ptm->tm_sec;

return 1;
}

#ifdef TEST
int main(void)
{
SYSTEMTIME timebuf;
struct tm stm;
char buf[512];

GetSystemTime(&timebuf); //Time of the day
SystemTime2StructTM(&timebuf,&stm);
strftime(buf,sizeof(buf),"%a %d %m %Y , %H:%M:%S",&stm);
puts(buf);
// Test a roundtrip conversion that should give the same value
StructTM2SystemTime(&stm,&timebuf);
SystemTime2StructTM(&timebuf,&stm);
strftime(buf,sizeof(buf),"%a %d %m %Y , %H:%M:%S",&stm);
puts(buf);
}
#endif
 
I

Ian Collins

jacob said:
Under windows, time is represented as a SYSTEMTIME structure that is
similar but not equivalent to the standard struct tm that is used by the
C language to represent time.

Since strftime uses a structure tm, it is necessary to convert the
Microsoft structure to the standard one.

Here is an attempt to do the conversion that *apparently* works.
I would be grateful if you take a critic look at it since those
apparently "simple" functions can hide an endless reserve of new bugs...

compile with
my_compiler -DTEST to see the conversion

--------------------------------------------cut here
#include <time.h>
#include <windows.h>
typedef struct _SYSTEMTIME {
unsigned short wYear;
unsigned short wMonth;
unsigned short wDayOfWeek;
unsigned short wDay;
unsigned short wHour;
unsigned short wMinute;
unsigned short wSecond;
unsigned short wMilliseconds;
} SYSTEMTIME;
int SystemTime2StructTM(SYSTEMTIME *st,struct tm * ptm)
{

ptm->tm_isdst = -1; /* mktime() computes whether this is */
/* during Standard or Daylight time. */
ptm->tm_sec = (int)st->wSecond;
ptm->tm_min = (int)st->wMinute;
ptm->tm_hour = (int)st->wHour;
ptm->tm_mday = (int)st->wDay;
ptm->tm_mon = (int)st->wMonth - 1;
ptm->tm_year = (int)st->wYear - 1900;
ptm->tm_wday = (int)st->wDayOfWeek;

/* Normalize uninitialized fields */
if ((time_t)mktime(ptm) == (time_t)-1)
return 0;

Why all the superfluous casts? They clutter the code.
 
J

jacob navia

Le 22/02/2014 01:16, Ian Collins a écrit :
Why all the superfluous casts? They clutter the code.
Yes, I got used to cast everything because MSVC, Microsoft compiler,
will emit endless warnings when assigning an int to a short or a long
long to an int. In this case when converting from short to int it is
just overkill, you are right.
 
I

Ike Naar

int StructTM2SystemTime(struct tm * ptm, SYSTEMTIME *st)
{
/* Normalize uninitialized fields */
if ((time_t)mktime(ptm) == (time_t)-1)
return 0;

st->wYear = (unsigned short)(ptm->tm_year + 1900);
st->wMonth = (unsigned short)(ptm->tm_mon + 1);
st->wDay = (unsigned short)ptm->tm_mday;
st->wHour = (unsigned short)(ptm->tm_hour);
st->wMinute = (unsigned short)ptm->tm_min;
st->wSecond = (unsigned short)ptm->tm_sec;

return 1;
}

st->wDayOfWeek is not set?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,900
Latest member
Nell636132

Latest Threads

Top