pdate.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. #include "astro.h"
  2. char* month[] =
  3. {
  4. "January",
  5. "February",
  6. "March",
  7. "April",
  8. "May",
  9. "June",
  10. "July",
  11. "August",
  12. "September",
  13. "October",
  14. "November",
  15. "December",
  16. };
  17. double
  18. dsrc(double d, Tim *t, int i)
  19. {
  20. double y;
  21. do {
  22. t->ifa[i] += 1.;
  23. y = convdate(t);
  24. } while(d >= y);
  25. do {
  26. t->ifa[i] -= 1.;
  27. y = convdate(t);
  28. } while(d < y);
  29. return d - y;
  30. }
  31. void
  32. dtsetup(double d, Tim *t)
  33. {
  34. double v;
  35. t->ifa[0] = floor(1900 + d/365.24220);
  36. t->ifa[1] = 1;
  37. t->ifa[2] = 1;
  38. t->ifa[3] = 0;
  39. t->ifa[4] = 0;
  40. t->ifa[1] = floor(1 + dsrc(d, t, 0)/30);
  41. t->ifa[2] = floor(1 + dsrc(d, t, 1));
  42. dsrc(d, t, 2);
  43. v = (d - convdate(t)) * 24;
  44. t->ifa[3] = floor(v);
  45. t->ifa[4] = (v - t->ifa[3]) * 60;
  46. convdate(t); /* to set timezone */
  47. }
  48. void
  49. pdate(double d)
  50. {
  51. int i;
  52. Tim t;
  53. dtsetup(d, &t);
  54. if(flags['s']) {
  55. i = t.ifa[1];
  56. print("%s ", month[i-1]);
  57. i = t.ifa[2];
  58. numb(i);
  59. print("...");
  60. return;
  61. }
  62. /* year month day */
  63. print("%4d %2d %2d",
  64. (int)t.ifa[0],
  65. (int)t.ifa[1],
  66. (int)t.ifa[2]);
  67. }
  68. void
  69. ptime(double d)
  70. {
  71. int h, m, s;
  72. char *mer;
  73. Tim t;
  74. if(flags['s']) {
  75. /* hour minute */
  76. dtsetup(d + .5/(24*60), &t);
  77. h = t.ifa[3];
  78. m = floor(t.ifa[4]);
  79. mer = "AM";
  80. if(h >= 12) {
  81. mer = "PM";
  82. h -= 12;
  83. }
  84. if(h == 0)
  85. h = 12;
  86. numb(h);
  87. if(m < 10) {
  88. if(m == 0) {
  89. print("%s exactly ...", mer);
  90. return;
  91. }
  92. print("O ");
  93. }
  94. numb(m);
  95. print("%s ...", mer);
  96. return;
  97. }
  98. /* hour minute second */
  99. dtsetup(d, &t);
  100. h = t.ifa[3];
  101. m = floor(t.ifa[4]);
  102. s = floor((t.ifa[4]-m) * 60);
  103. print("%.2d:%.2d:%.2d %.*s", h, m, s, utfnlen(t.tz, 3), t.tz);
  104. }
  105. char* unit[] =
  106. {
  107. "zero",
  108. "one",
  109. "two",
  110. "three",
  111. "four",
  112. "five",
  113. "six",
  114. "seven",
  115. "eight",
  116. "nine",
  117. "ten",
  118. "eleven",
  119. "twelve",
  120. "thirteen",
  121. "fourteen",
  122. "fifteen",
  123. "sixteen",
  124. "seventeen",
  125. "eighteen",
  126. "nineteen"
  127. };
  128. char* decade[] =
  129. {
  130. "twenty",
  131. "thirty",
  132. "forty",
  133. "fifty",
  134. "sixty",
  135. "seventy",
  136. "eighty",
  137. "ninety"
  138. };
  139. void
  140. pstime(double d)
  141. {
  142. setime(d);
  143. semi = 0;
  144. motion = 0;
  145. rad = 1.e9;
  146. lambda = 0;
  147. beta = 0;
  148. // uses lambda, beta, rad, motion
  149. // sets alpha, delta, rp
  150. helio();
  151. // uses alpha, delta, rp
  152. // sets ra, decl, lha, decl2, az, el
  153. geo();
  154. print(" %R %D %D %4.0f", lha, nlat, awlong, elev/3.28084);
  155. }
  156. void
  157. numb(int n)
  158. {
  159. if(n >= 100) {
  160. print("%d ", n);
  161. return;
  162. }
  163. if(n >= 20) {
  164. print("%s ", decade[n/10 - 2]);
  165. n %= 10;
  166. if(n == 0)
  167. return;
  168. }
  169. print("%s ", unit[n]);
  170. }
  171. double
  172. tzone(double y, Tim *z)
  173. {
  174. double t, l1, l2;
  175. Tm t1, t2;
  176. /*
  177. * get a rough approximation to unix mean time
  178. */
  179. t = (y - 25567.5) * 86400;
  180. /*
  181. * if outside unix conversions,
  182. * just call it GMT
  183. */
  184. if(t < 0 || t > 2.1e9)
  185. return y;
  186. /*
  187. * convert by both local and gmt
  188. */
  189. t1 = *localtime((long)t);
  190. t2 = *gmtime((long)t);
  191. /*
  192. * pick up year crossings
  193. */
  194. if(t1.yday == 0 && t2.yday > 1)
  195. t1.yday = t2.yday+1;
  196. if(t2.yday == 0 && t1.yday > 1)
  197. t2.yday = t1.yday+1;
  198. /*
  199. * convert times to days
  200. */
  201. l1 = t1.yday + t1.hour/24. + t1.min/1440. + t1.sec/86400.;
  202. l2 = t2.yday + t2.hour/24. + t2.min/1440. + t2.sec/86400.;
  203. /*
  204. * return difference
  205. */
  206. strncpy(z->tz, t1.zone, sizeof(z->tz));
  207. return y + (l2 - l1);
  208. }
  209. int dmo[12] =
  210. {
  211. 0,
  212. 31,
  213. 59,
  214. 90,
  215. 120,
  216. 151,
  217. 181,
  218. 212,
  219. 243,
  220. 273,
  221. 304,
  222. 334
  223. };
  224. /*
  225. * input date conversion
  226. * output is done by zero crossing
  227. * on this input conversion.
  228. */
  229. double
  230. convdate(Tim *t)
  231. {
  232. double y, d;
  233. int m;
  234. y = t->ifa[0];
  235. m = t->ifa[1];
  236. d = t->ifa[2];
  237. /*
  238. * normalize the month
  239. */
  240. while(m < 1) {
  241. m += 12;
  242. y -= 1;
  243. }
  244. while(m > 12) {
  245. m -= 12;
  246. y += 1;
  247. }
  248. /*
  249. * bc correction
  250. */
  251. if(y < 0)
  252. y += 1;
  253. /*
  254. * normal conversion
  255. */
  256. y += 4712;
  257. if(fmod(y, 4) == 0 && m > 2)
  258. d += 1;
  259. y = y*365 + floor((y+3)/4) + dmo[m-1] + d - 1;
  260. /*
  261. * gregorian change
  262. */
  263. if(y > 2361232)
  264. y -= floor((y-1794167)/36524.220) -
  265. floor((y-1721117)/146100);
  266. y += t->ifa[3]/24 + t->ifa[4]/1440 - 2415020.5;
  267. /*
  268. * kitchen clock correction
  269. */
  270. strncpy(t->tz, "GMT", sizeof(t->tz));
  271. if(flags['k'])
  272. y = tzone(y, t);
  273. return y;
  274. }