initial commit

This commit is contained in:
Steffen Vogel 2012-11-22 18:58:01 +01:00
commit 5cccbf6783
11 changed files with 466 additions and 0 deletions

1
AUTHORS Normal file
View File

@ -0,0 +1 @@
Steffen Vogel <post@steffenvogel.de>

0
ChangeLog Normal file
View File

1
INSTALL Symbolic link
View File

@ -0,0 +1 @@
/usr/share/automake-1.11/INSTALL

3
Makefile.am Normal file
View File

@ -0,0 +1,3 @@
SUBDIRS = src
dist_doc_DATA = README

0
NEWS Normal file
View File

1
README Normal file
View File

@ -0,0 +1 @@
libastro is a collection of functions for time, date and ephemeris calculus

29
configure.ac Normal file
View File

@ -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

4
src/Makefile.am Normal file
View File

@ -0,0 +1,4 @@
bin_PROGRAMS = astro
astro_SOURCES = calendar.c astro.c
astro_LDADD = -lm

48
src/astro.c Normal file
View File

@ -0,0 +1,48 @@
#include <stdio.h>
#include <time.h>
#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;
}

203
src/calendar.c Normal file
View File

@ -0,0 +1,203 @@
#include <math.h>
#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;
}

176
src/calendar.h Normal file
View File

@ -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 <post@steffenvogel.de>
* @author Arnold Barmettler <barmettler@astronomie.info>
* @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 <http://www.gnu.org/licenses/>.
*/
/* TODO
christliche Feiertage
Advent
Sommer/Frühlings/Herbstanfang
Längster/Kürzester Tag
Vollmond
*/
#ifndef _TIME_H_
#define _TIME_H_
#include <stdbool.h>
#include <time.h>
/** 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_ */