#include "../machine.h"
#include <time.h>
#include <locale.h>
#include <stdio.h>
#if WIN32
#include <sys/types.h>
#include <sys/timeb.h>
#else
#include <sys/time.h>
#endif
#if WIN32
extern void sciprint __PARAMS((char *fmt,...));
#endif
static int week_number __PARAMS ((struct tm *tp));
void C2F(scigetdate) __PARAMS ((time_t *dt, int *ierr));
void C2F(convertdate) __PARAMS ((time_t *dt, int w[]));
#if WIN32
#if _MSC_VER <=1200
static struct _timeb timebufferW;
#else
static struct __timeb64 timebufferW;
#endif
#else
static struct timeval timebufferU;
#endif
static int ChronoFlag=0;
void C2F(scigetdate)(dt,ierr)
time_t *dt;
int *ierr;
{
*ierr=0;
if (time(dt) == (time_t) - 1)
{
*ierr=1;
}
ChronoFlag=1;
#if WIN32
#if _MSC_VER <=1200
_ftime( &timebufferW );
#else
_ftime64( &timebufferW );
#endif
#else
gettimeofday(&timebufferU,NULL);
#endif
}
void C2F(convertdate)(dt,w)
int w[];
time_t *dt;
{
if (*dt<0)
{
w[0] = 0;
w[1] = 0;
w[2] = 0;
w[3] = 0;
w[4] = 0;
w[5] = 0;
w[6] = 0;
w[7] = 0;
w[8] = 0;
w[9] = 0;
sciprint("dt=getdate(x) x must be >0.\n");
}
else
{
struct tm *nowstruct=NULL;
nowstruct = localtime(dt);
if (nowstruct)
{
w[0] = 1900 + nowstruct->tm_year;
w[1] = 1 + nowstruct->tm_mon;
w[2] = week_number(nowstruct);
w[3] = 1 + nowstruct->tm_yday;
w[4] = 1 + nowstruct->tm_wday;
w[5] = nowstruct->tm_mday;
w[6] = nowstruct->tm_hour;
w[7] = nowstruct->tm_min;
w[8] = nowstruct->tm_sec;
if (ChronoFlag)
{
#if WIN32
w[9] = timebufferW.millitm;
#else
w[9] = timebufferU.tv_usec / 1000; /* micro to ms */
#endif
ChronoFlag=0;
}
else
{
w[9] = 0;
}
}
}
}
/* following code issued from glibc-2.1.2/time/strftime.c,
Tanks to Ton van Overbeek
*/
/* week_days computes
* The number of days from the first day of the first ISO week of this
* year to the year day YDAY with week day WDAY. ISO weeks start on
* Monday; the first ISO week has the year's first Thursday. YDAY may
* be as small as YDAY_MINIMUM. */
#define ISO_WEEK_START_WDAY 1 /* Monday */
#define ISO_WEEK1_WDAY 4 /* Thursday */
#define YDAY_MINIMUM (-366)
static int week_days __PARAMS ((int yday, int wday));
static int
week_days (yday, wday)
int yday;
int wday;
{
/* Add enough to the first operand of % to make it nonnegative. */
int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
return (yday
- (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) %
7
+ ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
}
/* week_number computes
* the ISO 8601 week number as a decimal number
* [01,53]. In the ISO 8601 week-based system, weeks
* begin on a Monday and week 1 of the year is the
* week that includes both January 4th and the first
* Thursday of the year. If the first Monday of
* January is the 2nd, 3rd, or 4th, the preceding
* days are part of the last week of the preceding
* year. */
#define TM_YEAR_BASE 1900
#ifndef __isleap
/* Nonzero if YEAR is a leap year (every 4 years,
except every 100th isn't, and every 400th is). */
# define __isleap(year) \
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
#endif
static int week_number(tp)
struct tm *tp;
{
int year = tp->tm_year + TM_YEAR_BASE;
int days = week_days (tp->tm_yday, tp->tm_wday);
if (days < 0)
{
/* This ISO week belongs to the previous year. */
year--;
days = week_days (tp->tm_yday + (365 + __isleap
(year)),
tp->tm_wday);
}
else
{
int d = week_days (tp->tm_yday - (365 + __isleap
(year)),
tp->tm_wday);
if (0 <= d)
{
/* This ISO week belongs to the next year. */
year++;
days = d;
}
}
return ( (int)days / 7 + 1);
}
syntax highlighted by Code2HTML, v. 0.9.1