pdate.c 4.4 KB

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