1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-02-07 13:27:13 +01:00
Sandu Liviu Catalin 4a6bfc086c Major plugin refactor and cleanup.
Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
2021-01-30 08:51:39 +02:00

229 lines
6.1 KiB
C

/*
* $Id: wce_localtime.c,v 1.2 2006/04/09 16:48:18 mloskot Exp $
*
* Defines localtime() function.
*
* Created by Mateusz Loskot (mateusz@loskot.net)
*
* Copyright (c) 2006 Taxus SI Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* MIT License:
* http://opensource.org/licenses/mit-license.php
*
* Contact:
* Taxus SI Ltd.
* http://www.taxussi.com.pl
*
*/
#include <wce_time.h>
#include <stdlib.h>
#include <windows.h>
/*******************************************************************************
Constants and macros used internally
*******************************************************************************/
#define SECS_PER_MIN 60
#define MINS_PER_HOUR 60
#define HOURS_PER_DAY 24
#define DAYS_PER_WEEK 7
#define DAYS_PER_NYEAR 365
#define DAYS_PER_LYEAR 366
#define SECS_PER_HOUR (SECS_PER_MIN * MINS_PER_HOUR)
#define SECS_PER_DAY ((long) SECS_PER_HOUR * HOURS_PER_DAY)
#define MONS_PER_YEAR 12
#define TM_SUNDAY 0
#define TM_MONDAY 1
#define TM_TUESDAY 2
#define TM_WEDNESDAY 3
#define TM_THURSDAY 4
#define TM_FRIDAY 5
#define TM_SATURDAY 6
#define TM_JANUARY 0
#define TM_FEBRUARY 1
#define TM_MARCH 2
#define TM_APRIL 3
#define TM_MAY 4
#define TM_JUNE 5
#define TM_JULY 6
#define TM_AUGUST 7
#define TM_SEPTEMBER 8
#define TM_OCTOBER 9
#define TM_NOVEBER 10
#define TM_DECEMBER 11
#define TM_SUNDAY 0
#define TM_YEAR_BASE 1900
#define EPOCH_YEAR 1970
#define EPOCH_WDAY TM_THURSDAY
#define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)
/*******************************************************************************
Local time functions
*******************************************************************************/
struct tm * __wceex_offtime(const time_t *timer, long tzoffset);
/*******************************************************************************
* wceex_localtime - Convert time_t value to tm struct.
*
* Description:
* Use offset as difference in seconds between local time and UTC time.
*
*******************************************************************************/
struct tm * wceex_localtime(const time_t *timer)
{
register struct tm *tmp;
long tzoffset;
TIME_ZONE_INFORMATION tzi;
// Retrive timezone offset in seconds
tzoffset = 0;
if (GetTimeZoneInformation(&tzi) != 0xFFFFFFFF)
{
tzoffset += (tzi.Bias * 60);
if (tzi.StandardDate.wMonth != 0)
{
tzoffset += (tzi.StandardBias * 60);
}
}
tzoffset *= -1;
tmp = __wceex_offtime(timer, tzoffset);
return tmp;
}
/*******************************************************************************
* wceex_gmtime - Convert time_t value to tm struct.
*
* Description:
* This function is similar to localtime, except that the broken-down
* time is expressed as Coordinated Universal Time (UTC)
* rather than relative to a local time zone.
*
*******************************************************************************/
struct tm * wceex_gmtime(const time_t *timer)
{
register struct tm *tmp;
tmp = __wceex_offtime(timer, 0L);
return tmp;
}
/*******************************************************************************
* __wceex_offtime - Convert time_t value to tm struct.
*
* Description:
* Use offset as difference in seconds between local time and UTC time.
*
*******************************************************************************/
static int mon_lengths[2][MONS_PER_YEAR] =
{
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
static int year_lengths[2] = { DAYS_PER_NYEAR, DAYS_PER_LYEAR };
struct tm * __wceex_offtime(const time_t *timer, long tzoffset)
{
register struct tm *tmp;
register long days;
register long rem;
register int y;
register int yleap;
register int *ip;
static struct tm tm;
tmp = &tm;
days = *timer / SECS_PER_DAY;
rem = *timer % SECS_PER_DAY;
rem += tzoffset;
while (rem < 0)
{
rem += SECS_PER_DAY;
--days;
}
while (rem >= SECS_PER_DAY)
{
rem -= SECS_PER_DAY;
++days;
}
tmp->tm_hour = (int) (rem / SECS_PER_HOUR);
rem = rem % SECS_PER_HOUR;
tmp->tm_min = (int) (rem / SECS_PER_MIN);
tmp->tm_sec = (int) (rem % SECS_PER_MIN);
tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYS_PER_WEEK);
if (tmp->tm_wday < 0)
tmp->tm_wday += DAYS_PER_WEEK;
y = EPOCH_YEAR;
if (days >= 0)
{
for ( ; ; )
{
yleap = isleap(y);
if (days < (long) year_lengths[yleap])
break;
++y;
days = days - (long) year_lengths[yleap];
}
}
else
{
do
{
--y;
yleap = isleap(y);
days = days + (long) year_lengths[yleap];
} while (days < 0);
}
tmp->tm_year = y - TM_YEAR_BASE;
tmp->tm_yday = (int) days;
ip = mon_lengths[yleap];
for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
{
days = days - (long) ip[tmp->tm_mon];
}
tmp->tm_mday = (int) (days + 1);
tmp->tm_isdst = 0;
return tmp;
}