Use the Julian/Gregorian calendar
Use the Julian calendar for dates through September 2, 1752 and the Gregorian calendar for dates from September 14, 1752.
This commit is contained in:
parent
7a58d65483
commit
6c2074560e
2
README
2
README
|
@ -9,7 +9,7 @@ The following tools are implemented (* == finished):
|
||||||
UTILITY POSIX 2008 COMPLIANT MISSING OPTIONS
|
UTILITY POSIX 2008 COMPLIANT MISSING OPTIONS
|
||||||
------- -------------------- ---------------
|
------- -------------------- ---------------
|
||||||
* basename yes none
|
* basename yes none
|
||||||
cal pending pending
|
cal yes none
|
||||||
* cat yes none
|
* cat yes none
|
||||||
chgrp no -h, -H, -L, -P
|
chgrp no -h, -H, -L, -P
|
||||||
chmod yes none
|
chmod yes none
|
||||||
|
|
3
cal.1
3
cal.1
|
@ -28,6 +28,7 @@ of calendars side by side. Each row of calendars contains at most
|
||||||
.IR columns
|
.IR columns
|
||||||
number of calendars. The defaults are obtained using
|
number of calendars. The defaults are obtained using
|
||||||
.IR localtime (3).
|
.IR localtime (3).
|
||||||
|
The Julian calendar is used through Sep 2, 1752, and the Gregorian calendar is used starting the next day with Sep 14, 1752.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B \-1
|
.B \-1
|
||||||
|
@ -57,3 +58,5 @@ Specify the first day of the week. 0 is Sunday and 6 is Saturday.
|
||||||
Specify the number months to print. The default is 1.
|
Specify the number months to print. The default is 1.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.IR localtime (3)
|
.IR localtime (3)
|
||||||
|
.SH STANDARDS
|
||||||
|
This program tries to conform to IEEE Std 1003.1, 2013 Edition, q.v. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cal.html.
|
||||||
|
|
41
cal.c
41
cal.c
|
@ -5,41 +5,61 @@
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
enum {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
|
||||||
|
enum caltype {Julian, Gregorian};
|
||||||
|
enum {TRANS_YEAR = 1752, TRANS_MONTH = Sep, TRANS_DAY = 2};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
isleap(int year)
|
isleap(int year, enum caltype cal)
|
||||||
{
|
{
|
||||||
|
if (cal == Gregorian) {
|
||||||
if (year % 400 == 0)
|
if (year % 400 == 0)
|
||||||
return 1;
|
return 1;
|
||||||
if (year % 100 == 0)
|
if (year % 100 == 0)
|
||||||
return 0;
|
return 0;
|
||||||
return (year % 4 == 0);
|
return (year % 4 == 0);
|
||||||
}
|
}
|
||||||
|
else { /* cal == Julian */
|
||||||
|
return (year % 4 == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
monthlength(int year, int month)
|
monthlength(int year, int month, enum caltype cal)
|
||||||
{
|
{
|
||||||
int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||||
return (month==1 && isleap(year)) ? 29 : mdays[month];
|
return (month==Feb && isleap(year,cal)) ? 29 : mdays[month];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* From http://www.tondering.dk/claus/cal/chrweek.php#calcdow */
|
/* From http://www.tondering.dk/claus/cal/chrweek.php#calcdow */
|
||||||
static int
|
static int
|
||||||
dayofweek(int year, int month, int dom)
|
dayofweek(int year, int month, int dom, enum caltype cal)
|
||||||
{
|
{
|
||||||
int m, y, a;
|
int m, y, a;
|
||||||
month += 1; /* in this formula, 1 <= month <= 12 */
|
month += 1; /* in this formula, 1 <= month <= 12 */
|
||||||
a = (14 - month) / 12;
|
a = (14 - month) / 12;
|
||||||
y = year - a;
|
y = year - a;
|
||||||
m = month + 12*a - 2;
|
m = month + 12*a - 2;
|
||||||
return (dom + y + y/4 - y/100 + y/400 +((31*m)/12)) % 7;
|
|
||||||
|
if (cal == Gregorian)
|
||||||
|
return (dom + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
|
||||||
|
else /* cal == Julian */
|
||||||
|
return (5 + dom + y + y/4 + (31*m)/12) % 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printgrid(int year, int month, int fday, int line)
|
printgrid(int year, int month, int fday, int line)
|
||||||
{
|
{
|
||||||
int dom, offset, d=0;
|
enum caltype cal;
|
||||||
|
int trans; /* are we in the transition from Julian to Gregorian? */
|
||||||
|
int offset, dom, d=0;
|
||||||
|
|
||||||
offset = dayofweek(year, month, 1) - fday;
|
if (year < TRANS_YEAR || (year == TRANS_YEAR && month <= TRANS_MONTH))
|
||||||
|
cal = Julian;
|
||||||
|
else
|
||||||
|
cal = Gregorian;
|
||||||
|
trans = (year == TRANS_YEAR && month == TRANS_MONTH);
|
||||||
|
offset = dayofweek(year, month, 1, cal) - fday;
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
offset += 7;
|
offset += 7;
|
||||||
if (line==1) {
|
if (line==1) {
|
||||||
|
@ -48,9 +68,14 @@ printgrid(int year, int month, int fday, int line)
|
||||||
dom = 1;
|
dom = 1;
|
||||||
} else {
|
} else {
|
||||||
dom = 8-offset + (line-2)*7;
|
dom = 8-offset + (line-2)*7;
|
||||||
|
if (trans && !(line==2 && fday==3))
|
||||||
|
dom += 11;
|
||||||
}
|
}
|
||||||
for ( ; d < 7 && dom <= monthlength(year, month); ++d, ++dom)
|
for ( ; d < 7 && dom <= monthlength(year, month, cal); ++d, ++dom) {
|
||||||
printf("%2d ", dom);
|
printf("%2d ", dom);
|
||||||
|
if (trans && dom==TRANS_DAY)
|
||||||
|
dom += 11;
|
||||||
|
}
|
||||||
for ( ; d < 7; ++d)
|
for ( ; d < 7; ++d)
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user