- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
276 lines
7.6 KiB
C++
276 lines
7.6 KiB
C++
/*------------------------------------------------------------------------*/
|
|
/* */
|
|
/* TIME.CPP */
|
|
/* */
|
|
/* Copyright (c) 1993, 1994 Borland International */
|
|
/* All Rights Reserved */
|
|
/* */
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
#if !defined( __TIME_H )
|
|
#include <time.h>
|
|
#endif
|
|
|
|
#if !defined( __STDIO_H )
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
#if !defined( __CHECKS_H )
|
|
#include <checks.h>
|
|
#endif
|
|
|
|
#if !defined( CLASSLIB_TIME_H )
|
|
#include <classlib/time.h>
|
|
#endif
|
|
|
|
enum TimeZone { CarolineIslands=-11, MarianaIslands, Japan,
|
|
China, minusSeven, minusSix,
|
|
Pakistan, CaspianSea, Turkey,
|
|
Finland, Europe, Greenwich,
|
|
Azores, two, Greenland,
|
|
Atlantic, USEastern, USCentral,
|
|
USMountain, USPacific, Alaska,
|
|
Hawaii, Bearing};
|
|
|
|
static const unsigned long SECONDS_IN_DAY = 86400L;
|
|
static const unsigned long SECONDS_IN_HOUR = 3600L;
|
|
static const unsigned SECONDS_IN_MIN = 60;
|
|
|
|
// Be sure that you have set your environment variable TZ.
|
|
// For example, for Pacific coast time, set TZ=PDT8PST.
|
|
// For other time zones, see your manuals.
|
|
|
|
struct TInitTime
|
|
{
|
|
TInitTime()
|
|
{ tzset(); }
|
|
};
|
|
|
|
static TInitTime cludgeTime; // To force the call to tzset()
|
|
|
|
|
|
const TDate TTime::RefDate( (DayTy)0, (YearTy)0 );
|
|
const TDate TTime::MaxDate( (DayTy)49709L, (YearTy)0 ); // ((2**32)-1)/SECONDS_IN_DAY -1
|
|
static const int SUNDAY = 7;
|
|
|
|
int TTime::AssertDate( const TDate _BIDSFAR & date )
|
|
{
|
|
return date.Between(RefDate,MaxDate);
|
|
}
|
|
|
|
/******************* private member functions ***********************/
|
|
|
|
|
|
// Adjust for local time zone and Daylight Savings Time.
|
|
ClockTy TTime::LocalSecs() const
|
|
{
|
|
TTime local_time( Sec - timezone );
|
|
if (local_time.IsDST())
|
|
local_time.Sec += SECONDS_IN_HOUR;
|
|
return local_time.Sec;
|
|
}
|
|
|
|
/*
|
|
* Builds the time from a local time, adjusting to GMT. Does *not* adjust for DST.
|
|
*/
|
|
TTime TTime::BuildLocal( const TDate _BIDSFAR & date, HourTy h )
|
|
{
|
|
return TTime( SECONDS_IN_DAY * (date-RefDate) +
|
|
SECONDS_IN_HOUR * h +
|
|
timezone);
|
|
}
|
|
|
|
/*************** public static member functions *******************/
|
|
|
|
/*
|
|
* Return the time at which DST starts for the given year.
|
|
* Note that the time returned is the time at which DST starts locally,
|
|
* but it is returned in GMT.
|
|
*/
|
|
TTime TTime::BeginDST( unsigned year )
|
|
{
|
|
if( year > 1986 )
|
|
{
|
|
TDate endMarch(31, 3, year);
|
|
return BuildLocal( endMarch.Previous(SUNDAY)+7, 2 );
|
|
}
|
|
|
|
// Ah, remember those energy conscious years...???
|
|
if( year==1974 )
|
|
return BuildLocal( TDate(6,1,1974), 2 );
|
|
if( year==1975 )
|
|
return BuildLocal( TDate(23,2,1975), 2 );
|
|
|
|
TDate endApril( 30, 4, year );
|
|
return BuildLocal( endApril.Previous(SUNDAY), 2 );
|
|
}
|
|
|
|
|
|
/*
|
|
* Return the time at which DST ends for the given year.
|
|
* Note that the time returned is the time at which DST ends locally,
|
|
* but it is returned in GMT.
|
|
*/
|
|
TTime TTime::EndDST( unsigned year )
|
|
{
|
|
TDate endOctober( 31, 10, year );
|
|
return BuildLocal( endOctober.Previous(SUNDAY), 1 );
|
|
}
|
|
|
|
|
|
/************************* constructor *********************************/
|
|
|
|
// Construct TTime with current time (seconds since Jan 1, 1901).
|
|
TTime::TTime()
|
|
{
|
|
time_t ltime;
|
|
time(<ime);
|
|
struct tm _FAR *t = localtime(<ime);
|
|
|
|
// Construct the date. The time struct returns int, so casts are used.
|
|
|
|
TDate today( (DayTy)t->tm_mday,
|
|
(MonthTy)(t->tm_mon + 1),
|
|
(YearTy)t->tm_year );
|
|
|
|
*this = TTime( today,
|
|
(HourTy)t->tm_hour,
|
|
(MinuteTy)t->tm_min,
|
|
(SecondTy)t->tm_sec );
|
|
}
|
|
|
|
// Specified time and today's date:
|
|
TTime::TTime( HourTy h, MinuteTy m, SecondTy s )
|
|
{
|
|
Sec = TTime( TDate(),h,m,s ).Sec;
|
|
}
|
|
|
|
/*
|
|
* Construct a Time for the specified (local) Date, hour, minute, and second.
|
|
* Note: this algorithm will fail if DST correction is something other
|
|
* than an hour.
|
|
* It is complicated by the DST boundary problem:
|
|
* 1) Times in the phantom zone between 2AM and 3AM when DST is invoked are invalid.
|
|
* 2) Times in the hour after 1AM when DST ends, are redundant.
|
|
* Checking for these situations necessitates a lot of jumping back
|
|
* and forth by an hour to check for the boundary.
|
|
*/
|
|
TTime::TTime( const TDate _BIDSFAR & date, HourTy h, MinuteTy m, SecondTy s )
|
|
{
|
|
if( date.IsValid() )
|
|
{
|
|
Sec = SECONDS_IN_DAY * (date-RefDate) +
|
|
SECONDS_IN_HOUR * (h-1L) + /* Note the adjustment by one hour */
|
|
SECONDS_IN_MIN * m + s;
|
|
if( Sec )
|
|
Sec += timezone; // Adjust to GMT.
|
|
|
|
if( IsDST() )
|
|
{
|
|
Sec += SECONDS_IN_HOUR;
|
|
if( IsDST() )
|
|
Sec -= SECONDS_IN_HOUR;
|
|
}
|
|
else
|
|
{
|
|
Sec += SECONDS_IN_HOUR;
|
|
if( IsDST() )
|
|
Sec = 0; // Invalid "phantom" time.
|
|
}
|
|
}
|
|
else
|
|
Sec = 0; // Invalid date
|
|
}
|
|
|
|
/*************** conversion from TTime to TDate *******************/
|
|
|
|
// Type conversion to date.
|
|
TDate::TDate( const TTime _BIDSFAR & t )
|
|
{
|
|
Julnum = t.IsValid() ? jul1901 + (JulTy)(t.LocalSecs()/SECONDS_IN_DAY) : 0;
|
|
}
|
|
|
|
/********************* public member functions **********************/
|
|
|
|
int TTime::CompareTo( const TTime _BIDSFAR &t ) const
|
|
{
|
|
ClockTy diff = Sec - t.Sec;
|
|
return diff==0 ? 0 : diff>0 ? 1 : -1;
|
|
}
|
|
|
|
// Hash function:
|
|
unsigned TTime::Hash() const
|
|
{
|
|
return (unsigned)Sec;
|
|
}
|
|
|
|
/*
|
|
* The hour in local time:
|
|
*/
|
|
HourTy TTime::Hour() const
|
|
{
|
|
return HourTy((LocalSecs() % SECONDS_IN_DAY) / SECONDS_IN_HOUR);
|
|
}
|
|
|
|
/*
|
|
* The hour in GMT:
|
|
*/
|
|
HourTy TTime::HourGMT() const
|
|
{
|
|
return HourTy((Sec % SECONDS_IN_DAY) / SECONDS_IN_HOUR);
|
|
}
|
|
|
|
/*
|
|
* Return TRUE if DST is active for this time:
|
|
*/
|
|
int TTime::IsDST() const
|
|
{
|
|
if( !daylight )
|
|
return 0;
|
|
|
|
DayTy daycount = (unsigned)(Sec/SECONDS_IN_DAY);
|
|
YearTy year = TDate( (DayTy)daycount, (YearTy)0 ).Year();
|
|
|
|
// Check to see if the time falls between the starting & stopping DST times.
|
|
return *this >= BeginDST( year ) && *this < EndDST( year );
|
|
}
|
|
|
|
TTime TTime::Max( const TTime _BIDSFAR & t ) const
|
|
{
|
|
if( *this > t )
|
|
return *this;
|
|
else
|
|
return t;
|
|
}
|
|
|
|
TTime TTime::Min( const TTime _BIDSFAR & t ) const
|
|
{
|
|
if( *this < t )
|
|
return *this;
|
|
else
|
|
return t;
|
|
}
|
|
|
|
/*
|
|
* minute, in local time
|
|
*/
|
|
MinuteTy TTime::Minute() const
|
|
{
|
|
return MinuteTy(((LocalSecs()%SECONDS_IN_DAY)%SECONDS_IN_HOUR)/SECONDS_IN_MIN);
|
|
}
|
|
|
|
/*
|
|
* minute: GMT
|
|
*/
|
|
MinuteTy TTime::MinuteGMT() const
|
|
{
|
|
return MinuteTy(((Sec%SECONDS_IN_DAY)%SECONDS_IN_HOUR)/SECONDS_IN_MIN);
|
|
}
|
|
|
|
// second;local time or GMT
|
|
SecondTy TTime::Second() const
|
|
{
|
|
return SecondTy(((Sec%SECONDS_IN_DAY)%SECONDS_IN_HOUR)%SECONDS_IN_MIN);
|
|
}
|
|
|