Created
March 25, 2012 20:06
-
-
Save jbedo/2199439 to your computer and use it in GitHub Desktop.
Local solar time clock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<u.h> | |
#include<libc.h> | |
#define MIN /60.0 | |
#define DEG * 2 * PI / 360.0 | |
#define RAD * 360.0 / (2 * PI) | |
double longitude = 2.0 + 20.0 MIN; | |
const double Eccentricity = 0.0167; | |
const double Obliquity = 23.44; | |
/* Adjusts a time structure by delta min */ | |
void | |
correct(Tm *t, double delta) | |
{ | |
int hours, min, sec; | |
hours = delta / 60; | |
min = delta - hours * 60; | |
sec = (delta - (int)delta) * 60; | |
t->sec += sec; | |
if(t->sec >= 60) t->sec -= 60, t->min++; | |
if(t->sec < 0) t->sec += 60, t->min--; | |
t->min += min; | |
if(t->min >= 60) t->min -= 60, t->hour++; | |
if(t->min < 0) t->min += 60, t->hour--; | |
t->hour += hours; | |
if(t->hour >= 24) t->hour -= 24; | |
if(t->hour < 0) t->hour += 24; | |
} | |
double | |
dsin(double x) | |
{ | |
return sin(x DEG); | |
} | |
double | |
dcos(double x) | |
{ | |
return cos(x DEG); | |
} | |
double | |
dtan(double x) | |
{ | |
return tan(x DEG); | |
} | |
double | |
datan(double x) | |
{ | |
return atan(x) RAD; | |
} | |
/* Hex formatter */ | |
#pragma varargck type "H" Tm* | |
int | |
hexfmt(Fmt *f) | |
{ | |
int hours, min, sec; | |
uint time; | |
Tm *t; | |
t = va_arg(f->args, Tm *); | |
time = 0.5+(float)0x10000 * ((float)t->hour + (float)t->min / 60.0 + (float)t->sec / (60.0 * 60.0)) / 24.0; | |
hours = time / 0x1000; | |
min = time % 0x1000 / 0x10; | |
sec = time % 0x10; | |
return fmtprint(f, "%01X_%02X_%01X", hours, min, sec); | |
} | |
/* Duodecimal formatter */ | |
#pragma varargck type "D" Tm* | |
int | |
duofmt(Fmt *f) | |
{ | |
Tm *t; | |
t = va_arg(f->args, Tm*); | |
return fmtprint(f, "%02d:%02d:%02d", t->hour, t->min, t->sec); | |
} | |
void | |
usage(void) | |
{ | |
fprint(2, "%s: [-l longitude] [-xf]\n", argv0); | |
exits("usage"); | |
} | |
void | |
main(int argc, char *argv[]) | |
{ | |
Tm *t; | |
int hex, follow; | |
char *fmt; | |
fmt = "%D\n"; | |
hex = 0; | |
follow = 0; | |
double w, a, b, c, eot; | |
ARGBEGIN{ | |
case 'l': | |
longitude = atof(EARGF(usage())); | |
break; | |
case 'x': | |
fmt = "%H\n"; | |
hex++; | |
break; | |
case 'f': | |
follow++; | |
break; | |
case 'h': | |
default: | |
usage(); | |
}ARGEND; | |
if(argc != 0) | |
usage(); | |
fmtinstall('H', hexfmt); | |
fmtinstall('D', duofmt); | |
beginning: | |
/* Get local mean time */ | |
t = gmtime(time(0)); | |
correct(t, longitude * 4.0); | |
/* Calculate equation of time */ | |
w = 360 / 365.24; // Mean angular orbit velocity | |
a = w * (t->yday + 10); // angular orbital distance from solstice (10 days befor jan 1) | |
b = a + (360 / PI) * Eccentricity * dsin(w * (t->yday - 2)); // angular deflection of earth | |
c = (a - datan(dtan(b) / dcos(Obliquity))) / 180; // Difference between mean and corrected angles | |
eot = 720 * (c - floor(c + 0.5)); | |
/* Alternative formulation */ | |
/* w = 2 * PI * (t->yday - 1) / 365.242; | |
eot = 0.258 * cos(w) - 7.416 * sin(w) - 3.648 * cos(2 * w) - 9.228 * sin(2 * w);*/ | |
//print("%f\n", eot); | |
correct(t, -eot); | |
print(fmt, t); | |
if(follow){ | |
sleep(hex ? (1000 / 0.76) : 1000); | |
goto beginning; | |
} | |
exits(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment