forked from KolibriOS/kolibrios
3be3768ce0
git-svn-id: svn://kolibrios.org@614 a494cfbc-eb01-0410-851d-a64ba20cac60
104 lines
4.1 KiB
C
104 lines
4.1 KiB
C
/****************************************************************************
|
|
*
|
|
* Open Watcom Project
|
|
*
|
|
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* This file contains Original Code and/or Modifications of Original
|
|
* Code as defined in and that are subject to the Sybase Open Watcom
|
|
* Public License version 1.0 (the 'License'). You may not use this file
|
|
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
|
|
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
|
|
* provided with the Original Code and Modifications, and is also
|
|
* available at www.sybase.com/developer/opensource.
|
|
*
|
|
* The Original Code and all software distributed under the License are
|
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
|
|
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
|
|
* NON-INFRINGEMENT. Please see the License for the specific language
|
|
* governing rights and limitations under the License.
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* Description: mktime() without timezone and struct tm fields adjustment.
|
|
* used by mktime() and DOS clock()
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "variety.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <limits.h>
|
|
#include "rtdata.h"
|
|
#include "timedata.h"
|
|
|
|
#define MONTH_YR ( 12 )
|
|
#define DAY_YR ( 365 )
|
|
#define HOUR_YR ( DAY_YR * 24 )
|
|
#define MINUTE_YR ( HOUR_YR * 60 )
|
|
#define SECOND_YR ( MINUTE_YR * 60 )
|
|
#define __MONTHS ( INT_MIN / MONTH_YR )
|
|
#define __DAYS ( INT_MIN / DAY_YR )
|
|
|
|
// these ones can underflow in 16bit environments,
|
|
// so check the relative values first
|
|
#if ( HOUR_YR ) < ( INT_MAX / 60 )
|
|
#define __MINUTES ( INT_MIN / MINUTE_YR )
|
|
#if ( MINUTE_YR ) < ( INT_MAX / 60 )
|
|
#define __SECONDS ( INT_MIN / SECOND_YR )
|
|
#else
|
|
#define __SECONDS ( 0 )
|
|
#endif
|
|
#else
|
|
#define __MINUTES ( 0 )
|
|
#define __SECONDS ( 0 )
|
|
#endif
|
|
|
|
#define SMALLEST_YEAR_VALUE ( __MONTHS + __DAYS + __MINUTES + __SECONDS )
|
|
|
|
time_t __local_mktime( const struct tm *t, long *pdays, long *pseconds )
|
|
{
|
|
int month;
|
|
int year;
|
|
long days;
|
|
long seconds;
|
|
short const *month_start;
|
|
|
|
month_start = __diyr;
|
|
month = t->tm_mon % 12; /* put tm_mon into range */
|
|
year = t->tm_year;
|
|
if( year < SMALLEST_YEAR_VALUE )
|
|
return( ( time_t ) -1 );
|
|
year += t->tm_mon / 12;
|
|
while( month < 0 )
|
|
--year, month += 12;
|
|
if( year < 0 )
|
|
return( ( time_t ) -1 );
|
|
if( __leapyear( ( unsigned ) ( year + 1900 ) ) )
|
|
month_start = __dilyr;
|
|
days = year * 365L /* # of days in the years */
|
|
+ ( ( year + 3 ) / 4 ) /* add # of leap years before year */
|
|
- ( ( year + 99 ) / 100 ) /* sub # of leap centuries */
|
|
+ ( ( year + 399 - 100 ) / 400 ) /* add # of leap 4 centuries */
|
|
/* adjust for 1900 offset */
|
|
/* note: -100 == 300 (mod 400) */
|
|
+ month_start[month] /* # of days to 1st of month*/
|
|
+ t->tm_mday - 1; /* day of the month */
|
|
seconds = ( ( ( long ) ( t->tm_hour ) ) *60L + ( long ) ( t->tm_min ) ) *60L + t->tm_sec;
|
|
/* seconds needs to be positive for __brktime */
|
|
while( seconds < 0 )
|
|
days -= 1, seconds += ( long ) SECONDS_PER_DAY;
|
|
while( seconds >= ( long ) SECONDS_PER_DAY )
|
|
days += 1, seconds -= ( long ) SECONDS_PER_DAY;
|
|
if( days < ( DAYS_FROM_1900_TO_1970 - 1 ) )
|
|
return( ( time_t ) -1 );
|
|
if ( pdays ) *pdays = days;
|
|
if ( pseconds ) *pseconds = seconds;
|
|
return( seconds + ( days - DAYS_FROM_1900_TO_1970 ) * ( long ) SECONDS_PER_DAY );
|
|
}
|