commit 5cccbf6783c73f0be5c0218014c2d000e33d9eec Author: Steffen Vogel Date: Thu Nov 22 18:58:01 2012 +0100 initial commit diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..c451cdc --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Steffen Vogel diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL b/INSTALL new file mode 120000 index 0000000..cbd1c80 --- /dev/null +++ b/INSTALL @@ -0,0 +1 @@ +/usr/share/automake-1.11/INSTALL \ No newline at end of file diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..4eb56c1 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +dist_doc_DATA = README diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..2805968 --- /dev/null +++ b/README @@ -0,0 +1 @@ +libastro is a collection of functions for time, date and ephemeris calculus diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..d99e2f7 --- /dev/null +++ b/configure.ac @@ -0,0 +1,29 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.69]) +AC_INIT(astro, 0.1, stv0g@0l.de) +AC_CONFIG_SRCDIR([include/sun.h]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +AC_PROG_CC + +# Checks for libraries. + +# Checks for header files. + +# Checks for typedefs, structures, and compiler characteristics. + +# Checks for library functions. + +# Automake +AM_INIT_AUTOMAKE +AM_PROG_CC_C_O + +AC_CONFIG_FILES([ + Makefile + src/Makefile +]) + +AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..93ae07e --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,4 @@ +bin_PROGRAMS = astro + +astro_SOURCES = calendar.c astro.c +astro_LDADD = -lm diff --git a/src/astro.c b/src/astro.c new file mode 100644 index 0000000..93eadb0 --- /dev/null +++ b/src/astro.c @@ -0,0 +1,48 @@ +#include +#include + +#include "calendar.h" + +extern const char* weekdays[]; +extern const char* months[]; + +int main(int argc, char *argv[]) { + time_t u = time(NULL); + struct tm *n = localtime(&u); /* current time and date */ + + struct date d; + struct time t; + + if (argc == 2) { + sscanf(argv[1], "%d.%d.%d", &d.day, &d.month, &d.year); + } + else { + d.day = n->tm_mday; + d.month = n->tm_mon+1; + d.year = n->tm_year+1900; + } + + t.hour = n->tm_hour; + t.minute = n->tm_min; + t.second = n->tm_sec; + + + printf("Berechne für %d.%d.%d %d:%0d\n", d.day, d.month, d.year, t.hour, t.minute); + + struct date e = eastern(d.year); + enum weekday wday = weekday(d); + bool leap = leapyear(d.year); + double dec = hms2decimal(t); + int day = daynumber(d); + int week = weeknumber(d); // TODO fix + + printf("In year %d, eastern is on %s the %d. %s\n", e.year, weekdays[weekday(e)], e.day, months[e.month-1]); + printf("The year %d %s a leapyear\n", d.year, (leap) ? "is" : "is not"); + printf("Daynumber: %d\n", day); + printf("Today is a %s\n", weekdays[wday]); + printf("%.1f %% of the day are over :-%c\n", dec*1e2, (dec > 0.5) ? '(' : ')'); + printf("Weeknumber: %d\n", week); + + + return 0; +} diff --git a/src/calendar.c b/src/calendar.c new file mode 100644 index 0000000..f7f89f6 --- /dev/null +++ b/src/calendar.c @@ -0,0 +1,203 @@ +#include + +#include "calendar.h" + +/** Constants */ +const double DELTA_T = 66.7; /* seconds */ + +const char *weekdays[] = { "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday", "Sunday" }; + +const char *holidays[] = { }; + +const char *months[] = { "January", "February", "March", + "April", "May", "June", "July", "August", + "October", "November", "December" }; + +const char *signs[] = { "Aries", "Taurus", "Gemini", "Cancer", + "Leo", "Virgo", "Libra", "Scorpio", + "Ophiuchus", "Sagittarius", "Capricorn", + "Aquarius", "Pisces" }; + +double frac(double x) { + return x - floor(x); +} + +struct date eastern(int year) { + int k = year / 100; /* Säkularzahl */ + int m = 15 + (3*k + 3) / 4 - (8*k + 13) / 25; /* säkulare Mondschaltung */ + int s = 2 - (3*k + 3) / 4; /* säkulare Sonnenschaltung */ + int a = year % 19; /* den Mondparameter */ + int d = (19*a + m) % 30; /* Keim für den ersten Vollmond im Frühling */ + int r = (d + a/11) / 29; /* kalendarische Korrekturgröße */ + int og = 21 + d - r; /* Ostergrenze */ + int sz = 7 - (year + year/4 + s) % 7; /* erster Sonntag im März */ + int oe = 7 - (og - sz) % 7; /* Osterentfernung in Tagen */ + int os = os = og + oe; /* Datum des Ostersonntags als Märzdatum */ + + struct date eastern = { + .year = year, + .month = (os > 31) ? 4 : 3, + .day = (os > 31) ? os - 31 : os + }; + + return eastern; +} + +struct date holiday(struct date date, enum holiday type) { + switch (type) { + case EASTER_SUNDAY: + return eastern(date.year); + break; + + case NEWYEAR: { + struct date ny; + ny.year = date.year; + ny.month = 1; + ny.day = 1; + return ny; + } + + case SILVESTER: { + struct date sv; + sv.year = date.year; + sv.month = 12; + sv.day = 31; + return sv; + } + } +} + +int weekday(struct date date) { + const int century_code[] = { 6, 4, 2, 0 }; + const int month_code[] = { 6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; + + int l = (leapyear(date.year) && date.month <= 2) ? 1 : 0; + int x = date.year % 100; + int y = date.year / 100; + int a = century_code[(y - 16) % 4]; + int b = month_code[(date.month-1) % 12] - l; + int c = x + x/4; + int d = date.day; + + return (a + b + c + d) % 7; +} + +bool leapyear(int year) { + if ((year % 400) == 0) + return true; + else if ((year % 100) == 0) + return false; + else if ((year % 4) == 0) + return true; + else + return false; +} + +int daynumber(struct date date) { + int days = date.month; + + if (date.month <= 2) { + days--; + days *= leapyear(date.year) ? 62 : 63; + days /= 2; + } + else { + days++; + days *= 30.6; + days -= leapyear(date.year)? 62 : 63; + } + + return days + date.day; +} + +int weeknumber(struct date date) { + int dn = daynumber(date); + + struct date ny = { /* new year */ + .year = date.year, + .month = 1, .day = 1 + }; + int wdny = weekday(ny); + + // Sonderfälle Freitag und Samstag + if (wdny >= 5) { + wdny -= 7; + } + + // Sonderfälle "Jahresanfang mit KW-Nummer aus dem Vorjahr" + if (dn + wdny <= 1) { + struct date sv = { /* silvester last year */ + .year = date.year - 1, + .month = 12, .day = 31 + }; + return weeknumber(sv); + } + + int wn = (dn + wdny + 5) / 7; + + /* 53 Kalenderwochen hat grundsätzlich nur ein Jahr, + welches mit einem Donnerstag anfängt ! + In Schaltjahren ist es auch mit einem Mittwoch möglich, z.B. 1992 + Andernfalls ist diese KW schon die KW1 des Folgejahres. */ + if (wn == 53) { + bool ly = leapyear(date.year); + + if ( (wdny + 7 ) % 7 == 4 || ((wdny + 7) % 7 == 3 && ly)) { + return wn; + } + else { + return 1; // Korrektur des Wertes + } + } + else { + return wn; + } +} + +double hms2decimal(struct time t) { + return (((t.second / 60.0) + t.minute) / 60.0 + t.hour) / 24.0; +} + +struct time decimal2hms(double decimal) { + double hours = decimal * 24; + double minutes = frac(hours) * 60; + double seconds = frac(minutes) * 60; + + struct time time = { hours, minutes, seconds }; + return time; +} + +int gregorian2julian(struct date d) { + if (d.month <= 2) { + d.year--; + d.month += 12; + } + + struct date x = { .day = 15, .month = 10, .year = 1582 }; + if (datecmp(d, x) > 0) { + int a = d.year / 100; + int b = 2 - a + + } + + return b + c + d + d.day + 1720994.5 +} + +struct date julian2gregorian(int jd) { + +} + +struct time utc2et(struct time d) { + +} + +int datecmp(struct date a, struct date b) { + if (a.year == b.year) { + if (a.month == b.month) { + if (a.day == b.day) return 0; + else return a.day - b.day; + } + else return a.month - b.month; + } + else return a.year - b.year; +} diff --git a/src/calendar.h b/src/calendar.h new file mode 100644 index 0000000..dd24cc1 --- /dev/null +++ b/src/calendar.h @@ -0,0 +1,176 @@ +/** + * Time and Calender calculus + * + * based on Practical astronomy with your calculator or spreadsheet + * from Peter Duffett-Smith, Jonathan Zwart. – 4th ed. (Cambridge University Press, 2011) + * + * @copyright 2012 Steffen Vogel + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + * @author Arnold Barmettler + * @link http://www.steffenvogel.de + */ +/* + * This file is part of libastro + * + * libastro is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * libastro is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libastro. If not, see . + */ + + +/* TODO +christliche Feiertage +Advent +Sommer/Frühlings/Herbstanfang +Längster/Kürzester Tag +Vollmond +*/ + +#ifndef _TIME_H_ +#define _TIME_H_ + +#include +#include + +/** Types */ +struct date { + int day; + int month; + int year; +}; + +struct time { + int second; + int minute; + int hour; +}; + +/* helper to convert libastro types to struct tm */ +struct tma { + struct time time; + struct date date; + int wday; /* day of the week */ + int yday; /* day in the year */ + int isdst; /* daylight saving time */ +}; + +union datetime { + struct tma libastro; + struct tm posix; +}; + +enum weekday { + MONDAY, TUESDAY, WEDNESDAY, + THURSDAY, FRIDAY, SATURDAY, SUNDAY +}; + +enum holiday { + EASTER_SUNDAY, + CHRISTMAS, + ADVENT_1, ADVENT_2, ADVENT_3, ADVENT_4, + SILVESTER, NEWYEAR +}; + +/** Prototypes */ + +/** Helper functions */ +double frac(double x); + +/** + * Compare to dates like strcmp() + */ +int datecmp(struct date a, struct date b); + +struct date dateadd(struct date a, struct date b); + + +struct date holiday(struct date d, enum holiday type); + +/** + * Calculate the date of eastern + * + * @see http://de.wikipedia.org/wiki/Gau%C3%9Fsche_Osterformel + */ +struct date eastern(int year); + +/** + * Checks if year is a leapyear + */ +bool leapyear(int year); + +/** + * Calculate the daynumber of a gregorian date + * e.g the number of days after 1.1. of the current year + */ +int daynumber(struct date d); + +/** + * Calculate the weeknumber of a gregorian date + * + * according to DIN1355 + */ +int weeknumber(struct date d); + +/** + * Return english weekday name + */ +int weekday(struct date d); + +/** + * Return sign + */ +const char * sign(struct date d, int mode); + +/** + * Convert a gregorian date to a julian date + */ +int gregorian2julian(struct date d); +struct date julian2gregorian(int jd); + +/** + * Convert HH:MM:SS to decimal day + */ +double hms2decimal(struct time t); +struct time decimal2hms(double decimal); + +/** + * Universial to Local Time + */ +//utc2local(struct date, int zone); + +/** + * Universal to Greenwich Sidereal Time + */ +//utc2gmst(); + +/** + * Greenwich Sidereal to Universal Time + */ +//gmst2utc(); + +/** + * Local Sidereal to Univeral Time + */ +//lmst2utc(); + +/** + * Universal to Terrestrial (dynamic) Time + */ +//utc2tdt(utc); + +/** + * Ephimeris Time + */ +//struct time utc2et(struct time d); + +#endif /* _TIME_H_ */