unicode
This commit is contained in:
parent
204f81876a
commit
14330244df
28
library/dialect/swi/os/libtai/BLURB
Normal file
28
library/dialect/swi/os/libtai/BLURB
Normal file
@ -0,0 +1,28 @@
|
||||
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.
|
3
library/dialect/swi/os/libtai/CHANGES
Normal file
3
library/dialect/swi/os/libtai/CHANGES
Normal file
@ -0,0 +1,3 @@
|
||||
19981013 libtai 0.60, alpha.
|
||||
19970908 libtai 0.56, alpha.
|
||||
19970730 libtai 0.50, alpha.
|
55
library/dialect/swi/os/libtai/CMakeLists.txt
Normal file
55
library/dialect/swi/os/libtai/CMakeLists.txt
Normal file
@ -0,0 +1,55 @@
|
||||
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
|
||||
)
|
||||
|
||||
|
||||
|
72
library/dialect/swi/os/libtai/FILES
Normal file
72
library/dialect/swi/os/libtai/FILES
Normal file
@ -0,0 +1,72 @@
|
||||
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
|
65
library/dialect/swi/os/libtai/INSTALL
Normal file
65
library/dialect/swi/os/libtai/INSTALL
Normal file
@ -0,0 +1,65 @@
|
||||
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.
|
93
library/dialect/swi/os/libtai/Makefile.in
Normal file
93
library/dialect/swi/os/libtai/Makefile.in
Normal file
@ -0,0 +1,93 @@
|
||||
################################################################
|
||||
# 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
|
||||
|
54
library/dialect/swi/os/libtai/caldate.3
Normal file
54
library/dialect/swi/os/libtai/caldate.3
Normal file
@ -0,0 +1,54 @@
|
||||
.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)
|
19
library/dialect/swi/os/libtai/caldate.h
Normal file
19
library/dialect/swi/os/libtai/caldate.h
Normal file
@ -0,0 +1,19 @@
|
||||
#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
|
45
library/dialect/swi/os/libtai/caldate_fmjd.c
Normal file
45
library/dialect/swi/os/libtai/caldate_fmjd.c
Normal file
@ -0,0 +1,45 @@
|
||||
#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;
|
||||
}
|
24
library/dialect/swi/os/libtai/caldate_fmt.c
Normal file
24
library/dialect/swi/os/libtai/caldate_fmt.c
Normal file
@ -0,0 +1,24 @@
|
||||
#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;
|
||||
}
|
111
library/dialect/swi/os/libtai/caldate_mjd.3
Normal file
111
library/dialect/swi/os/libtai/caldate_mjd.3
Normal file
@ -0,0 +1,111 @@
|
||||
.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)
|
44
library/dialect/swi/os/libtai/caldate_mjd.c
Normal file
44
library/dialect/swi/os/libtai/caldate_mjd.c
Normal file
@ -0,0 +1,44 @@
|
||||
#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;
|
||||
}
|
7
library/dialect/swi/os/libtai/caldate_norm.c
Normal file
7
library/dialect/swi/os/libtai/caldate_norm.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "tai.h"
|
||||
#include "caldate.h"
|
||||
|
||||
void caldate_normalize(struct caldate *cd)
|
||||
{
|
||||
caldate_frommjd(cd,caldate_mjd(cd),(int *) 0,(int *) 0);
|
||||
}
|
24
library/dialect/swi/os/libtai/caldate_scan.c
Normal file
24
library/dialect/swi/os/libtai/caldate_scan.c
Normal file
@ -0,0 +1,24 @@
|
||||
#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);
|
||||
}
|
24
library/dialect/swi/os/libtai/caldate_ster.c
Normal file
24
library/dialect/swi/os/libtai/caldate_ster.c
Normal file
@ -0,0 +1,24 @@
|
||||
#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; }
|
||||
}
|
82
library/dialect/swi/os/libtai/caltime.3
Normal file
82
library/dialect/swi/os/libtai/caltime.3
Normal file
@ -0,0 +1,82 @@
|
||||
.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)
|
20
library/dialect/swi/os/libtai/caltime.h
Normal file
20
library/dialect/swi/os/libtai/caltime.h
Normal file
@ -0,0 +1,20 @@
|
||||
#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
|
44
library/dialect/swi/os/libtai/caltime_fmt.c
Normal file
44
library/dialect/swi/os/libtai/caltime_fmt.c
Normal file
@ -0,0 +1,44 @@
|
||||
#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;
|
||||
}
|
39
library/dialect/swi/os/libtai/caltime_scan.c
Normal file
39
library/dialect/swi/os/libtai/caltime_scan.c
Normal file
@ -0,0 +1,39 @@
|
||||
#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);
|
||||
}
|
61
library/dialect/swi/os/libtai/caltime_tai.3
Normal file
61
library/dialect/swi/os/libtai/caltime_tai.3
Normal file
@ -0,0 +1,61 @@
|
||||
.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)
|
23
library/dialect/swi/os/libtai/caltime_tai.c
Normal file
23
library/dialect/swi/os/libtai/caltime_tai.c
Normal file
@ -0,0 +1,23 @@
|
||||
#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);
|
||||
}
|
31
library/dialect/swi/os/libtai/caltime_utc.c
Normal file
31
library/dialect/swi/os/libtai/caltime_utc.c
Normal file
@ -0,0 +1,31 @@
|
||||
#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;
|
||||
}
|
52
library/dialect/swi/os/libtai/check.c
Normal file
52
library/dialect/swi/os/libtai/check.c
Normal file
@ -0,0 +1,52 @@
|
||||
#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);
|
||||
}
|
44
library/dialect/swi/os/libtai/check.in
Normal file
44
library/dialect/swi/os/libtai/check.in
Normal file
@ -0,0 +1,44 @@
|
||||
-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
|
44
library/dialect/swi/os/libtai/check.out
Normal file
44
library/dialect/swi/os/libtai/check.out
Normal file
@ -0,0 +1,44 @@
|
||||
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
|
29
library/dialect/swi/os/libtai/easter.c
Normal file
29
library/dialect/swi/os/libtai/easter.c
Normal file
@ -0,0 +1,29 @@
|
||||
#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);
|
||||
}
|
106
library/dialect/swi/os/libtai/leapsecs.3
Normal file
106
library/dialect/swi/os/libtai/leapsecs.3
Normal file
@ -0,0 +1,106 @@
|
||||
.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)
|
30
library/dialect/swi/os/libtai/leapsecs.c
Normal file
30
library/dialect/swi/os/libtai/leapsecs.c
Normal file
@ -0,0 +1,30 @@
|
||||
#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);
|
||||
}
|
BIN
library/dialect/swi/os/libtai/leapsecs.dat
Normal file
BIN
library/dialect/swi/os/libtai/leapsecs.dat
Normal file
Binary file not shown.
16
library/dialect/swi/os/libtai/leapsecs.h
Normal file
16
library/dialect/swi/os/libtai/leapsecs.h
Normal file
@ -0,0 +1,16 @@
|
||||
#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
|
38
library/dialect/swi/os/libtai/leapsecs.txt
Normal file
38
library/dialect/swi/os/libtai/leapsecs.txt
Normal file
@ -0,0 +1,38 @@
|
||||
# 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
|
21
library/dialect/swi/os/libtai/leapsecs_add.c
Normal file
21
library/dialect/swi/os/libtai/leapsecs_add.c
Normal file
@ -0,0 +1,21 @@
|
||||
#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;
|
||||
}
|
12
library/dialect/swi/os/libtai/leapsecs_init.c
Normal file
12
library/dialect/swi/os/libtai/leapsecs_init.c
Normal file
@ -0,0 +1,12 @@
|
||||
#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;
|
||||
}
|
62
library/dialect/swi/os/libtai/leapsecs_read.c
Normal file
62
library/dialect/swi/os/libtai/leapsecs_read.c
Normal file
@ -0,0 +1,62 @@
|
||||
#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;
|
||||
}
|
25
library/dialect/swi/os/libtai/leapsecs_sub.c
Normal file
25
library/dialect/swi/os/libtai/leapsecs_sub.c
Normal file
@ -0,0 +1,25 @@
|
||||
#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;
|
||||
}
|
18
library/dialect/swi/os/libtai/taia_add.c
Normal file
18
library/dialect/swi/os/libtai/taia_add.c
Normal file
@ -0,0 +1,18 @@
|
||||
#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;
|
||||
}
|
||||
}
|
5
library/dialect/swi/os/libtai/taia_approx.c
Normal file
5
library/dialect/swi/os/libtai/taia_approx.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "taia.h"
|
||||
|
||||
double taia_approx(struct taia *t)
|
||||
{ return tai_approx(&t->sec) + taia_frac(t);
|
||||
}
|
31
library/dialect/swi/os/libtai/taia_fmtfrac.c
Normal file
31
library/dialect/swi/os/libtai/taia_fmtfrac.c
Normal file
@ -0,0 +1,31 @@
|
||||
#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;
|
||||
}
|
Reference in New Issue
Block a user