mirror of
https://github.com/reactos/reactos.git
synced 2024-08-21 10:53:15 +00:00
152 lines
2.9 KiB
C
152 lines
2.9 KiB
C
/*
|
|
* COPYRIGHT: LGPL, See LGPL.txt in the top level directory
|
|
* PROJECT: ReactOS CRT library
|
|
* FILE: lib/sdk/crt/time/mktime.c
|
|
* PURPOSE: Implementation of mktime, _mkgmtime
|
|
* PROGRAMERS: Timo Kreuzer
|
|
*/
|
|
#include <precomp.h>
|
|
#include "bitsfixup.h"
|
|
|
|
#define MAX_32BIT_TIME 0xFFFFFFFFULL
|
|
|
|
static int g_monthdays[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
|
|
|
|
__time64_t
|
|
mktime_worker(struct tm * ptm, int utc)
|
|
{
|
|
struct tm *ptm2;
|
|
__time64_t time;
|
|
int mons, years, leapyears;
|
|
TIME_ZONE_INFORMATION tzi;
|
|
DWORD ret;
|
|
|
|
/* Normalize year and month */
|
|
if (ptm->tm_mon < 0)
|
|
{
|
|
mons = -ptm->tm_mon - 1;
|
|
ptm->tm_year -= 1 + mons / 12;
|
|
ptm->tm_mon = 11 - (mons % 12);
|
|
}
|
|
else if (ptm->tm_mon > 11)
|
|
{
|
|
mons = ptm->tm_mon;
|
|
ptm->tm_year += (mons / 12);
|
|
ptm->tm_mon = mons % 12;
|
|
}
|
|
|
|
/* Is it inside margins */
|
|
if (ptm->tm_year < 70 || ptm->tm_year > 139) // FIXME: max year for 64 bits
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
years = ptm->tm_year - 70;
|
|
|
|
/* Number of leapyears passed since 1970 */
|
|
leapyears = (years + 1) / 4;
|
|
|
|
/* Calculate days up to 1st of Jan */
|
|
time = years * 365 + leapyears;
|
|
|
|
/* Calculate days up to 1st of month */
|
|
time += g_monthdays[ptm->tm_mon];
|
|
|
|
/* Check if we need to add a leap day */
|
|
if (((years + 2) % 4) == 0)
|
|
{
|
|
if (ptm->tm_mon > 2)
|
|
{
|
|
time++;
|
|
}
|
|
}
|
|
|
|
time += ptm->tm_mday - 1;
|
|
|
|
time *= 24;
|
|
time += ptm->tm_hour;
|
|
|
|
time *= 60;
|
|
time += ptm->tm_min;
|
|
|
|
time *= 60;
|
|
time += ptm->tm_sec;
|
|
|
|
if (time < 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
/* Finally get normalized tm struct */
|
|
ptm2 = _gmtime64(&time);
|
|
if (!ptm2)
|
|
{
|
|
return -1;
|
|
}
|
|
*ptm = *ptm2;
|
|
|
|
/* Finally adjust by the difference to GMT in seconds */
|
|
ret = GetTimeZoneInformation(&tzi);
|
|
if (ret != TIME_ZONE_ID_INVALID)
|
|
{
|
|
time += tzi.Bias * 60;
|
|
}
|
|
|
|
return time;
|
|
}
|
|
|
|
/* int tm_sec;
|
|
int tm_min;
|
|
int tm_hour;
|
|
int tm_mday;
|
|
int tm_mon;
|
|
int tm_year;
|
|
int tm_wday;
|
|
int tm_yday;
|
|
int tm_isdst;
|
|
*/
|
|
|
|
/**
|
|
* \name _mkgmtime
|
|
*
|
|
*/
|
|
time_t
|
|
_mkgmtime(struct tm *ptm)
|
|
{
|
|
__time64_t time = mktime_worker(ptm, 1);
|
|
return (time_t)((time > MAX_32BIT_TIME) ? -1 : time);
|
|
}
|
|
|
|
time_t
|
|
mktime(struct tm *ptm)
|
|
{
|
|
__time64_t time = mktime_worker(ptm, 0);
|
|
return (time_t)((time > MAX_32BIT_TIME) ? -1 : time);
|
|
}
|
|
|
|
__time32_t
|
|
_mkgmtime32(struct tm *ptm)
|
|
{
|
|
__time64_t time = mktime_worker(ptm, 1);
|
|
return (__time32_t)((time > MAX_32BIT_TIME) ? -1 : time);
|
|
}
|
|
|
|
__time32_t
|
|
_mktime32(struct tm *ptm)
|
|
{
|
|
__time64_t time = mktime_worker(ptm, 0);
|
|
return (__time32_t)((time > MAX_32BIT_TIME) ? -1 : time);
|
|
}
|
|
|
|
__time64_t
|
|
_mkgmtime64(struct tm *ptm)
|
|
{
|
|
return mktime_worker(ptm, 1);
|
|
}
|
|
|
|
__time64_t
|
|
_mktime64(struct tm *ptm)
|
|
{
|
|
return mktime_worker(ptm, 0);
|
|
}
|