not well supported in YAP

This commit is contained in:
Vítor Santos Costa 2015-06-18 01:02:06 +01:00
parent 9c1a3cc3b1
commit 204f81876a
65 changed files with 0 additions and 2278 deletions

View File

@ -1,28 +0,0 @@
libtai is a library for storing and manipulating dates and times.
libtai supports two time scales: (1) TAI64, covering a few hundred
billion years with 1-second precision; (2) TAI64NA, covering the same
period with 1-attosecond precision. Both scales are defined in terms of
TAI, the current international real time standard.
libtai provides an internal format for TAI64, struct tai, designed for
fast time manipulations. The tai_pack() and tai_unpack() routines
convert between struct tai and a portable 8-byte TAI64 storage format.
libtai provides similar internal and external formats for TAI64NA.
libtai provides struct caldate to store dates in year-month-day form. It
can convert struct caldate, under the Gregorian calendar, to a modified
Julian day number for easy date arithmetic.
libtai provides struct caltime to store calendar dates and times along
with UTC offsets. It can convert from struct tai to struct caltime in
UTC, accounting for leap seconds, for accurate date and time display. It
can also convert back from struct caltime to struct tai for user input.
Its overall UTC-to-TAI conversion speed is 100x better than the usual
UNIX mktime() implementation.
This version of libtai requires a UNIX system with gettimeofday(). It
will be easy to port to other operating systems with compilers
supporting 64-bit arithmetic.
The libtai source code is in the public domain.

View File

@ -1,3 +0,0 @@
19981013 libtai 0.60, alpha.
19970908 libtai 0.56, alpha.
19970730 libtai 0.50, alpha.

View File

@ -1,55 +0,0 @@
set(LIBYAPTAI_MAJOR_VERSION 0)
set(LIBYAPTAI_MINOR_VERSION 60)
set(LIBYAPTAI_PATCH_VERSION 0)
set(LIBYAPTAI_FULL_VERSION
${LIBYAPTAI_MAJOR_VERSION}.${LIBYAPTAI_MINOR_VERSION}.${LIBYAPTAI_PATCH_VERSION})
set(LIBYAPTAI_SOURCES
tai_add.c
tai_now.c
tai_pack.c
tai_sub.c
tai_unpack.c
taia_add.c
taia_approx.c
taia_fmtfrac.c
taia_frac.c
taia_half.c
taia_less.c
taia_now.c
taia_pack.c
taia_sub.c
taia_tai.c
taia_unpack.c
caldate_fmt.c
caldate_scan.c
caldate_fmjd.c
caldate_mjd.c
caldate_norm.c
caldate_ster.c
leapsecs_read.c
leapsecs_init.c
leapsecs_add.c
leapsecs_sub.c
caltime_fmt.c
caltime_scan.c
caltime_tai.c
caltime_utc.c
)
# ugh
set (POSITION_INDEPENDENT_CODE TRUE)
add_library (libyaptai OBJECT
${LIBYAPTAI_SOURCES})
set_target_properties(libyaptai
PROPERTIES
# RPATH ${libdir} VERSION ${LIBYAPTAI_FULL_VERSION}
# SOVERSION ${LIBYAPTAI_MAJOR_VERSION}.${LIBYAPTAI_MINOR_VERSION}
POSITION_INDEPENDENT_CODE TRUE
OUTPUT_NAME yaptai
)

View File

@ -1,72 +0,0 @@
BLURB
README
INSTALL
TODO
THANKS
CHANGES
FILES
VERSION
Makefile
leapsecs.txt
leapsecs.dat
leapsecs.c
check.in
check.out
check.c
easter.c
yearcal.c
nowutc.c
caldate.3
caldate_mjd.3
caldate.h
caldate_fmt.c
caldate_scan.c
caldate_mjd.c
caldate_fmjd.c
caldate_norm.c
caldate_ster.c
tai.3
tai_now.3
tai_pack.3
tai.h
tai_add.c
tai_now.c
tai_pack.c
tai_sub.c
tai_unpack.c
leapsecs.3
leapsecs.h
leapsecs_add.c
leapsecs_sub.c
leapsecs_init.c
leapsecs_read.c
caltime.3
caltime_tai.3
caltime.h
caltime_fmt.c
caltime_scan.c
caltime_tai.c
caltime_utc.c
taia.3
taia_now.3
taia_pack.3
taia.h
taia_add.c
taia_approx.c
taia_fmtfrac.c
taia_frac.c
taia_half.c
taia_less.c
taia_now.c
taia_pack.c
taia_sub.c
taia_tai.c
taia_unpack.c
conf-cc
conf-ld
find-systype.sh
make-compile.sh
make-load.sh
make-makelib.sh
trycpp.c
warn-auto.sh

View File

@ -1,65 +0,0 @@
Like any other piece of software (and information generally), libtai
comes with NO WARRANTY.
These are UNIX installation instructions; libtai has not yet been ported
to non-UNIX systems.
To compile the programs and format the man pages:
% make
Then, as root, enable leap second support:
# cp leapsecs.dat /etc/leapsecs.dat
# chmod 644 /etc/leapsecs.dat
To use another compiler, edit conf-cc and conf-ld.
There are five test programs here. The first is leapsecs, which creates
leapsecs.dat from leapsecs.txt. Try
% ./leapsecs < leapsecs.txt | cmp - leapsecs.dat
to make sure that there are no differences.
The second is check, which prints a variety of information about an
ISO-style input date. Try
% ./check < check.in | cmp - check.out
to make sure that your test results match mine. Note that the results
for future dates will change when more leap seconds are announced.
The third is easter, which prints the date of Easter in any given year.
Try
% ./easter 1997 1998 1999 2000 2001
and check the results against tables from some other source.
The fourth is yearcal, which prints a year-long calendar. Try
% ./yearcal 1997 | ul
and check the results against another calendar. (The days in January,
March, May, July, September, and November should show up in boldface.)
The fifth is nowutc, which prints the current time in UTC. Your system's
clock must be the number of seconds since 1970-01-01 00:00:10 TAI. This
is compatible with the interpretation of time_t in the Olson time
library with leap seconds enabled. Try
% env TZ=right/Etc/GMT date; ./nowutc
if your system has the Olson library.
The libtai code is in the public domain, so you can use it in your own
programs. But keep in mind that this is a very early release. Some of
the code hasn't been tested at all! caldate_mjd() and caldate_frommjd()
are based on previous code of mine; they need outside review. It would
be particularly helpful to systematically check my results against
independent results from someone else's code.

View File

@ -1,93 +0,0 @@
################################################################
# Makefile for the libtai
#
# Libtai by: D. J. Bernstein, djb@pobox.com
# This Makefile.in by: Jan Wielemaker, wielemak@science.uva.nl
#
# This makefile fits in the SWI-Prolog (www.swi-prolog.org)
# autconf setup.
################################################################
prefix=@prefix@
exec_prefix=@exec_prefix@
srcdir=@srcdir@
bindir=$(exec_prefix)/bin
PLBASE=@libdir@/@PL@-$(PLVERSION)
man_prefix=$(prefix)/man
mansec=1
lmansec=3
mandir=$(man_prefix)/man$(mansec)
lmandir=$(man_prefix)/man$(lmansec)
plmandir=$(PLBASE)/man
CC=@CC@
AR=@AR@
RANLIB=@RANLIB@
ifeq (@PROLOG_SYSTEM@,yap)
DEFS=@DEFS@ -D_YAP_NOT_INSTALLED_=1
CFLAGS= @SHLIB_CFLAGS@ $(YAP_EXTRAS) $(DEFS) -I$(srcdir) -I../../.. -I$(srcdir)/../../include @CPPFLAGS@ @JAVAINCPATH@
else
COFLAGS=@COFLAGS@
CWFLAGS=@CWFLAGS@
CIFLAGS=@CIFLAGS@
CMFLAGS=@CMFLAGS@
CPFLAGS=
LDFLAGS=@LDFLAGS@ $(CPFLAGS)
CFLAGS= $(CWFLAGS) $(COFLAGS) $(CIFLAGS) $(CMFLAGS) $(CPFLAGS)
endif #YAP/SWI
INSTALL=@INSTALL@
INSTALL_PROGRAM=@INSTALL_PROGRAM@
INSTALL_DATA=@INSTALL_DATA@
LIBOBJ= tai_add.o tai_now.o tai_pack.o \
tai_sub.o tai_unpack.o taia_add.o taia_approx.o \
taia_fmtfrac.o taia_frac.o taia_half.o taia_less.o \
taia_now.o taia_pack.o taia_sub.o taia_tai.o taia_unpack.o \
caldate_fmt.o caldate_scan.o caldate_fmjd.o caldate_mjd.o \
caldate_norm.o caldate_ster.o leapsecs_read.o \
leapsecs_init.o leapsecs_add.o leapsecs_sub.o caltime_fmt.o \
caltime_scan.o caltime_tai.o caltime_utc.o
PROG= easter check yearcal leapsecs nowutc
all: libtai.a
progs: $(PROG)
libtai.a: $(LIBOBJ)
rm -f $@
$(AR) cq $@ $(LIBOBJ)
$(RANLIB) $@
easter: easter.o libtai.a
$(CC) $(LDFLAGS) -o $@ easter.o -L. -ltai
check: check.o libtai.a
$(CC) $(LDFLAGS) -o $@ check.o -L. -ltai
yearcal: yearcal.o libtai.a
$(CC) $(LDFLAGS) -o $@ yearcal.o -L. -ltai
leapsecs: leapsecs.o libtai.a
$(CC) $(LDFLAGS) -o $@ leapsecs.o -L. -ltai
nowutc: nowutc.o libtai.a
$(CC) $(LDFLAGS) -o $@ nowutc.o -L. -ltai
%.o: $(srcdir)/%.c
$(CC) -c -I.. $(CFLAGS) $<
################################################################
# Cleanup
################################################################
clean:
rm -f *% *~ *.o *.gcda
profclean:
rm -f *.gcda
distclean: clean profclean
rm -f Makefile
rm -f $(PROG) libtai.a

View File

@ -1,37 +0,0 @@
################################################################
# Makefile for libtai
#
# Author: Jan Wielemaker
# E-mail: wielemak@science.uva.nl
################################################################
!include ..\rules.mk
LIBOBJ= tai_add.obj tai_now.obj tai_pack.obj tai_sub.obj \
tai_unpack.obj taia_add.obj taia_approx.obj \
taia_fmtfrac.obj taia_frac.obj taia_half.obj taia_less.obj \
taia_now.obj taia_pack.obj taia_sub.obj taia_tai.obj \
taia_unpack.obj caldate_fmt.obj caldate_scan.obj \
caldate_fmjd.obj caldate_mjd.obj caldate_norm.obj \
caldate_ster.obj leapsecs_read.obj \
leapsecs_init.obj leapsecs_add.obj leapsecs_sub.obj \
caltime_fmt.obj caltime_scan.obj caltime_tai.obj \
caltime_utc.obj
all: tai.lib
tai.lib: $(LIBOBJ)
if exist $@ del $@
$(AR) /out:$@ /nologo $(LIBOBJ)
################################################################
# Cleanup
################################################################
clean::
if exist *.obj del *.obj
if exist *~ del *~
distclean: clean
-del tai.lib *.pdb 2>nul

View File

@ -1,10 +0,0 @@
libtai 0.60, alpha.
19981013
Copyright 1998
D. J. Bernstein, djb@pobox.com
http://pobox.com/~djb/libtai.html
libtai is a library for storing and manipulating dates and times. See
BLURB for a more detailed advertisement.
INSTALL says how to set up and test libtai.

View File

@ -1,6 +0,0 @@
test caldate_mjd handling of weird days
test caldate_mjd handling of weird months
manually verify check.out
make 32-bit version?
test, test, test!
support time zones

View File

@ -1 +0,0 @@
libtai 0.60

View File

@ -1,54 +0,0 @@
.TH caldate 3
.SH NAME
caldate \- calendar dates
.SH SYNTAX
.B #include <caldate.h>
unsigned int \fBcaldate_fmt\fP(\fIs\fR,&\fIcd\fR);
.br
unsigned int \fBcaldate_scan\fP(\fIs\fR,&\fIcd\fR);
struct caldate \fIcd\fR;
.br
char *\fIs\fR;
.SH DESCRIPTION
A
.B struct caldate
value is a calendar date.
It has three components:
.BR year ,
.B month
(1...12),
and
.B day
(1...31).
.B caldate_fmt
prints
.I cd
in ISO style (yyyy-mm-dd)
into the character buffer
.IR s ,
without a terminating NUL.
It returns the number of characters printed.
.I s
may be zero;
then
.B caldate_fmt
returns the number of characters that would have been printed.
.B caldate_scan
reads a calendar date in ISO style
from the beginning of the character buffer
.I s
and puts it into
.IR cd .
It returns the number of characters read.
If
.I s
does not start with an ISO-style date,
.B caldate_scan
returns 0.
.SH "SEE ALSO"
caldate_mjd(3),
caltime(3)

View File

@ -1,19 +0,0 @@
#ifndef CALDATE_H
#define CALDATE_H
struct caldate {
long year;
int month;
int day;
} ;
extern unsigned int caldate_fmt(char *s, struct caldate *cd);
extern unsigned int caldate_scan(char *s, struct caldate *cd);
extern void caldate_frommjd(struct caldate *cd, int64_t day, int *pwday, int *pyday);
extern long caldate_mjd(struct caldate *cd);
extern void caldate_normalize(struct caldate *cd);
extern void caldate_easter(struct caldate *cd);
#endif

View File

@ -1,45 +0,0 @@
#include "tai.h"
#include "caldate.h"
void caldate_frommjd(struct caldate *cd, int64_t day, int *pwday, int *pyday)
{
long year;
long month;
int yday;
year = (long)(day / LL(146097));
day %= LL(146097);
day += LL(678881);
while (day >= LL(146097)) { day -= LL(146097); ++year; }
/* year * 146097 + day - 678881 is MJD; 0 <= day < 146097 */
/* 2000-03-01, MJD 51604, is year 5, day 0 */
if (pwday) *pwday = (int)((day + 3) % 7);
year *= 4;
if (day == LL(146096)) { year += 3; day = 36524L; }
else { year += (long)(day / LL(36524)); day %= LL(36524); }
year *= 25;
year += (long)(day / 1461);
day %= 1461;
year *= 4;
yday = (day < 306);
if (day == 1460) { year += 3; day = 365; }
else { year += (long)(day / 365); day %= 365; }
yday += (long)day;
day *= 10;
month = (long)((day + 5) / 306);
day = (day + 5) % 306;
day /= 10;
if (month >= 10) { yday -= 306; ++year; month -= 10; }
else { yday += 59; month += 2; }
cd->year = year;
cd->month = month + 1;
cd->day = (long)(day + 1);
if (pyday) *pyday = yday;
}

View File

@ -1,24 +0,0 @@
#include "tai.h"
#include "caldate.h"
unsigned int caldate_fmt(char *s, struct caldate *cd)
{
long x;
int i = 0;
x = cd->year; if (x < 0) x = -x; do { ++i; x /= 10; } while(x);
if (s) {
x = cd->year;
if (x < 0) { x = -x; *s++ = '-'; }
s += i; do { *--s = '0' + (char)(x % 10); x /= 10; } while(x); s += i;
x = cd->month;
s[0] = '-'; s[2] = '0' + (char)(x % 10); x /= 10; s[1] = '0' + (char)(x % 10);
x = cd->day;
s[3] = '-'; s[5] = '0' + (char)(x % 10); x /= 10; s[4] = '0' + (char)(x % 10);
}
return (cd->year < 0) + i + 6;
}

View File

@ -1,111 +0,0 @@
.TH caldate_mjd 3
.SH NAME
caldate_mjd \- manipulate calendar dates
.SH SYNTAX
.B #include <caldate.h>
void \fBcaldate_frommjd\fP(&\fIcd\fR,\fIday\fR,\fIweekday\fR,\fIyearday\fR);
.br
long \fBcaldate_mjd\fP(&\fIcd\fR);
.br
void \fBcaldate_normalize\fP(&\fIcd\fR);
void \fBcaldate_easter\fP(&\fIcd\fR);
struct caldate \fIcd\fR;
.br
long \fIday\fR;
.br
int *\fIweekday\fR;
.br
int *\fIyearday\fR;
.SH "BASIC CONVERSIONS"
Every calendar date has a
.I modified Julian day number\fR.
The day number increases by 1 every day.
Day number 0 is 17 November 1858.
Day number 51604 is 1 March 2000.
.B caldate_frommjd
puts into
.I cd
the date corresponding to the modified Julian day number
.IR day .
.B caldate_frommjd
also computes the day of the week (0 through 6)
and the day of the year (0 through 365).
It stores the day of the week in
.B *\fIweekday
if
.I weekday
is nonzero.
It stores the day of the year in
.B *\fIyearday
if
.I yearday
is nonzero.
.B caldate_mjd
returns the modified Julian day number corresponding to the date in
.IR cd .
.B caldate_mjd
accepts days outside the range 1 to 31,
referring to days before the beginning or after the end of the month.
It also accepts months outside the range 1 to 12,
referring to months before the beginning or after the end of the year.
.B caldate_normalize
calls
.B caldate_frommjd
with the result of
.BR caldate_mjd .
This means that it accepts out-of-range months and out-of-range days in
.IR cd ,
and puts a valid calendar date back into
.IR cd .
.SH "OTHER FUNCTIONS"
.B caldate_easter
reads the year from
.I cd
and then changes
.I cd
to the date of Easter in the same year.
.SH LIMITATIONS
The
.B caldate
routines currently support the Gregorian calendar,
which was defined in 1582 and adopted at different times
in different countries.
For earlier dates the
.B caldate
routines work with
``virtual Gregorian,''
defined mathematically by the 400-year Gregorian cycle
for years before 1582.
The Julian calendar is not supported.
The Gregorian calendar will be replaced by a new calendar
within a few thousand years.
The
.B caldate_frommjd
and
.B caldate_mjd
routines will be upgraded accordingly.
The current
.B caldate_frommjd
and
.B caldate_mjd
routines are not useful for dates far in the future.
Day numbers will overflow a 32-bit
.B long
sometime after the year 5000000;
all systems should upgrade to 64-bit
.BR long s
before then.
.B caldate_mjd
does not check for overflow.
.SH "SEE ALSO"
caldate(3)

View File

@ -1,44 +0,0 @@
#include "tai.h"
#include "caldate.h"
static unsigned long times365[4] = { 0, 365, 730, 1095 } ;
static unsigned long times36524[4] = { 0, 36524UL, 73048UL, 109572UL } ;
static unsigned long montab[12] =
{ 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337 } ;
/* month length after february is (306 * m + 5) / 10 */
long caldate_mjd(struct caldate *cd)
{
long y;
long m;
long d;
d = cd->day - 678882L;
m = cd->month - 1;
y = cd->year;
d += 146097L * (y / 400);
y %= 400;
if (m >= 2) m -= 2; else { m += 10; --y; }
y += (m / 12);
m %= 12;
if (m < 0) { m += 12; --y; }
d += montab[m];
d += 146097L * (y / 400);
y %= 400;
if (y < 0) { y += 400; d -= 146097L; }
d += times365[y & 3];
y >>= 2;
d += 1461L * (y % 25);
y /= 25;
d += times36524[y & 3];
return d;
}

View File

@ -1,7 +0,0 @@
#include "tai.h"
#include "caldate.h"
void caldate_normalize(struct caldate *cd)
{
caldate_frommjd(cd,caldate_mjd(cd),(int *) 0,(int *) 0);
}

View File

@ -1,24 +0,0 @@
#include "tai.h"
#include "caldate.h"
unsigned int caldate_scan(char *s, struct caldate *cd)
{
int sign = 1;
char *t = s;
unsigned long z;
unsigned long c;
if (*t == '-') { ++t; sign = -1; }
z = 0; while ((c = (unsigned char) (*t - '0')) <= 9) { z = z * 10 + c; ++t; }
cd->year = z * sign;
if (*t++ != '-') return 0;
z = 0; while ((c = (unsigned char) (*t - '0')) <= 9) { z = z * 10 + c; ++t; }
cd->month = z;
if (*t++ != '-') return 0;
z = 0; while ((c = (unsigned char) (*t - '0')) <= 9) { z = z * 10 + c; ++t; }
cd->day = z;
return (unsigned int)(t - s);
}

View File

@ -1,24 +0,0 @@
#include "tai.h"
#include "caldate.h"
void caldate_easter(struct caldate *cd)
{
long c;
long t;
long j;
long n;
long y;
y = cd->year;
c = (y / 100) + 1;
t = 210 - (((c * 3) / 4) % 210);
j = y % 19;
n = 57 - ((14 + j * 11 + (c * 8 + 5) / 25 + t) % 30);
if ((n == 56) && (j > 10)) --n;
if (n == 57) --n;
n -= ((((y % 28) * 5) / 4 + t + n + 2) % 7);
if (n < 32) { cd->month = 3; cd->day = n; }
else { cd->month = 4; cd->day = n - 31; }
}

View File

@ -1,82 +0,0 @@
.TH caltime 3
.SH NAME
caltime \- calendar dates and times
.SH SYNTAX
.B #include <caltime.h>
unsigned int \fBcaltime_fmt\fP(\fIs\fR,&\fIct\fR);
.br
unsigned int \fBcaltime_scan\fP(\fIs\fR,&\fIct\fR);
struct caltime \fIct\fR;
.br
char *\fIs\fR;
.SH DESCRIPTION
A
.B struct caltime
value is a calendar date and time with an offset in minutes from UTC.
It has five components:
.B date
(a
.B struct caldate\fR),
.B hour
(0...23),
.B minute
(0...59),
.B second
(0...60),
and
.B offset
(-5999...5999).
For example,
a leap second occurred
on 30 June 1997 at 23:59:60 UTC.
The local time in New York was
30 June 1997 19:59:60 -0400.
This local time is represented inside a
.B struct caltime
with
.B date
containing 1997, 6, 30;
.B hour
19;
.B minute
59;
.B second
60;
and
.B offset
\-240
(4 hours).
.SH FORMATTING
.B caltime_fmt
prints
.I ct
in ISO style (yyyy-mm-dd hh:mm:ss +oooo)
into the character buffer
.IR s ,
without a terminating NUL.
It returns the number of characters printed.
.I s
may be zero;
then
.B caltime_fmt
returns the number of characters that would have been printed.
.B caltime_scan
reads a calendar date, time, and offset in ISO style
from the beginning of the character buffer
.I s
and puts them into
.IR ct .
It returns the number of characters read.
If
.I s
does not start with an ISO-style date and time (including offset),
.B caltime_scan
returns 0.
.SH "SEE ALSO"
caltime_tai(3),
caldate(3),
tai(3)

View File

@ -1,20 +0,0 @@
#ifndef CALTIME_H
#define CALTIME_H
#include "caldate.h"
struct caltime {
struct caldate date;
int hour;
int minute;
int second;
long offset;
} ;
extern void caltime_tai(struct caltime *ct, struct tai *t);
extern void caltime_utc(struct caltime *ct, struct tai *t, int *pwday, int *pyday);
extern unsigned int caltime_fmt(char *s, struct caltime *ct);
extern unsigned int caltime_scan(char *s, struct caltime *ct);
#endif

View File

@ -1,44 +0,0 @@
#include "tai.h"
#include "caldate.h"
#include "caltime.h"
unsigned int caltime_fmt(char *s, struct caltime *ct)
{
unsigned int result;
long x;
result = caldate_fmt(s,&ct->date);
if (s) {
s += result;
x = ct->hour;
s[0] = ' ';
s[2] = '0' + (char)(x % 10); x /= 10;
s[1] = '0' + (char)(x % 10);
s += 3;
x = ct->minute;
s[0] = ':';
s[2] = '0' + (char)(x % 10); x /= 10;
s[1] = '0' + (char)(x % 10);
s += 3;
x = ct->second;
s[0] = ':';
s[2] = '0' + (char)(x % 10); x /= 10;
s[1] = '0' + (char)(x % 10);
s += 3;
s[0] = ' ';
x = ct->offset;
if (x < 0) { s[1] = '-'; x = -x; } else s[1] = '+';
s[5] = '0' + (char)(x % 10); x /= 10;
s[4] = '0' + (char)(x % 6); x /= 6;
s[3] = '0' + (char)(x % 10); x /= 10;
s[2] = '0' + (char)(x % 10);
}
return result + 15;
}

View File

@ -1,39 +0,0 @@
#include "tai.h"
#include "caltime.h"
unsigned int caltime_scan(char *s, struct caltime *ct)
{
char *t = s;
unsigned long z;
unsigned long c;
int sign;
t += caldate_scan(t,&ct->date);
while ((*t == ' ') || (*t == '\t') || (*t == 'T')) ++t;
z = 0; while ((c = (unsigned char) (*t - '0')) <= 9) { z = z * 10 + c; ++t; }
ct->hour = z;
if (*t++ != ':') return 0;
z = 0; while ((c = (unsigned char) (*t - '0')) <= 9) { z = z * 10 + c; ++t; }
ct->minute = z;
if (*t != ':')
ct->second = 0;
else {
++t;
z = 0; while ((c = (unsigned char) (*t - '0')) <= 9) { z = z * 10 + c; ++t; }
ct->second = z;
}
while ((*t == ' ') || (*t == '\t')) ++t;
if (*t == '+') sign = 1; else if (*t == '-') sign = -1; else return 0;
++t;
c = (unsigned char) (*t++ - '0'); if (c > 9) return 0; z = c;
c = (unsigned char) (*t++ - '0'); if (c > 9) return 0; z = z * 10 + c;
c = (unsigned char) (*t++ - '0'); if (c > 9) return 0; z = z * 6 + c;
c = (unsigned char) (*t++ - '0'); if (c > 9) return 0; z = z * 10 + c;
ct->offset = z * sign;
return (unsigned int)(t - s);
}

View File

@ -1,61 +0,0 @@
.TH caltime 3
.SH NAME
caltime_tai \- convert calendar dates and times
.SH SYNTAX
.B #include <caltime.h>
.br
.B #include <tai.h>
void \fBcaltime_tai\fP(&\fIct\fR,&\fIt\fR);
.br
void \fBcaltime_utc\fP(&\fIct\fR,&\fIt\fR,&\fIweekday\fR,&\fIyearday\fR);
struct caltime \fIct\fR;
.br
struct tai \fIt\fR;
.br
int *\fIweekday\fR;
.br
int *\fIyearday\fR;
.SH DESCRIPTION
.B caltime_tai
reads a date, time, and UTC offset from
.IR ct .
It puts the corresponding TAI64 label into
.IR t .
.B caltime_utc
reads a TAI64 label from
.IR t .
It puts the corresponding date and time into
.IR ct ,
with UTC offset 0.
.B caltime_utc
fills in
.I weekday
and
.I yearday
the same way as
.BR caldate_frommjd .
.SH LIMITATIONS
The sequence of TAI64 labels has been determined
for the next few hundred billion years.
The same is not true, however, for
calendar dates and times.
New leap seconds are added every year or two,
as discussed in
.BR leapsecs (3);
and the Gregorian calendar will change in a few thousand years,
as discussed in
.BR caldate_mjd (3).
This means that
.B caltime_tai
and
.B caltime_utc
are not useful for dates far in the future.
.SH "SEE ALSO"
caldate_mjd(3),
caltime(3),
tai(3),
leapsecs(3)

View File

@ -1,23 +0,0 @@
#include "tai.h"
#include "leapsecs.h"
#include "caldate.h"
#include "caltime.h"
/* XXX: breaks tai encapsulation */
void caltime_tai(struct caltime *ct, struct tai *t)
{
long day;
long s;
/* XXX: check for overflow? */
day = caldate_mjd(&ct->date);
s = ct->hour * 60 + ct->minute;
s = (s - ct->offset) * 60 + ct->second;
t->x = day * ULL(86400) + ULL(4611686014920671114) + (int64_t) s;
leapsecs_add(t,ct->second == 60);
}

View File

@ -1,31 +0,0 @@
#include "tai.h"
#include "leapsecs.h"
#include "caldate.h"
#include "caltime.h"
/* XXX: breaks tai encapsulation */
void caltime_utc(struct caltime *ct, struct tai *t, int *pwday, int *pyday)
{
struct tai t2 = *t;
uint64_t u;
int leap;
long s;
/* XXX: check for overfow? */
leap = leapsecs_sub(&t2);
u = t2.x;
u += 58486;
s = (long)(u % ULL(86400));
ct->second = (s % 60) + leap; s /= 60;
ct->minute = s % 60; s /= 60;
ct->hour = s;
u /= ULL(86400);
caldate_frommjd(&ct->date, (int64_t)u - LL(53375995543064), pwday, pyday);
ct->offset = 0;
}

View File

@ -1,52 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "tai.h"
#include "leapsecs.h"
#include "caltime.h"
char line[100];
char *dayname[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } ;
char out[101];
char x[TAI_PACK];
int
main(int argc, char **argv)
{
struct tai t;
struct tai t2;
struct caltime ct;
struct caltime ct2;
int weekday;
int yearday;
int i;
double packerr;
if (leapsecs_init() == -1)
printf("unable to init leapsecs\n");
while (fgets(line,sizeof line,stdin))
if (!caltime_scan(line,&ct))
printf("unable to parse\n");
else {
caltime_tai(&ct,&t);
caltime_utc(&ct2,&t,&weekday,&yearday);
tai_pack(x,&t);
tai_unpack(x,&t2);
tai_sub(&t2,&t2,&t);
packerr = tai_approx(&t2);
for (i = 0;i < TAI_PACK;++i)
printf("%2.2lx",(unsigned long) (unsigned char) x[i]);
if (packerr)
printf(" packerr=%f",packerr);
printf(" %03d %s",yearday,dayname[weekday]);
if (caltime_fmt((char *) 0,&ct2) + 1 < sizeof out) {
out[caltime_fmt(out,&ct2)] = 0;
printf(" %s",out);
}
printf("\n");
}
exit(0);
}

View File

@ -1,44 +0,0 @@
-1000000-12-31 23:59:59 +0000
-999999-1-1 0:0:0 +0000
-1-12-31 23:59:59 +0000
0-1-1 0:0:0 +0000
1-1-1 1:1:1 +0000
1000-01-01 12:04:37 +0000
1799-12-31 23:59:59 +0000
1899-12-31 23:59:59 +0000
1900-01-01 00:00:00 +0000
1969-12-31 23:59:49 +0000
1969-12-31 23:59:50 +0000
1969-12-31 23:59:59 +0000
1970-01-01 00:00:00 +0000
1970-01-01 00:00:01 +0000
1972-06-30 23:59:58 +0000
1972-06-30 23:59:59 +0000
1972-06-30 23:59:60 +0000
1972-07-01 00:00:00 +0000
1972-07-01 00:00:01 +0000
1995-12-31 23:59:58 +0000
1995-12-31 23:59:59 +0000
1995-12-31 23:59:60 +0000
1996-01-01 00:00:00 +0000
1996-01-01 00:00:01 +0000
1996-01-01 00:00:02 +0000
1997-06-30 23:59:59 +0000
1997-06-30 23:59:60 +0000
1997-07-01 00:00:00 +0000
1997-07-30 08:57:43 +0000
1997-10-03 18:14:48 +0000
1999-09-09 09:09:09 +0000
1999-12-31 23:59:59 +0000
2000-01-01 00:00:00 +0000
2000-01-01 00:00:01 +0000
2000-02-28 23:59:59 +0000
2000-02-29 23:59:59 +0000
2000-03-01 00:00:00 +0000
2000-12-31 23:59:59 +0000
2100-01-01 17:42:15 +0000
2200-01-01 17:42:15 +0000
3000-01-01 17:42:15 +0000
10000-01-01 17:42:15 +0000
999999-12-31 23:59:59 +0000
1000000-1-1 0:0:0 +0000

View File

@ -1,44 +0,0 @@
3fffe33e1b840309 365 Sun -1000000-12-31 23:59:59 +0000
3fffe33e1b84030a 000 Mon -999999-01-01 00:00:00 +0000
3ffffff1868b8409 364 Fri -1-12-31 23:59:59 +0000
3ffffff1868b840a 000 Sat 0-01-01 00:00:00 +0000
3ffffff1886e1757 000 Mon 1-01-01 01:01:01 +0000
3ffffff8df7db65f 000 Wed 1000-01-01 12:04:37 +0000
3ffffffec03dbf89 364 Tue 1799-12-31 23:59:59 +0000
3fffffff7c558189 364 Sun 1899-12-31 23:59:59 +0000
3fffffff7c55818a 000 Mon 1900-01-01 00:00:00 +0000
3fffffffffffffff 364 Wed 1969-12-31 23:59:49 +0000
4000000000000000 364 Wed 1969-12-31 23:59:50 +0000
4000000000000009 364 Wed 1969-12-31 23:59:59 +0000
400000000000000a 000 Thu 1970-01-01 00:00:00 +0000
400000000000000b 000 Thu 1970-01-01 00:00:01 +0000
4000000004b25808 181 Fri 1972-06-30 23:59:58 +0000
4000000004b25809 181 Fri 1972-06-30 23:59:59 +0000
4000000004b2580a 181 Fri 1972-06-30 23:59:60 +0000
4000000004b2580b 182 Sat 1972-07-01 00:00:00 +0000
4000000004b2580c 182 Sat 1972-07-01 00:00:01 +0000
4000000030e7241b 364 Sun 1995-12-31 23:59:58 +0000
4000000030e7241c 364 Sun 1995-12-31 23:59:59 +0000
4000000030e7241d 364 Sun 1995-12-31 23:59:60 +0000
4000000030e7241e 000 Mon 1996-01-01 00:00:00 +0000
4000000030e7241f 000 Mon 1996-01-01 00:00:01 +0000
4000000030e72420 000 Mon 1996-01-01 00:00:02 +0000
4000000033b8489d 180 Mon 1997-06-30 23:59:59 +0000
4000000033b8489e 180 Mon 1997-06-30 23:59:60 +0000
4000000033b8489f 181 Tue 1997-07-01 00:00:00 +0000
4000000033df0226 210 Wed 1997-07-30 08:57:43 +0000
4000000034353637 275 Fri 1997-10-03 18:14:48 +0000
4000000037d77955 251 Thu 1999-09-09 09:09:09 +0000
40000000386d439f 364 Fri 1999-12-31 23:59:59 +0000
40000000386d43a0 000 Sat 2000-01-01 00:00:00 +0000
40000000386d43a1 000 Sat 2000-01-01 00:00:01 +0000
4000000038bb0c1f 058 Mon 2000-02-28 23:59:59 +0000
4000000038bc5d9f 059 Tue 2000-02-29 23:59:59 +0000
4000000038bc5da0 060 Wed 2000-03-01 00:00:00 +0000
400000003a4fc89f 365 Sun 2000-12-31 23:59:59 +0000
40000000f4875017 000 Fri 2100-01-01 17:42:15 +0000
40000001b09f1217 000 Wed 2200-01-01 17:42:15 +0000
40000007915fc517 000 Wed 3000-01-01 17:42:15 +0000
4000003afff53a97 000 Sat 10000-01-01 17:42:15 +0000
40001ca4f3758a1f 364 Fri 999999-12-31 23:59:59 +0000
40001ca4f3758a20 000 Sat 1000000-01-01 00:00:00 +0000

View File

@ -1,29 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "caldate.h"
char *dayname[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } ;
char out[101];
int
main(int argc, char **argv)
{
struct caldate cd;
long day;
int weekday;
int yearday;
while (*++argv) {
cd.year = atoi(*argv);
if (cd.year > 0) {
caldate_easter(&cd);
day = caldate_mjd(&cd);
caldate_frommjd(&cd,day,&weekday,&yearday);
if (caldate_fmt((char *) 0,&cd) + 1 >= sizeof out) exit(1);
out[caldate_fmt(out,&cd)] = 0;
printf("%s %s yearday %d mjd %ld\n", dayname[weekday], out, yearday, day);
}
}
exit(0);
}

View File

@ -1,106 +0,0 @@
.TH leapsecs 3
.SH NAME
leapsecs \- handle UTC leap seconds
.SH SYNTAX
.B #include <leapsecs.h>
int \fBleapsecs_sub\fP(&\fIt\fR);
.br
void \fBleapsecs_add\fP(&\fIt\fR,\fIhit\fR);
int \fBleapsecs_read\fP();
.br
int \fBleapsecs_init\fP();
struct tai \fIt\fR;
.br
int \fIhit\fR;
.SH DESCRIPTION
.B leapsecs_sub
changes a seconds-since-epoch count
into a non-leap-seconds-since-epoch count.
It interprets
.I t
as a TAI64 label,
subtracts from
.I t
the number of leap seconds that have occurred
before or at
.IR t ,
and places the result back into
.IR t .
.B leapsecs_sub
returns 1 if
.I t
was a leap second,
0 otherwise.
.B leapsecs_add
reverses the effect of
.BR leapsecs_sub .
.I hit
must be 1
for a leap second,
0 otherwise.
.SH "LEAP-SECOND TABLE"
The current implementation of
.B leapsecs_sub
and
.B leapsecs_add
uses a leap-second table read from disk.
.B leapsecs_read
reads the leap-second table from
.BR /etc/leapsecs.dat .
It returns 0 on success, -1 on error.
If
.B /etc/leapsecs.dat
does not exist,
.B leapsecs_read
treats it as an empty file.
.B leapsecs_init
is a one-time version of
.BR leapsecs_read .
Initially it is the same as
.BR leapsecs_read ;
however, once
.B leapsecs_read
returns 0,
.B leapsecs_init
will always return 0
without calling
.B leapsecs_read
again.
.B leapsecs_add
and
.B leapsecs_sub
call
.BR leapsecs_init .
.B WARNING:
If
.B leapsecs_init
returns failure,
.B leapsecs_add
and
.B leapsecs_sub
will proceed without a leap-second table.
For reliability,
all programs should call
.B leapsecs_init
at startup and check for errors.
.B WARNING:
New entries are added to the leap-second table on disk
every 12 to 18 months.
.B leapsecs_read
may be called repeatedly.
It leaves the old table alone on error.
For reliability,
all long-running programs should call
.B leapsecs_read
at least once every month.
.SH "SEE ALSO"
tai(3)

View File

@ -1,30 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "tai.h"
#include "leapsecs.h"
#include "caldate.h"
/* XXX: breaks tai encapsulation */
/* XXX: output here has to be binary; DOS redirection uses ASCII */
char line[100];
int
main(int argc, char**argv)
{
struct caldate cd;
struct tai t;
char x[TAI_PACK];
long leaps = 0;
while (fgets(line,sizeof line,stdin))
if (line[0] == '+')
if (caldate_scan(line + 1,&cd)) {
t.x = (caldate_mjd(&cd) + 1) * 86400ULL + 4611686014920671114ULL + leaps++;
tai_pack(x,&t);
fwrite(x,TAI_PACK,1,stdout);
}
exit(0);
}

Binary file not shown.

View File

@ -1,16 +0,0 @@
#ifndef LEAPSECS_H
#define LEAPSECS_H
extern int leapsecs_init(void);
extern int leapsecs_read(const char *file);
extern void leapsecs_add(struct tai *t, int hit);
extern int leapsecs_sub(struct tai *t);
#ifndef GLOBAL
#define GLOBAL extern
#endif
GLOBAL struct tai *leapsecs;
GLOBAL int leapsecs_num;
#endif

View File

@ -1,38 +0,0 @@
# http://pobox.com/~djb/libtai/leapsecs.txt, version 1998-10-13
#
# Official sources:
# http://maia.usno.navy.mil/leapsec.html
# http://hpiers.obspm.fr/webiers/general/earthor/utc/UTC.html
#
# Dates must be listed in sorted order.
# + means a positive leap second, inserting 23:59:60 UTC.
# - means a negative leap second, skipping 23:59:59 UTC.
#
# Note for parsers: Negative leap seconds will probably never happen, but
# the year 10000 will happen. Please don't contribute to the Y10K problem.
#
# 1972-01-01 00:00:00 UTC was 1972-01-01 00:00:10 TAI.
#
+1972-06-30
+1972-12-31
+1973-12-31
+1974-12-31
+1975-12-31
+1976-12-31
+1977-12-31
+1978-12-31
+1979-12-31
+1981-06-30
+1982-06-30
+1983-06-30
+1985-06-30
+1987-12-31
+1989-12-31
+1990-12-31
+1992-06-30
+1993-06-30
+1994-06-30
+1995-12-31
+1997-06-30
+1998-12-31
+2005-12-31

View File

@ -1,21 +0,0 @@
#include "tai.h"
#include "leapsecs.h"
/* XXX: breaks tai encapsulation */
void leapsecs_add(struct tai *t, int hit)
{
int i;
uint64_t u;
if (leapsecs_init() == -1) return;
u = t->x;
for (i = 0;i < leapsecs_num;++i) {
if (u < leapsecs[i].x) break;
if (!hit || (u > leapsecs[i].x)) ++u;
}
t->x = u;
}

View File

@ -1,12 +0,0 @@
#include "tai.h"
#include "leapsecs.h"
static int flaginit = 0;
int leapsecs_init(void)
{
if (flaginit) return 0;
if (leapsecs_read("/etc/leapsecs.dat") == -1) return -1;
flaginit = 1;
return 0;
}

View File

@ -1,62 +0,0 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#ifdef __WINDOWS__
#include <io.h>
#else
#include <unistd.h>
#endif
#include "tai.h"
#define GLOBAL
#include "leapsecs.h"
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef O_NDELAY
#define O_NDELAY 0
#endif
int leapsecs_read(const char *file)
{ int fd;
struct stat st;
struct tai *t;
int n;
int i;
struct tai u;
fd = open(file, O_RDONLY|O_NDELAY|O_BINARY);
if (fd == -1) {
if (errno != ENOENT) return -1;
if (leapsecs) free(leapsecs);
leapsecs = 0;
leapsecs_num = 0;
return 0;
}
if (fstat(fd,&st) == -1) { close(fd); return -1; }
t = (struct tai *) malloc(st.st_size);
if (!t) { close(fd); return -1; }
n = read(fd,(char *) t,st.st_size);
close(fd);
if (n != st.st_size) { free(t); return -1; }
n /= sizeof(struct tai);
for (i = 0;i < n;++i) {
tai_unpack((char *) &t[i],&u);
t[i] = u;
}
if (leapsecs) free(leapsecs);
leapsecs = t;
leapsecs_num = n;
return 0;
}

View File

@ -1,25 +0,0 @@
#include "tai.h"
#include "leapsecs.h"
/* XXX: breaks tai encapsulation */
int leapsecs_sub(struct tai *t)
{
int i;
uint64_t u;
int s;
if (leapsecs_init() == -1) return 0;
u = t->x;
s = 0;
for (i = 0;i < leapsecs_num;++i) {
if (u < leapsecs[i].x) break;
++s;
if (u == leapsecs[i].x) { t->x = u - s; return 1; }
}
t->x = u - s;
return 0;
}

View File

@ -1,39 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "tai.h"
#include "leapsecs.h"
#include "taia.h"
#include "caltime.h"
struct taia now;
struct tai sec;
struct caltime ct;
char x[TAIA_FMTFRAC];
int
main(int argc, char **argv)
{
if (leapsecs_init() == -1) {
fprintf(stderr,"utcnow: fatal: unable to init leapsecs\n");
exit(111);
}
taia_now(&now);
x[taia_fmtfrac(x,&now)] = 0;
taia_tai(&now,&sec);
caltime_utc(&ct,&sec,(int *) 0,(int *) 0);
printf("%ld-%02d-%02d %02d:%02d:%02d.%s\n"
,ct.date.year
,ct.date.month
,ct.date.day
,ct.hour
,ct.minute
,ct.second
,x
);
exit(0);
}

View File

@ -1,83 +0,0 @@
.TH tai 3
.SH NAME
tai \- manipulate times with 1-second precision
.SH SYNTAX
.B #include <tai.h>
double \fBtai_approx\fP(&\fIt\fR);
int \fBtai_less\fP(&\fIa\fR,&\fIb\fR);
.br
void \fBtai_add\fP(&\fIt\fR,&\fIa\fR,&\fIb\fR);
.br
void \fBtai_sub\fP(&\fIt\fR,&\fIa\fR,&\fIb\fR);
struct tai \fIt\fR;
.br
struct tai \fIa\fR;
.br
struct tai \fIb\fR;
.SH DESCRIPTION
A
.B struct tai
stores an integer between 0 inclusive and 2^64 exclusive.
The format of
.B struct tai
is designed to speed up common operations;
applications should not look inside
.B struct tai\fR.
A
.B struct tai
variable is commonly used to store
a TAI64 label.
Each TAI64 label refers to one second of real time.
TAI64 labels span a period of
hundreds of billions of years.
See
.B http://pobox.com/~djb/proto/tai64.txt
for more information.
A
.B struct tai
variable may also be used to store
the numerical difference between two TAI64 labels.
.SH ARITHMETIC
.B tai_approx
returns a double-precision approximation to
.IR t .
The result of
.B tai_approx
is always nonnegative.
.B tai_less
returns 1 if
.I a
is smaller than
.IR b ,
0 otherwise.
.B tai_add
adds
.I a
and
.I b
modulo 2^64
and puts the result into
.IR t .
The inputs and outputs may overlap.
.B tai_sub
subtracts
.I b
from
.I a
modulo 2^64
and puts the result into
.IR t .
The inputs and outputs may overlap.
.SH "SEE ALSO"
tai_now(3),
tai_pack(3),
taia(3),
utc(3)

View File

@ -1,36 +0,0 @@
#ifndef TAI_H
#define TAI_H
#ifdef __WINDOWS__
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <inttypes.h> /* more portable than stdint.h */
#endif
#if defined(__WINDOWS__) && !defined(__GNUC__)
#define LL(x) x ## i64
#define ULL(x) x ## ui64
#else
#define LL(x) x ## LL
#define ULL(x) x ## ULL
#endif
struct tai {
uint64_t x;
} ;
extern void tai_now(struct tai *t);
/* JW: MSVC cannot convert unsigned to double :-( */
#define tai_approx(t) ((double) ((int64_t)(t)->x))
extern void tai_add(struct tai *t, struct tai *u, struct tai *v);
extern void tai_sub(struct tai *t, struct tai *u, struct tai *v);
#define tai_less(t,u) ((t)->x < (u)->x)
#define TAI_PACK 8
extern void tai_pack(char *s, struct tai *t);
extern void tai_unpack(char *s, struct tai *t);
#endif

View File

@ -1,6 +0,0 @@
#include "tai.h"
void tai_add(struct tai *t, struct tai *u, struct tai *v)
{
t->x = u->x + v->x;
}

View File

@ -1,34 +0,0 @@
.TH tai_now 3
.SH NAME
tai_now \- get current time, with 1-second precision
.SH SYNTAX
.B #include <tai.h>
void \fBtai_now\fP(&\fIt\fR);
struct tai \fIt\fR;
.SH DESCRIPTION
.B tai_now
puts the current time into
.IR t .
More precisely:
.B tai_now
puts into
.I t
its best guess as to the TAI64 label for the 1-second interval
that contains the current time.
.SH NOTES
This implementation of
.B tai_now
assumes that the
.B time_t
returned from the
.B time
function
represents the number of TAI seconds since
1970-01-01 00:00:10 TAI.
.SH "SEE ALSO"
tai(3),
taia_now(3),
time(3)

View File

@ -1,7 +0,0 @@
#include <time.h>
#include "tai.h"
void tai_now(struct tai *t)
{
t->x = ULL(4611686018427387914) + (uint64_t) time((time_t *) 0);
}

View File

@ -1,36 +0,0 @@
.TH tai_pack 3
.SH NAME
tai_pack \- convert TAI64 labels to external format
.SH SYNTAX
.B #include <tai.h>
void \fBtai_pack\fP(\fIbuf\fR,&\fIt\fR);
.br
void \fBtai_unpack\fP(\fIbuf\fR,&\fIt\fR);
char \fIbuf\fR[\fBTAI_PACK\fP];
.br
struct tai \fIt\fR;
.SH DESCRIPTION
.B tai_pack
converts a TAI64 label
from internal format in
.I t
to TAI64 format in
.IR buf .
.B tai_unpack
converts a TAI64 label
from TAI64 format in
.I buf
to internal format in
.IR t .
.B TAI_PACK
is 8.
See
.B http://pobox.com/~djb/proto/tai64.txt
for more information about TAI64 format.
.SH "SEE ALSO"
tai(3)

View File

@ -1,17 +0,0 @@
#include "tai.h"
void tai_pack(char *s, struct tai *t)
{
uint64_t x;
x = t->x;
/* JW: Cast to int need to get MSVC6 silent */
s[7] = (int)x & 255; x >>= 8;
s[6] = (int)x & 255; x >>= 8;
s[5] = (int)x & 255; x >>= 8;
s[4] = (int)x & 255; x >>= 8;
s[3] = (int)x & 255; x >>= 8;
s[2] = (int)x & 255; x >>= 8;
s[1] = (int)x & 255; x >>= 8;
s[0] = (int)x;
}

View File

@ -1,6 +0,0 @@
#include "tai.h"
void tai_sub(struct tai *t, struct tai *u, struct tai *v)
{
t->x = u->x - v->x;
}

View File

@ -1,16 +0,0 @@
#include "tai.h"
void tai_unpack(char *s, struct tai *t)
{
uint64_t x;
x = (unsigned char) s[0];
x <<= 8; x += (unsigned char) s[1];
x <<= 8; x += (unsigned char) s[2];
x <<= 8; x += (unsigned char) s[3];
x <<= 8; x += (unsigned char) s[4];
x <<= 8; x += (unsigned char) s[5];
x <<= 8; x += (unsigned char) s[6];
x <<= 8; x += (unsigned char) s[7];
t->x = x;
}

View File

@ -1,140 +0,0 @@
.TH taia 3
.SH NAME
taia \- manipulate times with 1-attosecond precision
.SH SYNTAX
.B #include <taia.h>
double \fBtaia_approx\fP(&\fIt\fR);
.br
double \fBtaia_frac\fP(&\fIt\fR);
.br
void \fBtaia_tai\fP(&\fIt\fR,&\fIsec\fR);
int \fBtaia_less\fP(&\fIa\fR,&\fIb\fR);
.br
void \fBtaia_add\fP(&\fIt\fR,&\fIa\fR,&\fIb\fR);
.br
void \fBtaia_sub\fP(&\fIt\fR,&\fIa\fR,&\fIb\fR);
.br
void \fBtaia_half\fP(&\fIt\fR,&\fIa\fR);
unsigned int \fBtaia_fmtfrac\fP(\fIs\fR,&\fIt\fR);
struct taia \fIt\fR;
.br
struct taia \fIa\fR;
.br
struct taia \fIb\fR;
.br
struct tai \fIsec\fR;
.br
char *\fIs\fR;
.SH DESCRIPTION
A
.B struct taia
stores an integer between 0 inclusive and 2^64x10^18 exclusive.
The format of
.B struct taia
is designed to speed up common operations;
applications should not look inside
.B struct taia\fR.
A
.B struct taia
variable is commonly used to store
a TAI64NA label.
Each TAI64NA label refers to one attosecond of real time;
see
.B http://pobox.com/~djb/proto/tai64.txt
for more information.
The integer in the
.B struct taia
is 10^18 times the second count,
plus 10^9 times the nanosecond count,
plus the attosecond count.
A
.B struct taia
variable may also be used to store
the numerical difference between two TAI64NA labels.
.SH ARITHMETIC
.B taia_approx
returns a double-precision approximation to
.IR t /10^18.
The result of
.B taia_approx
is always nonnegative.
.B taia_tai
places into
.I sec
the integer part of
.IR t /10^18.
.B taia_frac
returns a double-precision approximation to
the fraction part of
.IR t /10^18.
The result of
.B taia_frac
is always nonnegative.
.B taia_less
returns 1 if
.I a
is smaller than
.IR b ,
0 otherwise.
.B taia_add
adds
.I a
and
.I b
modulo 2^64x10^18
and puts the result into
.IR t .
The inputs and outputs may overlap.
.B taia_sub
subtracts
.I b
from
.I a
modulo 2^64x10^18
and puts the result into
.IR t .
The inputs and outputs may overlap.
.B taia_half
divides
.I a
by 2, rounding down,
and puts the result into
.IR t .
The input and output may overlap.
.SH "FORMATTING"
.B taia_fmtfrac
prints the remainder of
.IR t /10^18,
padded to exactly 18 digits,
into the character buffer
.IR s ,
without a terminating NUL.
It returns 18, the number of characters written.
.I s
may be zero;
then
.B taia_fmtfrac
returns 18 without printing anything.
The macro
.B TAIA_FMTFRAC
is defined as 19;
this is enough space for the output of
.B taia_fmtfrac
and a terminating NUL.
.SH "SEE ALSO"
taia_now(3),
taia_pack(3),
tai(3)

View File

@ -1,31 +0,0 @@
#ifndef TAIA_H
#define TAIA_H
#include "tai.h"
struct taia {
struct tai sec;
unsigned long nano; /* 0...999999999 */
unsigned long atto; /* 0...999999999 */
} ;
extern void taia_tai(struct taia *ta, struct tai *t);
extern void taia_now(struct taia *t);
extern double taia_approx(struct taia *t);
extern double taia_frac(struct taia *t);
extern void taia_add(struct taia *t, struct taia *u, struct taia *v);
extern void taia_sub(struct taia *t, struct taia *u, struct taia *v);
extern void taia_half(struct taia *t, struct taia *u);
extern int taia_less(struct taia *t, struct taia *u);
#define TAIA_PACK 16
extern void taia_pack(char *s, struct taia *t);
extern void taia_unpack(char *s, struct taia *t);
#define TAIA_FMTFRAC 19
extern unsigned int taia_fmtfrac(char *s, struct taia *t);
#endif

View File

@ -1,18 +0,0 @@
#include "taia.h"
/* XXX: breaks tai encapsulation */
void taia_add(struct taia *t, struct taia *u, struct taia *v)
{
t->sec.x = u->sec.x + v->sec.x;
t->nano = u->nano + v->nano;
t->atto = u->atto + v->atto;
if (t->atto > 999999999UL) {
t->atto -= 1000000000UL;
++t->nano;
}
if (t->nano > 999999999UL) {
t->nano -= 1000000000UL;
++t->sec.x;
}
}

View File

@ -1,5 +0,0 @@
#include "taia.h"
double taia_approx(struct taia *t)
{ return tai_approx(&t->sec) + taia_frac(t);
}

View File

@ -1,31 +0,0 @@
#include "taia.h"
unsigned int taia_fmtfrac(char *s, struct taia *t)
{
unsigned long x;
if (s) {
x = t->atto;
s[17] = '0' + (int)(x % 10); x /= 10;
s[16] = '0' + (int)(x % 10); x /= 10;
s[15] = '0' + (int)(x % 10); x /= 10;
s[14] = '0' + (int)(x % 10); x /= 10;
s[13] = '0' + (int)(x % 10); x /= 10;
s[12] = '0' + (int)(x % 10); x /= 10;
s[11] = '0' + (int)(x % 10); x /= 10;
s[10] = '0' + (int)(x % 10); x /= 10;
s[9] = '0' + (int)(x % 10);
x = t->nano;
s[8] = '0' + (int)(x % 10); x /= 10;
s[7] = '0' + (int)(x % 10); x /= 10;
s[6] = '0' + (int)(x % 10); x /= 10;
s[5] = '0' + (int)(x % 10); x /= 10;
s[4] = '0' + (int)(x % 10); x /= 10;
s[3] = '0' + (int)(x % 10); x /= 10;
s[2] = '0' + (int)(x % 10); x /= 10;
s[1] = '0' + (int)(x % 10); x /= 10;
s[0] = '0' + (int)(x % 10);
}
return 18;
}

View File

@ -1,6 +0,0 @@
#include "taia.h"
double taia_frac(struct taia *t)
{
return (t->atto * 0.000000001 + t->nano) * 0.000000001;
}

View File

@ -1,12 +0,0 @@
#include "taia.h"
/* XXX: breaks tai encapsulation */
void taia_half(struct taia *t, struct taia *u)
{
t->atto = u->atto >> 1;
if (u->nano & 1) t->atto += 500000000UL;
t->nano = u->nano >> 1;
if (u->sec.x & 1) t->nano += 500000000UL;
t->sec.x = u->sec.x >> 1;
}

View File

@ -1,12 +0,0 @@
#include "taia.h"
/* XXX: breaks tai encapsulation */
int taia_less(struct taia *t, struct taia *u)
{
if (t->sec.x < u->sec.x) return 1;
if (t->sec.x > u->sec.x) return 0;
if (t->nano < u->nano) return 1;
if (t->nano > u->nano) return 0;
return t->atto < u->atto;
}

View File

@ -1,33 +0,0 @@
.TH taia_now 3
.SH NAME
taia_now \- get current time, with 1-attosecond precision
.SH SYNTAX
.B #include <taia.h>
void \fBtaia_now\fP(&\fIt\fR);
struct taia \fIt\fR;
.SH DESCRIPTION
.B taia_now
puts the current time into
.IR t .
More precisely:
.B taia_now
puts into
.I t
its best guess as to the TAI64NA label for the 1-attosecond interval
that contains the current time.
.SH NOTES
This implementation of
.B tai_now
assumes that the
.B struct timeval
returned from
.B gettimeofday
represents the number of TAI seconds since
1970-01-01 00:00:10 TAI.
.SH "SEE ALSO"
gettimeofday(2),
tai_now(3),
taia(3)

View File

@ -1,40 +0,0 @@
#include <sys/types.h>
#ifdef __WINDOWS__
#define WINDOWS_LEAN_AND_MEAN 1
#include <windows.h>
#else
#include <sys/time.h>
#endif
#include "taia.h"
/* XXX: breaks tai encapsulation */
/*-------------------------------------------------------------------------
* The Microsoft Win32 API can return the current system time in "file
* timestamp" format, which is a 64-bit value representing the number of
* 100-nanosecond ticks since {AD1601-01-01 00:00:00 Z}.
* 11644473600 is seconds offset AD1601 to AD1970
*------------------------------------------------------------------------*/
void taia_now(struct taia *t)
{
#ifdef __WINDOWS__
FILETIME ft;
int64_t cns; /* 100ns ticks */
/* Get the current system time */
GetSystemTimeAsFileTime(&ft);
/* Convert to longtime_t form */
cns = ((int64_t)ft.dwHighDateTime << 32) + ft.dwLowDateTime;
t->sec.x = cns/10000000 - 11644473600 + ULL(4611686018427387914);
t->nano = (long)((cns % 10000000))*100;
t->atto = 0;
#else
struct timeval now;
gettimeofday(&now,(struct timezone *) 0);
t->sec.x = ULL(4611686018427387914) + (uint64_t) now.tv_sec;
t->nano = 1000 * now.tv_usec + 500;
t->atto = 0;
#endif
}

View File

@ -1,36 +0,0 @@
.TH taia_pack 3
.SH NAME
taia_pack \- convert TAI64NA labels to external format
.SH SYNTAX
.B #include <taia.h>
void \fBtaia_pack\fP(\fIbuf\fR,&\fIt\fR);
.br
void \fBtaia_unpack\fP(\fIbuf\fR,&\fIt\fR);
char \fIbuf\fR[\fBTAIA_PACK\fP];
.br
struct taia \fIt\fR;
.SH DESCRIPTION
.B taia_pack
converts a TAI64NA label
from internal format in
.I t
to TAI64NA format in
.IR buf .
.B taia_unpack
converts a TAI64NA label
from TAI64NA format in
.I buf
to internal format in
.IR t .
.B TAIA_PACK
is 16.
See
.B http://pobox.com/~djb/proto/tai64.txt
for more information about TAI64NA format.
.SH "SEE ALSO"
taia(3)

View File

@ -1,20 +0,0 @@
#include "taia.h"
void taia_pack(char *s, struct taia *t)
{
unsigned long x;
tai_pack(s,&t->sec);
s += 8;
x = t->atto;
s[7] = (int)x & 255; x >>= 8;
s[6] = (int)x & 255; x >>= 8;
s[5] = (int)x & 255; x >>= 8;
s[4] = (int)x;
x = t->nano;
s[3] = (int)x & 255; x >>= 8;
s[2] = (int)x & 255; x >>= 8;
s[1] = (int)x & 255; x >>= 8;
s[0] = (int)x;
}

View File

@ -1,21 +0,0 @@
#include "taia.h"
/* XXX: breaks tai encapsulation */
void taia_sub(struct taia *t, struct taia *u, struct taia *v)
{
unsigned long unano = u->nano;
unsigned long uatto = u->atto;
t->sec.x = u->sec.x - v->sec.x;
t->nano = unano - v->nano;
t->atto = uatto - v->atto;
if (t->atto > uatto) {
t->atto += 1000000000UL;
--t->nano;
}
if (t->nano > unano) {
t->nano += 1000000000UL;
--t->sec.x;
}
}

View File

@ -1,6 +0,0 @@
#include "taia.h"
void taia_tai(struct taia *ta, struct tai *t)
{
*t = ta->sec;
}

View File

@ -1,20 +0,0 @@
#include "taia.h"
void taia_unpack(char *s, struct taia *t)
{
unsigned long x;
tai_unpack(s,&t->sec);
s += 8;
x = (unsigned char) s[4];
x <<= 8; x += (unsigned char) s[5];
x <<= 8; x += (unsigned char) s[6];
x <<= 8; x += (unsigned char) s[7];
t->atto = x;
x = (unsigned char) s[0];
x <<= 8; x += (unsigned char) s[1];
x <<= 8; x += (unsigned char) s[2];
x <<= 8; x += (unsigned char) s[3];
t->nano = x;
}

View File

@ -1,66 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "caldate.h"
char *montab[] = {
"January"
, "February"
, "March"
, "April"
, "May"
, "June"
, "July"
, "August"
, "September"
, "October"
, "November"
, "December"
} ;
int main(int argc, char **argv)
{
int year;
long daystart;
long dayend;
long day;
int weekday;
struct caldate cd;
while (*++argv) {
year = atoi(*argv);
cd.year = year;
cd.month = 1;
cd.day = 1;
daystart = caldate_mjd(&cd);
cd.year = year + 1;
dayend = caldate_mjd(&cd);
while ((daystart + 3) % 7) --daystart;
while ((dayend + 3) % 7) ++dayend;
for (day = daystart;day < dayend;++day) {
caldate_frommjd(&cd,day,&weekday,(int *) 0);
if (cd.year != year)
printf(" ");
else {
if (cd.month & 1)
if (cd.day < 10)
printf(" %d%c%d ",cd.day % 10,8,cd.day % 10);
else
printf("%d%c%d%d%c%d ",cd.day / 10,8,cd.day / 10,cd.day % 10,8,cd.day % 10);
else
printf("%2d ",cd.day);
if (weekday == 6) {
if ((cd.day >= 15) && (cd.day < 22))
printf(" %s %d\n",montab[cd.month - 1],year);
else
printf("\n");
}
}
}
printf("\n");
}
exit(0);
}