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