initial commit
This commit is contained in:
commit
5cccbf6783
11 changed files with 466 additions and 0 deletions
1
AUTHORS
Normal file
1
AUTHORS
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Steffen Vogel <post@steffenvogel.de>
|
0
ChangeLog
Normal file
0
ChangeLog
Normal file
1
INSTALL
Symbolic link
1
INSTALL
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/usr/share/automake-1.11/INSTALL
|
3
Makefile.am
Normal file
3
Makefile.am
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
SUBDIRS = src
|
||||||
|
|
||||||
|
dist_doc_DATA = README
|
0
NEWS
Normal file
0
NEWS
Normal file
1
README
Normal file
1
README
Normal file
|
@ -0,0 +1 @@
|
||||||
|
libastro is a collection of functions for time, date and ephemeris calculus
|
29
configure.ac
Normal file
29
configure.ac
Normal 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
4
src/Makefile.am
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
bin_PROGRAMS = astro
|
||||||
|
|
||||||
|
astro_SOURCES = calendar.c astro.c
|
||||||
|
astro_LDADD = -lm
|
48
src/astro.c
Normal file
48
src/astro.c
Normal 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
203
src/calendar.c
Normal 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
176
src/calendar.h
Normal 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_ */
|
Loading…
Add table
Reference in a new issue