Re: Need a Pascal equivalent to C's difftime()




"Heinrich Wolf" <invalid@xxxxxxxxxxxxxxx> schrieb im Newsbeitrag
news:es8g0c$vca$1@xxxxxxxxxxxxxxxxxxxxx
Hi,

when I look at the definition
double difftime(time_t time2, time_t time1);
then it almost reduces to me as

double difftime(time_t time2, time_t time1)
{
return time2 - (double) time1;
}

When I compare it to TP5.5 GetTime and GetDate,
then you rather need a really complicated stuff called
time_t mktime(struct tm *tm_struct);
which is available in today's C,
but neither in TC 2.0 nor in TP5.5.

Some time ago ...

.... I also coded mktime() for using it in TC2.0 etc.
The code uses some macros coming from various compilers,
e.g. on SCO Unix, SINIX 5.2 (NSC), TC2.0

I'm sorry! mktime() is C, not PASCAL.
But maybe you know how to cross-translate.

mktime needs the environment variable TZ (time zone)!
But for difftime() that doesn't matter.

Since again my code uses German words,
here are some translations:
German - English
Zeit - time
Jahr - year
Monat - month
Tag - day
Stunde - hour
Minute - minute
Sekunde - second
Schaltjahr - leap year
Beispiel - example
z.B. - e.g.
ab - from
bis - until

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

/*
DOS:
BIOS = localtime
TZ default = "EST5EDT"

Beispiel auf Unix:
BIOS = 7:00
gmtime = 6:00
localtime = 8:00
TZ = MET-1DST
tm_isdst = 1
*/

int Monat_Len[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
extern char *tzname[2];

#ifdef __TURBOC__
#define mktime mktime_x
#endif

#ifdef _MSC_VER
#if _MSC_VER < 1200
#define mktime mktime_x
#endif
#endif

void CheckSchaltjahr(unsigned int Jahr)
/* Jahr ab 1583, ueber 2100 hinaus */
{
if ((Jahr % 400 == 0) || (Jahr % 4 == 0) && (Jahr % 100 > 0))
Monat_Len[1] = 29;
else
Monat_Len[1] = 28;
}

struct tm *gmtime_x(time_t *lZeit)
/* 01.01.1970 00:00:00 bis 07.02.2106 06:28:15 */
{
unsigned long l,
Schaltjahre;
static struct tm zeit;

memset(&zeit, 0, sizeof(zeit));

l = *lZeit;

zeit.tm_sec = (int) ( l % 60);
l /= 60;
zeit.tm_min = (int) ( l % 60);
l /= 60;
zeit.tm_hour = (int) ( l % 24);
l /= 24;
zeit.tm_wday = (int) ((l + 4) % 7);

/*
l | tm_year | 4 * l |
------------------+---------+-------------------+---
364 | 70 | 4 * 365 + 1 - 5 |
365 | 71 | 4 * 365 + 1 - 1 | +4
365 + 364 | 71 | 8 * 365 + 2 - 6 | -5
2 * 365 | 72 | 8 * 365 + 2 - 2 | +4
2 * 365 + 365 | 72 | 12 * 365 + 3 - 3 | -1
3 * 365 + 1 | 73 | 12 * 365 + 3 + 1 | +4
3 * 365 + 1 + 364 | 73 | 16 * 365 + 4 - 4 | -5
4 * 365 + 1 | 74 | 16 * 365 + 4 + 0 | +4
4 * 365 + 1 + 364 | 74 | 20 * 365 + 5 - 5 | -5
*/

if (l < 47482 /* 1.1.2100 */)
zeit.tm_year = (4 * l + 2) / (4 * 365 + 1) + 70;
else
zeit.tm_year = (4 * l + 6) / (4 * 365 + 1) + 70;
Schaltjahre = (zeit.tm_year - 69) / 4;
if (zeit.tm_year > 200)
Schaltjahre --;
l -= (zeit.tm_year - 70) * 365L + Schaltjahre;
zeit.tm_yday = l;
CheckSchaltjahr(zeit.tm_year + 1900);
while (l >= Monat_Len[zeit.tm_mon])
{
l -= Monat_Len[zeit.tm_mon];
zeit.tm_mon ++;
}
zeit.tm_mday = l + 1;
return &zeit;
}

void tzset_x(void)
{
char *TZ,
*p;
float fStunde;
int Args,
Minuten,
iStunde;

Args = 0;
TZ = getenv("TZ");
if (TZ)
{
/* z.B. VAR-3:30VAS */
strcpy(tzname[0], "");
strncat(tzname[0], TZ, 3);
p = strstr(TZ, ",M");
if (! p)
p = TZ + strlen(TZ);
strcpy(tzname[1], "");
if (p - 3 < TZ)
strncat(tzname[1], TZ, 3);
else
strncat(tzname[1], p - 3, 3);
if (strlen(TZ) > 3)
Args = sscanf(TZ + 3, "%f:%d",
&fStunde,
&Minuten);
}
switch (Args)
{
case 1:
Minuten = ((int) (fStunde * 60)) % 60;
iStunde = (int) fStunde;
break;
case 2:
iStunde = (int) fStunde;
if (iStunde < 0)
Minuten = -Minuten;
default:
#if defined (SNI) || defined (M_UNIX) || defined(linux)
iStunde = 0;
#else
iStunde = 5;
#endif
Minuten = 0;
}
timezone = (iStunde * 60L + Minuten) * 60;

#if defined (SNI) || defined (M_UNIX)
altzone = timezone - 3600;
#endif
}

struct tm *localtime_x(time_t *lZeit)
{
time_t l;
struct tm *zeit;
char *TZ,
*p;
float fStunde1,
fStunde2;
int Args,
iStunde1,
iStunde2,
Minute1,
Minute2,
Monat,
Tag1,
Monat1,
Woche1,
WTag1,
Tag2,
Monat2,
Woche2,
WTag2;
unsigned long DSTshift;

l = *lZeit - timezone;
zeit = gmtime_x(&l);
TZ = getenv("TZ");
p = NULL;
Args = 0;
if (TZ)
/* z.B. VAR-3:30VAS,M3.5.0/1:30,M10.5.0/2:30 */
p = strstr(TZ, ",M");
if (p)
Args = sscanf(p + 2, "%d.%d.%d/%f:%d",
&Monat1,
&Woche1,
&WTag1,
&fStunde1,
&Minute1);
switch (Args)
{
case 3:
Minute1 = 0;
iStunde1 = 2;
break;
case 4:
Minute1 = ((int) (fStunde1 * 60)) % 60;
iStunde1 = (int) fStunde1;
break;
case 5 :
iStunde1 = (int) fStunde1;
break;
default:
Args = 0;
}
if (Args)
{
p = strstr(p + 2, ",M");
if (! p)
Args = 0;
}
if (Args)
Args = sscanf(p + 2, "%d.%d.%d/%f:%d",
&Monat2,
&Woche2,
&WTag2,
&fStunde2,
&Minute2);
switch (Args)
{
case 3:
Minute2 = 0;
iStunde2 = 2;
break;
case 4:
Minute2 = ((int) (fStunde2 * 60)) % 60;
iStunde2 = (int) fStunde2;
break;
case 5:
iStunde2 = (int) fStunde2;
break;
default:
Args = 0;
}
if (Args)
{
#if defined (SNI) || defined (M_UNIX)
DSTshift = (timezone - altzone) / 60;
#else
DSTshift = 60;
#endif

Minute2 -= DSTshift;
Monat1 --;
Monat2 --;
Tag1 = zeit->tm_mday;
Monat = zeit->tm_mon;
while (Monat < Monat1)
{
Tag1 += 7;
if (Tag1 > Monat_Len[Monat])
{
Tag1 -= Monat_Len[Monat];
Monat ++;
}
}
while (Monat > Monat1)
{
Tag1 -= 7;
if (Tag1 < 1)
{
Monat --;
Tag1 += Monat_Len[Monat];
}
}
Tag1 = (Tag1 + WTag1 - zeit->tm_wday + 6) % 7 + 1 + (Woche1 - 1) * 7;
while (Tag1 > Monat_Len[Monat1])
Tag1 -= 7;
Tag2 = zeit->tm_mday;
Monat = zeit->tm_mon;
Minute2 += iStunde2 * 60;
if (Minute2 < 0)
{
Minute2 += 24 * 60;
Tag2 --;
if (Tag2 < 1)
{
Monat --;
Tag2 += Monat_Len[Monat];
}
}
iStunde2 = Minute2 / 60;
Minute2 %= 60;
while (Monat < Monat2)
{
Tag2 += 7;
if (Tag2 > Monat_Len[Monat])
{
Tag2 -= Monat_Len[Monat];
Monat ++;
}
}
while (Monat > Monat2)
{
Tag2 -= 7;
if (Tag2 < 1)
{
Monat --;
Tag2 += Monat_Len[Monat];
}
}
Tag2 = (Tag2 + WTag2 - zeit->tm_wday + 6) % 7 + 1 + (Woche2 - 1) * 7;
while (Tag2 > Monat_Len[Monat2])
Tag2 -= 7;
if (Monat1 < zeit->tm_mon && zeit->tm_mon < Monat2)
zeit->tm_isdst = 1;
else
if (zeit->tm_mon == Monat1)
{
if (zeit->tm_mday > Tag1)
zeit->tm_isdst = 1;
else
if (zeit->tm_mday == Tag1)
if (zeit->tm_hour > iStunde1)
zeit->tm_isdst = 1;
else
if (zeit->tm_hour == iStunde1)
if (zeit->tm_min >= Minute1)
zeit->tm_isdst = 1;
}
else
if (zeit->tm_mon == Monat2)
if (zeit->tm_mday < Tag2)
zeit->tm_isdst = 1;
else
if (zeit->tm_mday == Tag2)
if (zeit->tm_hour < iStunde2)
zeit->tm_isdst = 1;
else
if (zeit->tm_hour == iStunde2)
if (zeit->tm_min < Minute2)
zeit->tm_isdst = 1;
}
if (zeit->tm_isdst)
{
#if defined (SNI) || defined (M_UNIX)
DSTshift = timezone - altzone;
#else
DSTshift = 3600;
#endif
zeit->tm_sec += DSTshift;
zeit->tm_min += zeit->tm_sec / 60;
zeit->tm_sec = zeit->tm_sec % 60;
zeit->tm_hour += zeit->tm_min / 60;
zeit->tm_min = zeit->tm_min % 60;
if (zeit->tm_hour == 24)
{
zeit->tm_hour = 0;
zeit->tm_wday = (zeit->tm_wday + 1) % 7;
zeit->tm_yday ++;
zeit->tm_mday ++;
if (zeit->tm_mday > Monat_Len[zeit->tm_mon])
{
zeit->tm_mday = 1;
zeit->tm_mon ++;
}
}
}
return zeit;
}

time_t mktime_x(struct tm *zeit)
/* GMT 01.01.1970 00:00:00 bis 07.02.2106 06:28:15 */
{
unsigned long Schaltjahre,
Tage,
Sekunden,
DSTshift;
int i;

if (zeit->tm_mon < 0)
i = - ((11 - zeit->tm_mon) / 12);
else
i = zeit->tm_mon / 12;
zeit->tm_year += i;
zeit->tm_mon -= i * 12;
CheckSchaltjahr(zeit->tm_year + 1900);
Schaltjahre = (zeit->tm_year - 69) / 4;
if (zeit->tm_year > 200)
Schaltjahre --;
Tage = (zeit->tm_year - 70) * 365L + Schaltjahre;
for (i = 0; i < zeit->tm_mon; i ++)
Tage += Monat_Len[i];
Sekunden = (((Tage + zeit->tm_mday - 1) * 24
+ zeit->tm_hour) * 60
+ zeit->tm_min) * 60
+ zeit->tm_sec
+ timezone;

if (zeit->tm_isdst == -1)
memcpy(zeit, localtime_x((time_t *) &Sekunden), sizeof(*zeit));

if (zeit->tm_isdst)
{
#if defined (SNI) || defined (M_UNIX)
DSTshift = timezone - altzone;
#else
DSTshift = 3600;
#endif
Sekunden -= DSTshift;
}

memcpy(zeit, localtime_x((time_t *) &Sekunden), sizeof(*zeit));
return Sekunden;
}


.