[hackers] [sbase] Use the Julian/Gregorian calendar || Greg Reagle

From: <git_AT_suckless.org>
Date: Fri, 16 Jan 2015 11:03:25 +0100 (CET)

commit 6c2074560efe07b5b8c357e4b2bb306502419197
Author: Greg Reagle <greg.reagle_AT_umbc.edu>
Date: Thu Jan 8 17:16:19 2015 -0500

    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.

diff --git a/README b/README
index 107e4ad..6b1a6a6 100644
--- a/README
+++ b/README
_AT_@ -9,7 +9,7 @@ The following tools are implemented (* == finished):
   UTILITY POSIX 2008 COMPLIANT MISSING OPTIONS
   ------- -------------------- ---------------
 * basename yes none
- cal pending pending
+ cal yes none
 * cat yes none
   chgrp no -h, -H, -L, -P
   chmod yes none
diff --git a/cal.1 b/cal.1
index c215340..8619460 100644
--- a/cal.1
+++ b/cal.1
_AT_@ -28,6 +28,7 @@ of calendars side by side. Each row of calendars contains at most
 .IR columns
 number of calendars. The defaults are obtained using
 .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
 .TP
 .B \-1
_AT_@ -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.
 .SH SEE ALSO
 .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.
diff --git a/cal.c b/cal.c
index 53c6022..8d6dda0 100644
--- a/cal.c
+++ b/cal.c
_AT_@ -5,41 +5,61 @@
 
 #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
-isleap(int year)
+isleap(int year, enum caltype cal)
 {
- if (year % 400 == 0)
- return 1;
- if (year % 100 == 0)
- return 0;
- return (year % 4 == 0);
+ if (cal == Gregorian) {
+ if (year % 400 == 0)
+ return 1;
+ if (year % 100 == 0)
+ return 0;
+ return (year % 4 == 0);
+ }
+ else { /* cal == Julian */
+ return (year % 4 == 0);
+ }
 }
 
 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 };
- 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 */
 static int
-dayofweek(int year, int month, int dom)
+dayofweek(int year, int month, int dom, enum caltype cal)
 {
         int m, y, a;
         month += 1; /* in this formula, 1 <= month <= 12 */
         a = (14 - month) / 12;
         y = year - a;
         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
 printgrid(int year, int month, int fday, int line)
 {
- int dom, offset, d=0;
-
- offset = dayofweek(year, month, 1) - fday;
+ enum caltype cal;
+ int trans; /* are we in the transition from Julian to Gregorian? */
+ int offset, dom, d=0;
+
+ 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)
                 offset += 7;
         if (line==1) {
_AT_@ -48,9 +68,14 @@ printgrid(int year, int month, int fday, int line)
                 dom = 1;
         } else {
                 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);
+ if (trans && dom==TRANS_DAY)
+ dom += 11;
+ }
         for ( ; d < 7; ++d)
                 printf(" ");
 }
Received on Fri Jan 16 2015 - 11:03:25 CET

This archive was generated by hypermail 2.3.0 : Fri Jan 16 2015 - 11:12:23 CET