svn commit: r204189 - user/edwin/calendar

Edwin Groothuis edwin at FreeBSD.org
Mon Feb 22 06:59:17 UTC 2010


Author: edwin
Date: Mon Feb 22 06:59:16 2010
New Revision: 204189
URL: http://svn.freebsd.org/changeset/base/204189

Log:
  - Fix off-by-one error in the equinoxe/solstice calculations.
  - Make solar and lunar events fully UTC/longitude compliant.
  - Be able to give correct times on solar and lunar events.

Modified:
  user/edwin/calendar/calendar.h
  user/edwin/calendar/events.c
  user/edwin/calendar/io.c
  user/edwin/calendar/parsedata.c
  user/edwin/calendar/sunpos.c

Modified: user/edwin/calendar/calendar.h
==============================================================================
--- user/edwin/calendar/calendar.h	Mon Feb 22 04:43:37 2010	(r204188)
+++ user/edwin/calendar/calendar.h	Mon Feb 22 06:59:16 2010	(r204189)
@@ -114,7 +114,7 @@ extern int	year1, year2;
  * - Use event_continue() to add more text to the last added event
  * - Use event_print_all() to display them in time chronological order
  */
-struct event *event_add(int, int, int, char *, int, char *);
+struct event *event_add(int, int, int, char *, int, char *, char *);
 void	event_continue(struct event *events, char *txt);
 void	event_print_all(FILE *fp);
 struct event {
@@ -124,6 +124,7 @@ struct event {
 	int	var;
 	char	*date;
 	char	*text;
+	char	*extra;
 	struct event *next;
 };
 
@@ -151,7 +152,7 @@ void	settimes(time_t,int, int, struct tm
 time_t	Mktime(char *);
 
 /* parsedata.c */
-int	parsedaymonth(char *, int *, int *, int *, int *);
+int	parsedaymonth(char *, int *, int *, int *, int *, char **);
 void	dodebug(char *type);
 
 /* io.c */
@@ -183,4 +184,5 @@ void	fpom(int year, double utcoffset, do
 
 /* sunpos.c */
 void	equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays);
+void	fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays);
 int	calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths);

Modified: user/edwin/calendar/events.c
==============================================================================
--- user/edwin/calendar/events.c	Mon Feb 22 04:43:37 2010	(r204188)
+++ user/edwin/calendar/events.c	Mon Feb 22 06:59:16 2010	(r204189)
@@ -37,7 +37,8 @@ __FBSDID("$FreeBSD: user/edwin/calendar/
 #include "calendar.h"
 
 struct event *
-event_add(int year, int month, int day, char *date, int var, char *txt)
+event_add(int year, int month, int day, char *date, int var, char *txt,
+    char *extra)
 {
 	struct event *e;
 
@@ -60,6 +61,9 @@ event_add(int year, int month, int day, 
 	e->text = strdup(txt);
 	if (e->text == NULL)
 		errx(1, "event_add: cannot allocate memory");
+	e->extra = NULL;
+	if (extra != NULL)
+		e->extra = strdup(extra);
 	addtodate(e, year, month, day);
 	return (e);
 }
@@ -108,8 +112,13 @@ event_print_all(FILE *fp)
 		 * dates
 		 */
 		while (e != NULL) {
-			(void)fprintf(fp, "%s%c%s\n", e->date,
-			    e->var ? '*' : ' ', e->text);
+			(void)fprintf(fp, "%s%c%s%s%s%s\n", e->date,
+			    e->var ? '*' : ' ', e->text,
+			    e->extra != NULL ? " (" : "",
+			    e->extra != NULL ? e->extra : "",
+			    e->extra != NULL ? ")" : ""
+			);
+
 			e = e->next;
 		}
 	}

Modified: user/edwin/calendar/io.c
==============================================================================
--- user/edwin/calendar/io.c	Mon Feb 22 04:43:37 2010	(r204188)
+++ user/edwin/calendar/io.c	Mon Feb 22 06:59:16 2010	(r204189)
@@ -102,6 +102,7 @@ cal(void)
 	int month[MAXCOUNT];
 	int day[MAXCOUNT];
 	int year[MAXCOUNT];
+	char **extradata;	/* strings of 20 length */
 	int flags;
 	static int d_first = -1;
 	char buf[2048 + 1];
@@ -109,6 +110,11 @@ cal(void)
 	struct tm tm;
 	char dbuf[80];
 
+	extradata = (char **)calloc(MAXCOUNT, sizeof(char *));
+	for (i = 0; i < MAXCOUNT; i++) {
+		extradata[i] = (char *)calloc(1, 20);
+	}
+
 	/* Unused */
 	tm.tm_sec = 0;
 	tm.tm_min = 0;
@@ -172,7 +178,8 @@ cal(void)
 
 		p = *pp;
 		*pp = '\0';
-		if ((count = parsedaymonth(buf, year, month, day, &flags)) == 0)
+		if ((count = parsedaymonth(buf, year, month, day, &flags,
+		    extradata)) == 0)
 			continue;
 		*pp = p;
 
@@ -192,7 +199,8 @@ cal(void)
 			if (debug)
 				fprintf(stderr, "got %s\n", pp);
 			events[i] = event_add(year[i], month[i], day[i], dbuf,
-			    ((flags &= F_VARIABLE) != 0) ? 1 : 0, pp);
+			    ((flags &= F_VARIABLE) != 0) ? 1 : 0, pp,
+			    extradata[i]);
 		}
 	}
 

Modified: user/edwin/calendar/parsedata.c
==============================================================================
--- user/edwin/calendar/parsedata.c	Mon Feb 22 04:43:37 2010	(r204188)
+++ user/edwin/calendar/parsedata.c	Mon Feb 22 06:59:16 2010	(r204189)
@@ -46,6 +46,7 @@ static int isonlydigits(char *s, int nos
 static int indextooffset(char *s);
 static int parseoffset(char *s);
 static char *floattoday(int year, double f);
+static char *floattotime(double f);
 
 /*
  * Expected styles:
@@ -297,12 +298,17 @@ allfine:
 }
 
 static void
-remember(int index, int *y, int *m, int *d, int yy, int mm, int dd)
+remember(int index, int *y, int *m, int *d, char **ed, int yy, int mm, int dd,
+    char *extra)
 {
 
 	y[index] = yy;
 	m[index] = mm;
 	d[index] = dd;
+	if (extra != NULL)
+		strcpy(ed[index], extra);
+	else
+		ed[index][0] = '\0';
 }
 
 static void
@@ -336,7 +342,8 @@ struct yearinfo {
 	int ieaster, ipaskha, firstcnyday;
 	double ffullmoon[MAXMOONS], fnewmoon[MAXMOONS];
 	double ffullmooncny[MAXMOONS], fnewmooncny[MAXMOONS];
-	int ichinesemonths[MAXMOONS], equinoxdays[2], solsticedays[2];
+	int ichinesemonths[MAXMOONS];
+	double equinoxdays[2], solsticedays[2];
 	int *mondays;
 	struct yearinfo *next;
 };
@@ -351,12 +358,14 @@ struct yearinfo {
  * along with the matched line.
  */
 int
-parsedaymonth(char *date, int *yearp, int *monthp, int *dayp, int *flags)
+parsedaymonth(char *date, int *yearp, int *monthp, int *dayp, int *flags,
+    char **edp)
 {
 	char month[100], dayofmonth[100], dayofweek[100], modifieroffset[100];
 	char modifierindex[100], specialday[100];
 	int idayofweek, imonth, idayofmonth, year, index;
 	int d, m, dow, rm, rd, offset;
+	char *ed;
 
 	static struct yearinfo *years, *yearinfo;
 
@@ -413,7 +422,7 @@ parsedaymonth(char *date, int *yearp, in
 			    yearinfo->fnewmoon);
 			fpom(year, UTCOFFSET_CNY, yearinfo->ffullmooncny,
 			    yearinfo->fnewmooncny);
-			equinoxsolstice(year, 0.0,
+			fequinoxsolstice(year, UTCoffset,
 			    yearinfo->equinoxdays, yearinfo->solsticedays);
 
 			/*
@@ -436,8 +445,8 @@ parsedaymonth(char *date, int *yearp, in
 		if (*flags == (F_MONTH | F_DAYOFMONTH)) {
 			if (!remember_ymd(year, imonth, idayofmonth))
 				continue;
-			remember(index++, yearp, monthp, dayp,
-			    year, imonth, idayofmonth);
+			remember(index++, yearp, monthp, dayp, edp,
+			    year, imonth, idayofmonth, NULL);
 			continue;
 		}
 
@@ -446,8 +455,8 @@ parsedaymonth(char *date, int *yearp, in
 			for (m = 1; m <= 12; m++) {
 				if (!remember_ymd(year, m, idayofmonth))
 					continue;
-				remember(index++, yearp, monthp, dayp,
-				    year, m, idayofmonth);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, m, idayofmonth, NULL);
 			}
 			continue;
 		}
@@ -457,8 +466,8 @@ parsedaymonth(char *date, int *yearp, in
 			for (d = 1; d <= yearinfo->mondays[imonth]; d++) {
 				if (!remember_ymd(year, imonth, d))
 					continue;
-				remember(index++, yearp, monthp, dayp,
-				    year, imonth, d);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, imonth, d, NULL);
 			}
 			continue;
 		}
@@ -468,8 +477,8 @@ parsedaymonth(char *date, int *yearp, in
 			for (m = 1; m <= 12; m++) {
 				if (!remember_ymd(year, m, idayofmonth))
 					continue;
-				remember(index++, yearp, monthp, dayp,
-				    year, m, idayofmonth);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, m, idayofmonth, NULL);
 			}
 			continue;
 		}
@@ -480,8 +489,9 @@ parsedaymonth(char *date, int *yearp, in
 			d = (idayofweek - dow + 8) % 7;
 			while (d <= 366) {
 				if (remember_yd(year, d, &rm, &rd))
-					remember(index++, yearp, monthp, dayp,
-					    year, rm, rd);
+					remember(index++,
+					    yearp, monthp, dayp, edp,
+					    year, rm, rd, NULL);
 				d += 7;
 			}
 			continue;
@@ -498,9 +508,9 @@ parsedaymonth(char *date, int *yearp, in
 				while (d <= yearinfo->mondays[imonth]) {
 					if (--offset == 0
 					 && remember_ymd(year, imonth, d)) {
-						remember(index++, yearp,
-						    monthp, dayp, year, imonth,
-						    d);
+						remember(index++,
+						    yearp, monthp, dayp, edp,
+						    year, imonth, d, NULL);
 						continue;
 					}
 					d += 7;
@@ -515,8 +525,9 @@ parsedaymonth(char *date, int *yearp, in
 					d -= 7;
 				}
 				if (remember_ymd(year, imonth, d))
-					remember(index++, yearp,
-					    monthp, dayp, year, imonth, d);
+					remember(index++,
+					    yearp, monthp, dayp, edp,
+					    year, imonth, d, NULL);
 				continue;
 			}
 			continue;
@@ -528,8 +539,9 @@ parsedaymonth(char *date, int *yearp, in
 			d = (idayofweek - dow + 8) % 7;
 			while (d <= yearinfo->mondays[imonth]) {
 				if (remember_ymd(year, imonth, d))
-					remember(index++, yearp, monthp, dayp,
-					    year, imonth, d);
+					remember(index++,
+					    yearp, monthp, dayp, edp,
+					    year, imonth, d, NULL);
 				d += 7;
 			}
 			continue;
@@ -543,8 +555,8 @@ parsedaymonth(char *date, int *yearp, in
 				offset = parseoffset(modifieroffset);
 			if (remember_yd(year, yearinfo->ieaster + offset,
 			    &rm, &rd))
-				remember(index++, yearp, monthp, dayp,
-				    year, rm, rd);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, rm, rd, NULL);
 			continue;
 		}
 
@@ -556,8 +568,8 @@ parsedaymonth(char *date, int *yearp, in
 				offset = parseoffset(modifieroffset);
 			if (remember_yd(year, yearinfo->ipaskha + offset,
 			    &rm, &rd))
-				remember(index++, yearp, monthp, dayp,
-				    year, rm, rd);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, rm, rd, NULL);
 			continue;
 		}
 
@@ -569,8 +581,8 @@ parsedaymonth(char *date, int *yearp, in
 				offset = parseoffset(modifieroffset);
 			if (remember_yd(year, yearinfo->firstcnyday + offset,
 			    &rm, &rd))
-				remember(index++, yearp, monthp, dayp,
-				    year, rm, rd);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, rm, rd, NULL);
 			continue;
 		}
 
@@ -585,9 +597,13 @@ parsedaymonth(char *date, int *yearp, in
 			for (i = 0; yearinfo->ffullmoon[i] > 0; i++) {
 				if (remember_yd(year,
 				    floor(yearinfo->ffullmoon[i]) + offset,
-					&rm, &rd))
-					remember(index++, yearp, monthp, dayp,
-						year, rm, rd);
+					&rm, &rd)) {
+					ed = floattotime(
+					    yearinfo->ffullmoon[i]);
+					remember(index++,
+					    yearp, monthp, dayp, edp,
+					    year, rm, rd, ed);
+				}
 			}
 			continue;
 		}
@@ -603,9 +619,12 @@ parsedaymonth(char *date, int *yearp, in
 			for (i = 0; yearinfo->ffullmoon[i] > 0; i++) {
 				if (remember_yd(year,
 				    floor(yearinfo->fnewmoon[i]) + offset,
-				    &rm, &rd))
-					remember(index++, yearp, monthp, dayp,
-						year, rm, rd);
+				    &rm, &rd)) {
+					ed = floattotime(yearinfo->fnewmoon[i]);
+					remember(index++,
+					    yearp, monthp, dayp, edp,
+					    year, rm, rd, ed);
+				}
 			}
 			continue;
 		}
@@ -617,9 +636,11 @@ parsedaymonth(char *date, int *yearp, in
 			if ((*flags & F_MODIFIEROFFSET) != 0)
 				offset = parseoffset(modifieroffset);
 			if (remember_yd(year, yearinfo->equinoxdays[0] + offset,
-			    &rm, &rd))
-				remember(index++, yearp, monthp, dayp,
-				    year, rm, rd);
+			    &rm, &rd)) {
+				ed = floattotime(yearinfo->equinoxdays[0]);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, rm, rd, ed);
+			}
 			continue;
 		}
 		if ((*flags & ~F_MODIFIEROFFSET) ==
@@ -628,9 +649,11 @@ parsedaymonth(char *date, int *yearp, in
 			if ((*flags & F_MODIFIEROFFSET) != 0)
 				offset = parseoffset(modifieroffset);
 			if (remember_yd(year, yearinfo->equinoxdays[1] + offset,
-			    &rm, &rd))
-				remember(index++, yearp, monthp, dayp,
-				    year, rm, rd);
+			    &rm, &rd)) {
+				ed = floattotime(yearinfo->equinoxdays[1]);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, rm, rd, ed);
+			}
 			continue;
 		}
 
@@ -641,9 +664,11 @@ parsedaymonth(char *date, int *yearp, in
 			if ((*flags & F_MODIFIEROFFSET) != 0)
 				offset = parseoffset(modifieroffset);
 			if (remember_yd(year,
-			    yearinfo->solsticedays[0] + offset, &rm, &rd))
-				remember(index++, yearp, monthp, dayp,
-				    year, rm, rd);
+			    yearinfo->solsticedays[0] + offset, &rm, &rd)) {
+				ed = floattotime(yearinfo->solsticedays[0]);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, rm, rd, ed);
+			}
 			continue;
 		}
 		if ((*flags & ~F_MODIFIEROFFSET) ==
@@ -652,9 +677,11 @@ parsedaymonth(char *date, int *yearp, in
 			if ((*flags & F_MODIFIEROFFSET) != 0)
 				offset = parseoffset(modifieroffset);
 			if (remember_yd(year,
-			    yearinfo->solsticedays[1] + offset, &rm, &rd))
-				remember(index++, yearp, monthp, dayp,
-				    year, rm, rd);
+			    yearinfo->solsticedays[1] + offset, &rm, &rd)) {
+				ed = floattotime(yearinfo->solsticedays[1]);
+				remember(index++, yearp, monthp, dayp, edp,
+				    year, rm, rd, ed);
+			}
 			continue;
 		}
 
@@ -854,6 +881,25 @@ parseoffset(char *s)
 }
 
 static char *
+floattotime(double f)
+{
+	static char buf[100];
+	int hh, mm, ss, i;
+
+	f -= floor(f);
+	i = f * SECSPERDAY;
+
+	hh = i / SECSPERHOUR;
+	i %= SECSPERHOUR;
+	mm = i / SECSPERMINUTE;
+	i %= SECSPERMINUTE;
+	ss = i;
+
+	sprintf(buf, "%02d:%02d:%02d", hh, mm, ss);
+	return (buf);
+}
+
+static char *
 floattoday(int year, double f)
 {
 	static char buf[100];
@@ -924,4 +970,26 @@ dodebug(char *what)
 	
 		return;
 	}
+
+	if (strcmp(what, "sun") == 0) {
+		double equinoxdays[2], solsticedays[2];
+		for (year = year1; year <= year2; year++) {
+			printf("Sun in %d:\n", year);
+			fequinoxsolstice(year, UTCoffset, equinoxdays,
+			    solsticedays);
+			printf("e[0] - %g (%s)\n",
+			    equinoxdays[0],
+			    floattoday(year, equinoxdays[0]));
+			printf("e[1] - %g (%s)\n",
+			    equinoxdays[1],
+			    floattoday(year, equinoxdays[1]));
+			printf("s[0] - %g (%s)\n",
+			    solsticedays[0],
+			    floattoday(year, solsticedays[0]));
+			printf("s[1] - %g (%s)\n",
+			    solsticedays[1],
+			    floattoday(year, solsticedays[1]));
+		}
+		return;
+	}
 }

Modified: user/edwin/calendar/sunpos.c
==============================================================================
--- user/edwin/calendar/sunpos.c	Mon Feb 22 04:43:37 2010	(r204188)
+++ user/edwin/calendar/sunpos.c	Mon Feb 22 06:59:16 2010	(r204189)
@@ -191,6 +191,18 @@ sunpos(int inYY, int inMM, int inDD, dou
 void
 equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays)
 {
+	double fe[2], fs[2];
+
+	fequinoxsolstice(year, UTCoffset, fe, fs);
+	equinoxdays[0] = round(fe[0]);
+	equinoxdays[1] = round(fe[1]);
+	solsticedays[0] = round(fs[0]);
+	solsticedays[1] = round(fs[1]);
+}
+
+void
+fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays)
+{
 	double dec, prevdec, L;
 	int h, d, prevangle, angle;
 	int found = 0;
@@ -214,7 +226,8 @@ equinoxsolstice(int year, double UTCoffs
 				DEBUG1(year, 3, d, HOUR(h), MIN(h),
 				    prevdec, dec);
 #endif
-				equinoxdays[0] = cumdays[3] + d;
+				equinoxdays[0] = 1 + cumdays[3] + d +
+				    ((h / 4.0) / 24.0);
 				found = 1;
 				break;
 			}
@@ -239,7 +252,8 @@ equinoxsolstice(int year, double UTCoffs
 				DEBUG1(year, 9, d, HOUR(h), MIN(h),
 				    prevdec, dec);
 #endif
-				equinoxdays[1] = cumdays[9] + d;
+				equinoxdays[1] = 1 + cumdays[9] + d +
+				    ((h / 4.0) / 24.0);
 				found = 1;
 				break;
 			}
@@ -267,7 +281,8 @@ equinoxsolstice(int year, double UTCoffs
 				DEBUG2(year, 6, d, HOUR(h), MIN(h),
 				    prevdec, dec, prevangle, angle);
 #endif
-				solsticedays[0] = cumdays[6] + d;
+				solsticedays[0] = 1 + cumdays[6] + d +
+				    ((h / 4.0) / 24.0);
 				found = 1;
 				break;
 			}
@@ -296,7 +311,8 @@ equinoxsolstice(int year, double UTCoffs
 				DEBUG2(year, 12, d, HOUR(h), MIN(h),
 				    prevdec, dec, prevangle, angle);
 #endif
-				solsticedays[1] = cumdays[12] + d;
+				solsticedays[1] = 1 + cumdays[12] + d +
+				    ((h / 4.0) / 24.0);
 				found = 1;
 				break;
 			}


More information about the svn-src-user mailing list