from bsdmainutils 11.1.2ubuntu3
This commit is contained in:
commit
70e5f00193
|
@ -0,0 +1,12 @@
|
||||||
|
PROG = ncal
|
||||||
|
SRC = ncal.c calendar.c easter.c
|
||||||
|
FLAGS = -D_GNU_SOURCE -include bsd/string.h
|
||||||
|
|
||||||
|
LIBS += -ltinfo -lbsd
|
||||||
|
|
||||||
|
topdir=../..
|
||||||
|
include $(topdir)/config.mk
|
||||||
|
|
||||||
|
install-2:
|
||||||
|
(cd $(bindir); ln -sf ncal cal)
|
||||||
|
(cd $(mandir); ln -sf ncal.1 cal.1)
|
|
@ -0,0 +1,203 @@
|
||||||
|
.\" Copyright (c) 1997 Wolfgang Helbig
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD: head/lib/libcalendar/calendar.3 267773 2014-06-23 08:23:05Z bapt $
|
||||||
|
.\"
|
||||||
|
.Dd November 29, 1997
|
||||||
|
.Dt CALENDAR 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm easterg ,
|
||||||
|
.Nm easterog ,
|
||||||
|
.Nm easteroj ,
|
||||||
|
.Nm gdate ,
|
||||||
|
.Nm jdate ,
|
||||||
|
.Nm ndaysg ,
|
||||||
|
.Nm ndaysj ,
|
||||||
|
.Nm week ,
|
||||||
|
.Nm weekday
|
||||||
|
.Nd Calendar arithmetic for the Christian era
|
||||||
|
.Sh LIBRARY
|
||||||
|
.Lb libcalendar
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In calendar.h
|
||||||
|
.Ft struct date *
|
||||||
|
.Fn easterg "int year" "struct date *dt"
|
||||||
|
.Ft struct date *
|
||||||
|
.Fn easterog "int year" "struct date *dt"
|
||||||
|
.Ft struct date *
|
||||||
|
.Fn easteroj "int year" "struct date *dt"
|
||||||
|
.Ft struct date *
|
||||||
|
.Fn gdate "int nd" "struct date *dt"
|
||||||
|
.Ft struct date *
|
||||||
|
.Fn jdate "int nd" "struct date *dt"
|
||||||
|
.Ft int
|
||||||
|
.Fn ndaysg "struct date *dt"
|
||||||
|
.Ft int
|
||||||
|
.Fn ndaysj "struct date *dt"
|
||||||
|
.Ft int
|
||||||
|
.Fn week "int nd" "int *year"
|
||||||
|
.Ft int
|
||||||
|
.Fn weekday "int nd"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These functions provide calendar arithmetic for a large range of years,
|
||||||
|
starting at March 1st, year zero (i.e., 1 B.C.) and ending way beyond
|
||||||
|
year 100000.
|
||||||
|
.Pp
|
||||||
|
Programs should be linked with
|
||||||
|
.Fl lcalendar .
|
||||||
|
.Pp
|
||||||
|
The functions
|
||||||
|
.Fn easterg ,
|
||||||
|
.Fn easterog
|
||||||
|
and
|
||||||
|
.Fn easteroj
|
||||||
|
store the date of Easter Sunday into the structure pointed at by
|
||||||
|
.Fa dt
|
||||||
|
and return a pointer to this structure.
|
||||||
|
The function
|
||||||
|
.Fn easterg
|
||||||
|
assumes Gregorian Calendar (adopted by most western churches after 1582) and
|
||||||
|
the functions
|
||||||
|
.Fn easterog
|
||||||
|
and
|
||||||
|
.Fn easteroj
|
||||||
|
compute the date of Easter Sunday according to the orthodox rules
|
||||||
|
(Western churches before 1582, Greek and Russian Orthodox Church
|
||||||
|
until today).
|
||||||
|
The result returned by
|
||||||
|
.Fn easterog
|
||||||
|
is the date in Gregorian Calendar, whereas
|
||||||
|
.Fn easteroj
|
||||||
|
returns the date in Julian Calendar.
|
||||||
|
.Pp
|
||||||
|
The functions
|
||||||
|
.Fn gdate ,
|
||||||
|
.Fn jdate ,
|
||||||
|
.Fn ndaysg
|
||||||
|
and
|
||||||
|
.Fn ndaysj
|
||||||
|
provide conversions between the common "year, month, day" notation
|
||||||
|
of a date and the "number of days" representation, which is better suited
|
||||||
|
for calculations.
|
||||||
|
The days are numbered from March 1st year 1 B.C., starting
|
||||||
|
with zero, so the number of a day gives the number of days since March 1st,
|
||||||
|
year 1 B.C.
|
||||||
|
The conversions work for nonnegative day numbers only.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn gdate
|
||||||
|
and
|
||||||
|
.Fn jdate
|
||||||
|
functions
|
||||||
|
store the date corresponding to the day number
|
||||||
|
.Fa nd
|
||||||
|
into the structure pointed at by
|
||||||
|
.Fa dt
|
||||||
|
and return a pointer to this structure.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn ndaysg
|
||||||
|
and
|
||||||
|
.Fn ndaysj
|
||||||
|
functions
|
||||||
|
return the day number of the date pointed at by
|
||||||
|
.Fa dt .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn gdate
|
||||||
|
and
|
||||||
|
.Fn ndaysg
|
||||||
|
functions
|
||||||
|
assume Gregorian Calendar after October 4, 1582 and Julian Calendar before,
|
||||||
|
whereas
|
||||||
|
.Fn jdate
|
||||||
|
and
|
||||||
|
.Fn ndaysj
|
||||||
|
assume Julian Calendar throughout.
|
||||||
|
.Pp
|
||||||
|
The two calendars differ by the definition of the leap year.
|
||||||
|
The
|
||||||
|
Julian Calendar says every year that is a multiple of four is a
|
||||||
|
leap year.
|
||||||
|
The Gregorian Calendar excludes years that are multiples of
|
||||||
|
100 and not multiples of 400.
|
||||||
|
This means the years 1700, 1800, 1900, 2100 are not leap years
|
||||||
|
and the year 2000 is
|
||||||
|
a leap year.
|
||||||
|
The new rules were inaugurated on October 4, 1582 by deleting ten
|
||||||
|
days following this date.
|
||||||
|
Most catholic countries adopted the new
|
||||||
|
calendar by the end of the 16th century, whereas others stayed with
|
||||||
|
the Julian Calendar until the 20th century.
|
||||||
|
The United Kingdom and
|
||||||
|
their colonies switched on September 2, 1752.
|
||||||
|
They already had to
|
||||||
|
delete 11 days.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn week
|
||||||
|
returns the number of the week which contains the day numbered
|
||||||
|
.Fa nd .
|
||||||
|
The argument
|
||||||
|
.Fa *year
|
||||||
|
is set with the year that contains (the greater part of) the week.
|
||||||
|
The weeks are numbered per year starting with week 1, which is the
|
||||||
|
first week in a year that includes more than three days of the year.
|
||||||
|
Weeks start on Monday.
|
||||||
|
This function is defined for Gregorian Calendar only.
|
||||||
|
.Pp
|
||||||
|
The function
|
||||||
|
.Fn weekday
|
||||||
|
returns the weekday (Mo = 0 ..\& Su = 6) of the day numbered
|
||||||
|
.Fa nd .
|
||||||
|
.Pp
|
||||||
|
The structure
|
||||||
|
.Fa date
|
||||||
|
is defined in
|
||||||
|
.In calendar.h .
|
||||||
|
It contains these fields:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
int y; /\(** year (0000 - ????) \(**/
|
||||||
|
int m; /\(** month (1 - 12) \(**/
|
||||||
|
int d; /\(** day of month (1 - 31) \(**/
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The year zero is written as "1 B.C." by historians and "0" by astronomers
|
||||||
|
and in this library.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr ncal 1 ,
|
||||||
|
.Xr strftime 3
|
||||||
|
.Sh STANDARDS
|
||||||
|
The week number conforms to ISO 8601: 1988.
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm calendar
|
||||||
|
library first appeared in
|
||||||
|
.Fx 3.0 .
|
||||||
|
.Sh AUTHORS
|
||||||
|
This manual page and the library was written by
|
||||||
|
.An Wolfgang Helbig Aq Mt helbig@FreeBSD.org .
|
||||||
|
.Sh BUGS
|
||||||
|
The library was coded with great care so there are no bugs left.
|
|
@ -0,0 +1,335 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997 Wolfgang Helbig
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <langinfo.h>
|
||||||
|
__FBSDID("$FreeBSD: head/lib/libcalendar/calendar.c 326219 2017-11-26 02:00:33Z pfg $");
|
||||||
|
|
||||||
|
#include "calendar.h"
|
||||||
|
extern int weekstart;
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For each month tabulate the number of days elapsed in a year before the
|
||||||
|
* month. This assumes the internal date representation, where a year
|
||||||
|
* starts on March 1st. So we don't need a special table for leap years.
|
||||||
|
* But we do need a special table for the year 1582, since 10 days are
|
||||||
|
* deleted in October. This is month1s for the switch from Julian to
|
||||||
|
* Gregorian calendar.
|
||||||
|
*/
|
||||||
|
static int const month1[] =
|
||||||
|
{0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337};
|
||||||
|
/* M A M J J A S O N D J */
|
||||||
|
static int const month1s[]=
|
||||||
|
{0, 31, 61, 92, 122, 153, 184, 214, 235, 265, 296, 327};
|
||||||
|
|
||||||
|
typedef struct date date;
|
||||||
|
|
||||||
|
/* The last day of Julian calendar, in internal and ndays representation */
|
||||||
|
static int nswitch; /* The last day of Julian calendar */
|
||||||
|
static date jiswitch = {1582, 7, 3};
|
||||||
|
|
||||||
|
static date *date2idt(date *idt, date *dt);
|
||||||
|
static date *idt2date(date *dt, date *idt);
|
||||||
|
static int ndaysji(date *idt);
|
||||||
|
static int ndaysgi(date *idt);
|
||||||
|
static int firstweek(int year);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the Julian date from the number of days elapsed since
|
||||||
|
* March 1st of year zero.
|
||||||
|
*/
|
||||||
|
date *
|
||||||
|
jdate(int ndays, date *dt)
|
||||||
|
{
|
||||||
|
date idt; /* Internal date representation */
|
||||||
|
int r; /* hold the rest of days */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the year by starting with an approximation not smaller
|
||||||
|
* than the answer and using linear search for the greatest
|
||||||
|
* year which does not begin after ndays.
|
||||||
|
*/
|
||||||
|
idt.y = ndays / 365;
|
||||||
|
idt.m = 0;
|
||||||
|
idt.d = 0;
|
||||||
|
while ((r = ndaysji(&idt)) > ndays)
|
||||||
|
idt.y--;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set r to the days left in the year and compute the month by
|
||||||
|
* linear search as the largest month that does not begin after r
|
||||||
|
* days.
|
||||||
|
*/
|
||||||
|
r = ndays - r;
|
||||||
|
for (idt.m = 11; month1[idt.m] > r; idt.m--)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Compute the days left in the month */
|
||||||
|
idt.d = r - month1[idt.m];
|
||||||
|
|
||||||
|
/* return external representation of the date */
|
||||||
|
return (idt2date(dt, &idt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the number of days since March 1st of the year zero.
|
||||||
|
* The date is given according to Julian calendar.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ndaysj(date *dt)
|
||||||
|
{
|
||||||
|
date idt; /* Internal date representation */
|
||||||
|
|
||||||
|
if (date2idt(&idt, dt) == NULL)
|
||||||
|
return (-1);
|
||||||
|
else
|
||||||
|
return (ndaysji(&idt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same as above, where the Julian date is given in internal notation.
|
||||||
|
* This formula shows the beauty of this notation.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ndaysji(date * idt)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (idt->d + month1[idt->m] + idt->y * 365 + idt->y / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the date according to the Gregorian calendar from the number of
|
||||||
|
* days since March 1st, year zero. The date computed will be Julian if it
|
||||||
|
* is older than 1582-10-05. This is the reverse of the function ndaysg().
|
||||||
|
*/
|
||||||
|
date *
|
||||||
|
gdate(int ndays, date *dt)
|
||||||
|
{
|
||||||
|
int const *montht; /* month-table */
|
||||||
|
date idt; /* for internal date representation */
|
||||||
|
int r; /* holds the rest of days */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the year by starting with an approximation not smaller
|
||||||
|
* than the answer and search linearly for the greatest year not
|
||||||
|
* starting after ndays.
|
||||||
|
*/
|
||||||
|
idt.y = ndays / 365;
|
||||||
|
idt.m = 0;
|
||||||
|
idt.d = 0;
|
||||||
|
while ((r = ndaysgi(&idt)) > ndays)
|
||||||
|
idt.y--;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set ndays to the number of days left and compute by linear
|
||||||
|
* search the greatest month which does not start after ndays. We
|
||||||
|
* use the table month1 which provides for each month the number
|
||||||
|
* of days that elapsed in the year before that month. Here the
|
||||||
|
* year 1582 is special, as 10 days are left out in October to
|
||||||
|
* resynchronize the calendar with the earth's orbit. October 4th
|
||||||
|
* 1582 is followed by October 15th 1582. We use the "switch"
|
||||||
|
* table month1s for this year.
|
||||||
|
*/
|
||||||
|
ndays = ndays - r;
|
||||||
|
if (idt.y == 1582)
|
||||||
|
montht = month1s;
|
||||||
|
else
|
||||||
|
montht = month1;
|
||||||
|
|
||||||
|
for (idt.m = 11; montht[idt.m] > ndays; idt.m--)
|
||||||
|
;
|
||||||
|
|
||||||
|
idt.d = ndays - montht[idt.m]; /* the rest is the day in month */
|
||||||
|
|
||||||
|
/* Advance ten days deleted from October if after switch in Oct 1582 */
|
||||||
|
if (idt.y == jiswitch.y && idt.m == jiswitch.m && jiswitch.d < idt.d)
|
||||||
|
idt.d += 10;
|
||||||
|
|
||||||
|
/* return external representation of found date */
|
||||||
|
return (idt2date(dt, &idt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the number of days since March 1st of the year zero. The date is
|
||||||
|
* assumed Gregorian if younger than 1582-10-04 and Julian otherwise. This
|
||||||
|
* is the reverse of gdate.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ndaysg(date *dt)
|
||||||
|
{
|
||||||
|
date idt; /* Internal date representation */
|
||||||
|
|
||||||
|
if (date2idt(&idt, dt) == NULL)
|
||||||
|
return (-1);
|
||||||
|
return (ndaysgi(&idt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same as above, but with the Gregorian date given in internal
|
||||||
|
* representation.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ndaysgi(date *idt)
|
||||||
|
{
|
||||||
|
int nd; /* Number of days--return value */
|
||||||
|
|
||||||
|
/* Cache nswitch if not already done */
|
||||||
|
if (nswitch == 0)
|
||||||
|
nswitch = ndaysji(&jiswitch);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assume Julian calendar and adapt to Gregorian if necessary, i. e.
|
||||||
|
* younger than nswitch. Gregori deleted
|
||||||
|
* the ten days from Oct 5th to Oct 14th 1582.
|
||||||
|
* Thereafter years which are multiples of 100 and not multiples
|
||||||
|
* of 400 were not leap years anymore.
|
||||||
|
* This makes the average length of a year
|
||||||
|
* 365d +.25d - .01d + .0025d = 365.2425d. But the tropical
|
||||||
|
* year measures 365.2422d. So in 10000/3 years we are
|
||||||
|
* again one day ahead of the earth. Sigh :-)
|
||||||
|
* (d is the average length of a day and tropical year is the
|
||||||
|
* time from one spring point to the next.)
|
||||||
|
*/
|
||||||
|
if ((nd = ndaysji(idt)) == -1)
|
||||||
|
return (-1);
|
||||||
|
if (idt->y >= 1600)
|
||||||
|
nd = (nd - 10 - (idt->y - 1600) / 100 + (idt->y - 1600) / 400);
|
||||||
|
else if (nd > nswitch)
|
||||||
|
nd -= 10;
|
||||||
|
return (nd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the week number from the number of days since March 1st year 0.
|
||||||
|
* The weeks are numbered per year starting with 1. If the first
|
||||||
|
* week of a year includes at least four days of that year it is week 1,
|
||||||
|
* otherwise it gets the number of the last week of the previous year.
|
||||||
|
* The variable y will be filled with the year that contains the greater
|
||||||
|
* part of the week.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
week(int nd, int *y)
|
||||||
|
{
|
||||||
|
date dt;
|
||||||
|
int fw; /* 1st day of week 1 of previous, this and
|
||||||
|
* next year */
|
||||||
|
gdate(nd, &dt);
|
||||||
|
for (*y = dt.y + 1; nd < (fw = firstweek(*y)); (*y)--)
|
||||||
|
;
|
||||||
|
return ((nd - fw) / 7 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the first day of week 1 of year y */
|
||||||
|
static int
|
||||||
|
firstweek(int y)
|
||||||
|
{
|
||||||
|
date idt;
|
||||||
|
int nd, wd;
|
||||||
|
|
||||||
|
idt.y = y - 1; /* internal representation of y-1-1 */
|
||||||
|
idt.m = 10;
|
||||||
|
idt.d = 0;
|
||||||
|
|
||||||
|
nd = ndaysgi(&idt);
|
||||||
|
/*
|
||||||
|
* If more than 3 days of this week are in the preceding year, the
|
||||||
|
* next week is week 1 (and the next sunday/monday is the answer),
|
||||||
|
* otherwise this week is week 1 and the last sunday/monday is the
|
||||||
|
* answer.
|
||||||
|
*/
|
||||||
|
/* 3 may or may not be correct, better use what the locale says */
|
||||||
|
if ((wd = weekday(nd) + 1 - weekstart) >= *nl_langinfo(_NL_TIME_WEEK_1STWEEK))
|
||||||
|
return (nd - wd + 7);
|
||||||
|
else
|
||||||
|
return (nd - wd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the weekday (Mo = 0 .. Su = 6) */
|
||||||
|
int
|
||||||
|
weekday(int nd)
|
||||||
|
{
|
||||||
|
date dmondaygi = {1997, 8, 16}; /* Internal repr. of 1997-11-17 */
|
||||||
|
static int nmonday; /* ... which is a monday */
|
||||||
|
|
||||||
|
/* Cache the daynumber of one monday */
|
||||||
|
if (nmonday == 0)
|
||||||
|
nmonday = ndaysgi(&dmondaygi);
|
||||||
|
|
||||||
|
/* return (nd - nmonday) modulo 7 which is the weekday */
|
||||||
|
nd = (nd - nmonday) % 7;
|
||||||
|
if (nd < 0)
|
||||||
|
return (nd + 7);
|
||||||
|
else
|
||||||
|
return (nd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a date to internal date representation: The year starts on
|
||||||
|
* March 1st, month and day numbering start at zero. E. g. March 1st of
|
||||||
|
* year zero is written as y=0, m=0, d=0.
|
||||||
|
*/
|
||||||
|
static date *
|
||||||
|
date2idt(date *idt, date *dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
idt->d = dt->d - 1;
|
||||||
|
if (dt->m > 2) {
|
||||||
|
idt->m = dt->m - 3;
|
||||||
|
idt->y = dt->y;
|
||||||
|
} else {
|
||||||
|
idt->m = dt->m + 9;
|
||||||
|
idt->y = dt->y - 1;
|
||||||
|
}
|
||||||
|
if (idt->m < 0 || idt->m > 11 || idt->y < 0)
|
||||||
|
return (NULL);
|
||||||
|
else
|
||||||
|
return idt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reverse of date2idt */
|
||||||
|
static date *
|
||||||
|
idt2date(date *dt, date *idt)
|
||||||
|
{
|
||||||
|
|
||||||
|
dt->d = idt->d + 1;
|
||||||
|
if (idt->m < 10) {
|
||||||
|
dt->m = idt->m + 3;
|
||||||
|
dt->y = idt->y;
|
||||||
|
} else {
|
||||||
|
dt->m = idt->m - 9;
|
||||||
|
dt->y = idt->y + 1;
|
||||||
|
}
|
||||||
|
if (dt->m < 1)
|
||||||
|
return (NULL);
|
||||||
|
else
|
||||||
|
return (dt);
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997 Wolfgang Helbig
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $FreeBSD: head/lib/libcalendar/calendar.h 326219 2017-11-26 02:00:33Z pfg $
|
||||||
|
*/
|
||||||
|
struct date {
|
||||||
|
int y; /* year */
|
||||||
|
int m; /* month */
|
||||||
|
int d; /* day */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct date *easterg(int _year, struct date *_dt);
|
||||||
|
struct date *easterog(int _year, struct date *_dt);
|
||||||
|
struct date *easteroj(int _year, struct date *_dt);
|
||||||
|
struct date *gdate(int _nd, struct date *_dt);
|
||||||
|
struct date *jdate(int _nd, struct date *_dt);
|
||||||
|
int ndaysg(struct date *_dt);
|
||||||
|
int ndaysj(struct date *_dt);
|
||||||
|
int week(int _nd, int *_year);
|
||||||
|
int weekday(int _nd);
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997 Wolfgang Helbig
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__FBSDID("$FreeBSD: head/lib/libcalendar/easter.c 326219 2017-11-26 02:00:33Z pfg $");
|
||||||
|
|
||||||
|
#include "calendar.h"
|
||||||
|
|
||||||
|
typedef struct date date;
|
||||||
|
|
||||||
|
static int easterodn(int y);
|
||||||
|
|
||||||
|
/* Compute Easter Sunday in Gregorian Calendar */
|
||||||
|
date *
|
||||||
|
easterg(int y, date *dt)
|
||||||
|
{
|
||||||
|
int c, i, j, k, l, n;
|
||||||
|
|
||||||
|
n = y % 19;
|
||||||
|
c = y / 100;
|
||||||
|
k = (c - 17) / 25;
|
||||||
|
i = (c - c/4 -(c-k)/3 + 19 * n + 15) % 30;
|
||||||
|
i = i -(i/28) * (1 - (i/28) * (29/(i + 1)) * ((21 - n)/11));
|
||||||
|
j = (y + y/4 + i + 2 - c + c/4) % 7;
|
||||||
|
l = i - j;
|
||||||
|
dt->m = 3 + (l + 40) / 44;
|
||||||
|
dt->d = l + 28 - 31*(dt->m / 4);
|
||||||
|
dt->y = y;
|
||||||
|
return (dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the Gregorian date of Easter Sunday in Julian Calendar */
|
||||||
|
date *
|
||||||
|
easterog(int y, date *dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (gdate(easterodn(y), dt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the Julian date of Easter Sunday in Julian Calendar */
|
||||||
|
date *
|
||||||
|
easteroj(int y, date * dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (jdate(easterodn(y), dt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the day number of Easter Sunday in Julian Calendar */
|
||||||
|
static int
|
||||||
|
easterodn(int y)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Table for the easter limits in one metonic (19-year) cycle. 21
|
||||||
|
* to 31 is in March, 1 through 18 in April. Easter is the first
|
||||||
|
* sunday after the easter limit.
|
||||||
|
*/
|
||||||
|
int mc[] = {5, 25, 13, 2, 22, 10, 30, 18, 7, 27, 15, 4,
|
||||||
|
24, 12, 1, 21, 9, 29, 17};
|
||||||
|
|
||||||
|
/* Offset from a weekday to next sunday */
|
||||||
|
int ns[] = {6, 5, 4, 3, 2, 1, 7};
|
||||||
|
date dt;
|
||||||
|
int dn;
|
||||||
|
|
||||||
|
/* Assign the easter limit of y to dt */
|
||||||
|
dt.d = mc[y % 19];
|
||||||
|
|
||||||
|
if (dt.d < 21)
|
||||||
|
dt.m = 4;
|
||||||
|
else
|
||||||
|
dt.m = 3;
|
||||||
|
|
||||||
|
dt.y = y;
|
||||||
|
|
||||||
|
/* Return the next sunday after the easter limit */
|
||||||
|
dn = ndaysj(&dt);
|
||||||
|
return (dn + ns[weekday(dn)]);
|
||||||
|
}
|
|
@ -0,0 +1,250 @@
|
||||||
|
.\" Copyright (c) 1997 Wolfgang Helbig
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD: head/usr.bin/ncal/ncal.1 267773 2014-06-23 08:23:05Z bapt $
|
||||||
|
.\"
|
||||||
|
.Dd March 14, 2009
|
||||||
|
.Dt CAL 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm cal ,
|
||||||
|
.Nm ncal
|
||||||
|
.Nd displays a calendar and the date of Easter
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl 31jy
|
||||||
|
.Op Fl A Ar number
|
||||||
|
.Op Fl B Ar number
|
||||||
|
.Op Fl d Ar yyyy-mm
|
||||||
|
.Oo
|
||||||
|
.Op Ar month
|
||||||
|
.Ar year
|
||||||
|
.Oc
|
||||||
|
.Nm
|
||||||
|
.Op Fl 31j
|
||||||
|
.Op Fl A Ar number
|
||||||
|
.Op Fl B Ar number
|
||||||
|
.Op Fl d Ar yyyy-mm
|
||||||
|
.Fl m Ar month
|
||||||
|
.Op Ar year
|
||||||
|
.Nm ncal
|
||||||
|
.Op Fl C
|
||||||
|
.Op Fl 31jy
|
||||||
|
.Op Fl A Ar number
|
||||||
|
.Op Fl B Ar number
|
||||||
|
.Op Fl d Ar yyyy-mm
|
||||||
|
.Oo
|
||||||
|
.Op Ar month
|
||||||
|
.Ar year
|
||||||
|
.Oc
|
||||||
|
.Nm ncal
|
||||||
|
.Op Fl C
|
||||||
|
.Op Fl 31j
|
||||||
|
.Op Fl A Ar number
|
||||||
|
.Op Fl B Ar number
|
||||||
|
.Op Fl d Ar yyyy-mm
|
||||||
|
.Fl m Ar month
|
||||||
|
.Op Ar year
|
||||||
|
.Nm ncal
|
||||||
|
.Op Fl 31bhjJpwySM
|
||||||
|
.Op Fl A Ar number
|
||||||
|
.Op Fl B Ar number
|
||||||
|
.Op Fl H Ar yyyy-mm-dd
|
||||||
|
.Op Fl d Ar yyyy-mm
|
||||||
|
.Op Fl s Ar country_code
|
||||||
|
.Oo
|
||||||
|
.Op Ar month
|
||||||
|
.Ar year
|
||||||
|
.Oc
|
||||||
|
.Nm ncal
|
||||||
|
.Op Fl 31bhJeoSM
|
||||||
|
.Op Fl A Ar number
|
||||||
|
.Op Fl B Ar number
|
||||||
|
.Op Fl d Ar yyyy-mm
|
||||||
|
.Op Ar year
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility displays a simple calendar in traditional format and
|
||||||
|
.Nm ncal
|
||||||
|
offers an alternative layout, more options and the date of Easter.
|
||||||
|
The new format is a little cramped but it makes a year fit
|
||||||
|
on a 25x80 terminal.
|
||||||
|
If arguments are not specified,
|
||||||
|
the current month is displayed.
|
||||||
|
.Pp
|
||||||
|
The options are as follows:
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Fl h
|
||||||
|
Turns off highlighting of today.
|
||||||
|
.It Fl J
|
||||||
|
Display Julian Calendar, if combined with the
|
||||||
|
.Fl o
|
||||||
|
option, display date of Orthodox Easter according to the Julian Calendar.
|
||||||
|
.It Fl e
|
||||||
|
Display date of Easter (for western churches).
|
||||||
|
.It Fl j
|
||||||
|
Display Julian days (days one-based, numbered from January 1).
|
||||||
|
.It Fl m Ar month
|
||||||
|
Display the specified
|
||||||
|
.Ar month .
|
||||||
|
If
|
||||||
|
.Ar month
|
||||||
|
is specified as a decimal number, appending
|
||||||
|
.Ql f
|
||||||
|
or
|
||||||
|
.Ql p
|
||||||
|
displays the same month of the following or previous year respectively.
|
||||||
|
.It Fl o
|
||||||
|
Display date of Orthodox Easter (Greek and Russian
|
||||||
|
Orthodox Churches).
|
||||||
|
.It Fl p
|
||||||
|
Print the country codes and switching days from Julian to Gregorian
|
||||||
|
Calendar as they are assumed by
|
||||||
|
.Nm ncal .
|
||||||
|
The country code as determined from the local environment is marked
|
||||||
|
with an asterisk.
|
||||||
|
.It Fl s Ar country_code
|
||||||
|
Assume the switch from Julian to Gregorian Calendar at the date
|
||||||
|
associated with the
|
||||||
|
.Ar country_code .
|
||||||
|
If not specified,
|
||||||
|
.Nm ncal
|
||||||
|
tries to guess the switch date from the local environment or
|
||||||
|
falls back to September 2, 1752.
|
||||||
|
This was when Great
|
||||||
|
Britain and her colonies switched to the Gregorian Calendar.
|
||||||
|
.It Fl w
|
||||||
|
Print the number of the week below each week column.
|
||||||
|
.It Fl y
|
||||||
|
Display a calendar for the specified year. This option is implied when
|
||||||
|
a year but no month are specified on the command line.
|
||||||
|
.It Fl 3
|
||||||
|
Display the previous, current and next month surrounding today.
|
||||||
|
.It Fl 1
|
||||||
|
Display only the current month. This is the default.
|
||||||
|
.It Fl A Ar number
|
||||||
|
Months to add after. The specified number of months is added to the
|
||||||
|
end of the display. This is in addition to any date range selected by the
|
||||||
|
.Fl y ,
|
||||||
|
.Fl 3 ,
|
||||||
|
or
|
||||||
|
.Fl 1
|
||||||
|
options. For example,
|
||||||
|
.Dq Li cal -y -B2 -A2
|
||||||
|
shows everything from November of the previous year to
|
||||||
|
February of the following year. Negative numbers are allowed, in which
|
||||||
|
case the specified number of months is subtracted. For example,
|
||||||
|
.Dq Li cal -y -B-6
|
||||||
|
shows July to December. And
|
||||||
|
.Dq Li cal -A11
|
||||||
|
simply shows the next 12 months.
|
||||||
|
.It Fl B Ar number
|
||||||
|
Months to add before. The specified number of months is added to the
|
||||||
|
beginning of the display. See
|
||||||
|
.Fl A
|
||||||
|
for examples.
|
||||||
|
.It Fl C
|
||||||
|
Completely switch to
|
||||||
|
.Nm cal
|
||||||
|
mode. For
|
||||||
|
.Nm cal
|
||||||
|
like output only, use
|
||||||
|
.Fl b
|
||||||
|
instead.
|
||||||
|
.It Fl N
|
||||||
|
Switch to
|
||||||
|
.Nm ncal
|
||||||
|
mode.
|
||||||
|
.It Fl d Ar yyyy-mm
|
||||||
|
Use
|
||||||
|
.Ar yyyy-mm
|
||||||
|
as the current date (for debugging of date selection).
|
||||||
|
.It Fl H Ar yyyy-mm-dd
|
||||||
|
Use
|
||||||
|
.Ar yyyy-mm-dd
|
||||||
|
as the current date (for debugging of highlighting).
|
||||||
|
.It Fl M
|
||||||
|
Weeks start on Monday.
|
||||||
|
.It Fl S
|
||||||
|
Weeks start on Sunday.
|
||||||
|
.It Fl b
|
||||||
|
Use oldstyle format for ncal output.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
A single parameter specifies the year (1\(en9999) to be displayed;
|
||||||
|
note the year must be fully specified:
|
||||||
|
.Dq Li cal 89
|
||||||
|
will
|
||||||
|
.Em not
|
||||||
|
display a calendar for 1989. Two parameters denote the month and
|
||||||
|
year; the month is either a number between 1 and 12, or a full or
|
||||||
|
abbreviated name as specified by the current locale. Month and
|
||||||
|
year default to those of the current system clock and time zone (so
|
||||||
|
.Dq Li cal -m 8
|
||||||
|
will display a calendar for the month of August in the current
|
||||||
|
year).
|
||||||
|
.Pp
|
||||||
|
Not all options can be used together. For example, the options
|
||||||
|
.Fl y , 3 ,
|
||||||
|
and
|
||||||
|
.Fl 1
|
||||||
|
are mutually exclusive. If inconsistent options are given, the later
|
||||||
|
ones take precedence over the earlier ones.
|
||||||
|
.Pp
|
||||||
|
A year starts on January 1.
|
||||||
|
.Pp
|
||||||
|
Highlighting of dates is disabled if stdout is not a tty.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr calendar 3 ,
|
||||||
|
.Xr strftime 3
|
||||||
|
.Sh HISTORY
|
||||||
|
A
|
||||||
|
.Nm
|
||||||
|
command appeared in
|
||||||
|
.At v5 .
|
||||||
|
The
|
||||||
|
.Nm ncal
|
||||||
|
command appeared in
|
||||||
|
.Fx 2.2.6 .
|
||||||
|
The output of the
|
||||||
|
.Nm cal
|
||||||
|
command is supposed to be bit for bit compatible to the original Unix
|
||||||
|
.Nm cal
|
||||||
|
command, because its output is processed by other programs like CGI scripts,
|
||||||
|
that should not be broken. Therefore it will always output 8 lines, even if
|
||||||
|
only 7 contain data. This extra blank line also appears with the original
|
||||||
|
.Nm cal
|
||||||
|
command, at least on Solaris 8
|
||||||
|
.Sh AUTHORS
|
||||||
|
The
|
||||||
|
.Nm ncal
|
||||||
|
command and manual were written by
|
||||||
|
.An Wolfgang Helbig Aq Mt helbig@FreeBSD.org .
|
||||||
|
.Sh BUGS
|
||||||
|
The assignment of Julian\(enGregorian switching dates to country
|
||||||
|
codes is historically naive for many countries.
|
||||||
|
.Pp
|
||||||
|
Not all options are compatible and using them in different orders
|
||||||
|
will give varying results.
|
Loading…
Reference in New Issue