svn commit: r203324 - user/edwin/calendar

Edwin Groothuis edwin at FreeBSD.org
Sun Jan 31 21:51:28 UTC 2010


Author: edwin
Date: Sun Jan 31 21:51:27 2010
New Revision: 203324
URL: http://svn.freebsd.org/changeset/base/203324

Log:
  Be able to determine Chinese New Year.

Modified:
  user/edwin/calendar/calendar.h
  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	Sun Jan 31 21:47:39 2010	(r203323)
+++ user/edwin/calendar/calendar.h	Sun Jan 31 21:51:27 2010	(r203324)
@@ -163,3 +163,4 @@ void	pom(int year, int *fms, int *nms);
 
 /* sunpos.c */
 void	equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays);
+int	calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths);

Modified: user/edwin/calendar/io.c
==============================================================================
--- user/edwin/calendar/io.c	Sun Jan 31 21:47:39 2010	(r203323)
+++ user/edwin/calendar/io.c	Sun Jan 31 21:51:27 2010	(r203324)
@@ -174,7 +174,6 @@ cal(void)
 		*pp = '\0';
 		if ((count = parsedaymonth(buf, year, month, day, &flags)) == 0)
 			continue;
-		printf("%s - count: %d\n", buf, count);
 		*pp = p;
 
 		/* Find the last tab */

Modified: user/edwin/calendar/parsedata.c
==============================================================================
--- user/edwin/calendar/parsedata.c	Sun Jan 31 21:47:39 2010	(r203323)
+++ user/edwin/calendar/parsedata.c	Sun Jan 31 21:51:27 2010	(r203324)
@@ -347,10 +347,10 @@ parsedaymonth(char *date, int *yearp, in
 	int idayofweek, imonth, idayofmonth, year, index;
 
 	int ieaster, ipaskha;
-	int ifullmoon[MAXMOONS], inewmoon[MAXMOONS];
+	int ifullmoon[MAXMOONS], inewmoon[MAXMOONS], ichinesemonths[MAXMOONS];
 	int equinoxdays[2], solsticedays[2];
 
-	int *mondays, d, m, dow, rm, rd, offset;
+	int *mondays, d, m, dow, rm, rd, offset, firstcnyday;
 
 	/*
 	 * CONVENTION
@@ -389,6 +389,16 @@ parsedaymonth(char *date, int *yearp, in
 		pom(year, ifullmoon, inewmoon);
 		equinoxsolstice(year, 0.0, equinoxdays, solsticedays);
 
+		/* CNY: Match day with sun longitude at 330` with new moon */
+		firstcnyday = calculatesunlongitude30(year, 120,
+		    ichinesemonths);
+		for (m = 0; inewmoon[m] != 0; m++) {
+			if (inewmoon[m] > firstcnyday) {
+				firstcnyday = inewmoon[m - 1];
+				break;
+			}
+		}
+
 		/* Same day every year */
 		if (*flags == (F_MONTH | F_DAYOFMONTH)) {
 			if (!remember_ymd(year, imonth, idayofmonth))
@@ -516,6 +526,18 @@ parsedaymonth(char *date, int *yearp, in
 			continue;
 		}
 
+		/* Chinese New Year */
+		if ((*flags & ~F_MODIFIEROFFSET) ==
+		    (F_SPECIALDAY | F_VARIABLE | F_CNY)) {
+			offset = 0;
+			if ((*flags & F_MODIFIEROFFSET) != 0)
+				offset = parseoffset(modifieroffset);
+			if (remember_yd(year, firstcnyday + offset, &rm, &rd))
+				remember(index++, yearp, monthp, dayp,
+				    year, rm, rd);
+			continue;
+		}
+
 		/* FullMoon */
 		if ((*flags & ~F_MODIFIEROFFSET) ==
 		    (F_SPECIALDAY | F_VARIABLE | F_FULLMOON)) {

Modified: user/edwin/calendar/sunpos.c
==============================================================================
--- user/edwin/calendar/sunpos.c	Sun Jan 31 21:47:39 2010	(r203323)
+++ user/edwin/calendar/sunpos.c	Sun Jan 31 21:51:27 2010	(r203324)
@@ -93,14 +93,10 @@ static double ZJtable[] = {
 
 static void
 sunpos(int inYY, int inMM, int inDD, double UTCOFFSET, int inHOUR, int inMIN,
-    double eastlongitude, double latitude, double *DEC, double *ALT, double *AZ)
+    double eastlongitude, double latitude, double *L, double *DEC)
 {
 	int Y;
-	double ZJ, D, T, L, M, epsilon, lambda, alpha, HA, UTHM;
-
-	/* Not calculated in this code */
-	*ALT = 0;
-	*AZ = 0;
+	double ZJ, D, T, M, epsilon, lambda, alpha, HA, UTHM;
 
 	ZJ = ZJtable[inMM];
 	if (inMM <= 2 && isleap(inYY))
@@ -110,14 +106,14 @@ sunpos(int inYY, int inMM, int inDD, dou
 	Y = inYY - 1900;						/*  1 */
 	D = floor(365.25 * Y) + ZJ + inDD + UTHM / 24;			/*  3 */
 	T = D / 36525.0;						/*  4 */
-	L = 279.697 + 36000.769 * T;					/*  5 */
-	fixup(&L);
+	*L = 279.697 + 36000.769 * T;					/*  5 */
+	fixup(L);
 	M = 358.476 + 35999.050 * T;					/*  6 */
 	fixup(&M);
 	epsilon = 23.452 - 0.013 * T;					/*  7 */
 	fixup(&epsilon);
 
-	lambda = L + (1.919 - 0.005 * T) * SIN(M) + 0.020 * SIN(2 * M);	/*  8 */
+	lambda = *L + (1.919 - 0.005 * T) * SIN(M) + 0.020 * SIN(2 * M);	/*  8 */
 	fixup(&lambda);
 	alpha = ATAN(TAN(lambda) * COS(epsilon));			/*  9 */
 
@@ -134,7 +130,7 @@ sunpos(int inYY, int inMM, int inDD, dou
 	*DEC = ASIN(SIN(lambda) * SIN(epsilon));			/* 10 */
 	fixup(DEC);
 	fixup(&eastlongitude);
-	HA = L - alpha + 180 + 15 * UTHM + eastlongitude;		/* 12 */
+	HA = *L - alpha + 180 + 15 * UTHM + eastlongitude;		/* 12 */
 	fixup(&HA);
 	fixup(&latitude);
 #ifdef NOTDEF
@@ -195,7 +191,7 @@ sunpos(int inYY, int inMM, int inDD, dou
 void
 equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays)
 {
-	double dec, prevdec, alt, az;
+	double dec, prevdec, L;
 	int h, d, prevangle, angle;
 	int found = 0;
 
@@ -212,7 +208,7 @@ equinoxsolstice(int year, double UTCoffs
 	for (d = 18; d < 31; d++) {
 		for (h = 0; h < 4 * 24; h++) {
 			sunpos(year, 3, d, UTCoffset, HOUR(h), MIN(h),
-			    0.0, 0.0, &dec, &alt, &az);
+			    0.0, 0.0, &L, &dec);
 			if (SIGN(prevdec) != SIGN(dec)) {
 #ifdef NOTDEF
 				DEBUG1(year, 3, d, HOUR(h), MIN(h),
@@ -237,7 +233,7 @@ equinoxsolstice(int year, double UTCoffs
 	for (d = 18; d < 31; d++) {
 		for (h = 0; h < 4 * 24; h++) {
 			sunpos(year, 9, d, UTCoffset, HOUR(h), MIN(h),
-			    0.0, 0.0, &dec, &alt, &az);
+			    0.0, 0.0, &L, &dec);
 			if (SIGN(prevdec) != SIGN(dec)) {
 #ifdef NOTDEF
 				DEBUG1(year, 9, d, HOUR(h), MIN(h),
@@ -264,7 +260,7 @@ equinoxsolstice(int year, double UTCoffs
 	for (d = 18; d < 31; d++) {
 		for (h = 0; h < 4 * 24; h++) {
 			sunpos(year, 6, d, UTCoffset, HOUR(h), MIN(h),
-			    0.0, 0.0, &dec, &alt, &az);
+			    0.0, 0.0, &L, &dec);
 			angle = ANGLE(prevdec, dec);
 			if (prevangle != angle) {
 #ifdef NOTDEF
@@ -293,7 +289,7 @@ equinoxsolstice(int year, double UTCoffs
 	for (d = 18; d < 31; d++) {
 		for (h = 0; h < 4 * 24; h++) {
 			sunpos(year, 12, d, UTCoffset, HOUR(h), MIN(h),
-			    0.0, 0.0, &dec, &alt, &az);
+			    0.0, 0.0, &L, &dec);
 			angle = ANGLE(prevdec, dec);
 			if (prevangle != angle) {
 #ifdef NOTDEF
@@ -314,6 +310,58 @@ equinoxsolstice(int year, double UTCoffs
 	return;
 }
 
+int
+calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths)
+{
+	int m, d, h;
+	double dec;
+	double curL, prevL;
+	int *pichinesemonths, *monthdays, *cumdays, i;
+	int firstmonth330;
+
+	cumdays = cumdaytab[isleap(year)];
+	monthdays = mondaytab[isleap(year)];
+	pichinesemonths = ichinesemonths;
+
+	sunpos(year - 1, 12, 31,
+	    -24 * (degreeGMToffset / 360.0),
+	    HOUR(h), MIN(h), 0.0, 0.0, &prevL, &dec);
+
+	for (m = 1; m <= 12; m++) {
+		for (d = 1; d <= monthdays[m]; d++) {
+			for (h = 0; h < 4 * 24; h++) {
+				sunpos(year, m, d,
+				    -24 * (degreeGMToffset / 360.0),
+				    HOUR(h), MIN(h), 0.0, 0.0, &curL, &dec);
+				if (curL < 180 && prevL > 180) {
+					*pichinesemonths = cumdays[m] + d;
+#ifdef DEBUG
+printf("%04d-%02d-%02d %02d:%02d - %d %g\n",
+    year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
+#endif
+					    pichinesemonths++;
+				} else {
+					for (i = 0; i <= 360; i += 30)
+						if (curL > i && prevL < i) {
+							*pichinesemonths =
+							    cumdays[m] + d;
+#ifdef DEBUG
+printf("%04d-%02d-%02d %02d:%02d - %d %g\n",
+    year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
+#endif
+							if (i == 330)
+								firstmonth330 = *pichinesemonths;
+							pichinesemonths++;
+						}
+				}
+				prevL = curL;
+			}
+		}
+	}
+	*pichinesemonths = 0;
+	return (firstmonth330);
+}
+
 #ifdef NOTDEF
 int
 main(int argc, char **argv)


More information about the svn-src-user mailing list