kolibrios/programs/develop/open watcom/trunk/clib/time/locmktim.c

104 lines
4.1 KiB
C
Raw Normal View History

/****************************************************************************
*
* 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 );
}