PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/wrfv2_fire/external/io_grib1/WGRIB/PDS_date.c

http://github.com/jbeezley/wrf-fire
C | 213 lines | 147 code | 31 blank | 35 comment | 60 complexity | 4c92b20becab5af625175e89ba2ad42d MD5 | raw file
Possible License(s): AGPL-1.0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4. #include <string.h>
  5. #include "pds4.h"
  6. #include "grib.h"
  7. /*
  8. * PDS_date.c v1.2 wesley ebisuzaki
  9. *
  10. * prints a string with a date code
  11. *
  12. * PDS_date(pds,option, v_time)
  13. * options=0 .. 2 digit year
  14. * options=1 .. 4 digit year
  15. *
  16. * v_time=0 .. initial time
  17. * v_time=1 .. verification time
  18. *
  19. * assumption: P1 and P2 are unsigned integers (not clear from doc)
  20. *
  21. * v1.2 years that are multiple of 400 are leap years, not 500
  22. * v1.2.1 make the change to the source code for v1.2
  23. * v1.2.2 add 3/6/12 hour forecast time units
  24. */
  25. static int msg_count = 0;
  26. extern int minute;
  27. int PDS_date(unsigned char *pds, int option, int v_time) {
  28. int year, month, day, hour, min;
  29. if (v_time == 0) {
  30. year = PDS_Year4(pds);
  31. month = PDS_Month(pds);
  32. day = PDS_Day(pds);
  33. hour = PDS_Hour(pds);
  34. }
  35. else {
  36. if (verf_time(pds, &year, &month, &day, &hour) != 0) {
  37. if (msg_count++ < 5) fprintf(stderr, "PDS_date: problem\n");
  38. }
  39. }
  40. min = PDS_Minute(pds);
  41. switch(option) {
  42. case 0:
  43. printf("%2.2d%2.2d%2.2d%2.2d", year % 100, month, day, hour);
  44. if (minute) printf("-%2.2d", min);
  45. break;
  46. case 1:
  47. printf("%4.4d%2.2d%2.2d%2.2d", year, month, day, hour);
  48. if (minute) printf("-%2.2d", min);
  49. break;
  50. default:
  51. fprintf(stderr,"missing code\n");
  52. exit(8);
  53. }
  54. return 0;
  55. }
  56. #define FEB29 (31+29)
  57. static int monthjday[12] = {
  58. 0,31,59,90,120,151,181,212,243,273,304,334};
  59. static int leap(int year) {
  60. if (year % 4 != 0) return 0;
  61. if (year % 100 != 0) return 1;
  62. return (year % 400 == 0);
  63. }
  64. int add_time(int *year, int *month, int *day, int *hour, int dtime, int unit) {
  65. int y, m, d, h, jday, i;
  66. y = *year;
  67. m = *month;
  68. d = *day;
  69. h = *hour;
  70. if (unit == YEAR) {
  71. *year = y + dtime;
  72. return 0;
  73. }
  74. if (unit == DECADE) {
  75. *year = y + (10 * dtime);
  76. return 0;
  77. }
  78. if (unit == CENTURY) {
  79. *year = y + (100 * dtime);
  80. return 0;
  81. }
  82. if (unit == NORMAL) {
  83. *year = y + (30 * dtime);
  84. return 0;
  85. }
  86. if (unit == MONTH) {
  87. dtime += (m - 1);
  88. *year = y + (dtime / 12);
  89. *month = 1 + (dtime % 12);
  90. return 0;
  91. }
  92. if (unit == SECOND) {
  93. dtime /= 60;
  94. unit = MINUTE;
  95. }
  96. if (unit == MINUTE) {
  97. dtime /= 60;
  98. unit = HOUR;
  99. }
  100. if (unit == HOURS3) {
  101. dtime *= 3;
  102. unit = HOUR;
  103. }
  104. else if (unit == HOURS6) {
  105. dtime *= 6;
  106. unit = HOUR;
  107. }
  108. else if (unit == HOURS12) {
  109. dtime *= 12;
  110. unit = HOUR;
  111. }
  112. if (unit == HOUR) {
  113. dtime += h;
  114. *hour = dtime % 24;
  115. dtime = dtime / 24;
  116. unit = DAY;
  117. }
  118. /* this is the hard part */
  119. if (unit == DAY) {
  120. /* set m and day to Jan 0, and readjust dtime */
  121. jday = d + monthjday[m-1];
  122. if (leap(y) && m > 2) jday++;
  123. dtime += jday;
  124. /* 4 year chuncks */
  125. i = dtime / (4 * 365 + 1);
  126. if (i) {
  127. /* assume century years are leap */
  128. y = y + i*4;
  129. dtime -= i*(4 * 365 + 1);
  130. /* see if we have gone past feb 28, 1900, 2000, etc */
  131. if ((y - 1) / 100 != (*year-1) / 100) {
  132. /* crossed the feb 28, xx00 */
  133. /* correct for only one century mark */
  134. if ((y / 100) % 4 != 0) dtime++;
  135. }
  136. }
  137. /* one year chunks */
  138. while (dtime > 365 + leap(y)) {
  139. dtime -= (365 + leap(y));
  140. y++;
  141. }
  142. /* calculate the month and day */
  143. if (leap(y) && dtime == FEB29) {
  144. m = 2;
  145. d = 29;
  146. }
  147. else {
  148. if (leap(y) && dtime > FEB29) dtime--;
  149. for (i = 11; monthjday[i] >= dtime; --i);
  150. m = i + 1;
  151. d = dtime - monthjday[i];
  152. }
  153. *year = y;
  154. *month = m;
  155. *day = d;
  156. return 0;
  157. }
  158. fprintf(stderr,"add_time: undefined time unit %d\n", unit);
  159. return 1;
  160. }
  161. /*
  162. * verf_time:
  163. *
  164. * this routine returns the "verification" time
  165. * should have behavior similar to gribmap
  166. *
  167. */
  168. int verf_time(unsigned char *pds, int *year, int *month, int *day, int *hour) {
  169. int tr, dtime, unit;
  170. *year = PDS_Year4(pds);
  171. *month = PDS_Month(pds);
  172. *day = PDS_Day(pds);
  173. *hour = PDS_Hour(pds);
  174. /* find time increment */
  175. dtime = PDS_P1(pds);
  176. tr = PDS_TimeRange(pds);
  177. unit = PDS_ForecastTimeUnit(pds);
  178. if (tr == 10) dtime = PDS_P1(pds) * 256 + PDS_P2(pds);
  179. if (tr > 1 && tr < 6 ) dtime = PDS_P2(pds);
  180. if (dtime == 0) return 0;
  181. return add_time(year, month, day, hour, dtime, unit);
  182. }