1 /*
2  * (C) Copyright 2005- ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  *
7  * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
8  * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
9  */
10 
11 /***************************************************************************
12  *   Enrico Fucile                                                            *
13  *                                                                         *
14  ***************************************************************************/
15 #include "grib_api_internal.h"
16 
17 #define ROUND(a) ((a) >= 0 ? (long)((a) + 0.5) : (long)((a)-0.5))
grib_julian_to_datetime(double jd,long * year,long * month,long * day,long * hour,long * minute,long * second)18 int grib_julian_to_datetime(double jd, long* year, long* month, long* day,
19                             long* hour, long* minute, long* second)
20 {
21     long z, a, alpha, b, c, d, e;
22     double dday;
23     double f;
24     long s;
25 
26     jd += 0.5;
27     z = (long)jd;
28     f = jd - z;
29 
30     if (z < 2299161)
31         a = z;
32     else {
33         alpha = (long)((z - 1867216.25) / 36524.25);
34         a     = z + 1 + alpha - (long)(((double)alpha) / 4);
35     }
36     b = a + 1524;
37     c = (long)((b - 122.1) / 365.25);
38     d = (long)(365.25 * c);
39     e = (long)(((double)(b - d)) / 30.6001);
40 
41     dday = b - d - (long)(30.6001 * e) + f;
42     *day = (long)dday;
43     dday -= *day;
44 
45 #if 1
46     /* ANF-CG 02.03.2012 */
47     s       = ROUND((double)(dday * 86400)); /* total in sec , no msec*/
48     *hour   = (long)s / 3600;
49     *minute = (long)((s % 3600) / 60);
50     *second = (long)(s % 60);
51 #else
52     /* Old algorithm, now replaced by above. See GRIB-180 */
53     dhour = dday * 24;
54     *hour = (long)dhour;
55     dhour -= *hour;
56     dminute = dhour * 60;
57     *minute = (long)dminute;
58     *second = (long)((dminute - *minute) * 60);
59 #endif
60 
61     if (e < 14)
62         *month = e - 1;
63     else
64         *month = e - 13;
65 
66     if (*month > 2)
67         *year = c - 4716;
68     else
69         *year = c - 4715;
70 
71     return GRIB_SUCCESS;
72 }
73 
grib_datetime_to_julian(long year,long month,long day,long hour,long minute,long second,double * jd)74 int grib_datetime_to_julian(long year, long month, long day,
75                             long hour, long minute, long second, double* jd)
76 {
77     return grib_datetime_to_julian_d(year, month, day, hour, minute, second, jd);
78 }
79 
80 /* This version can deal with seconds provided as a double. Supporting milliseconds etc */
grib_datetime_to_julian_d(long year,long month,long day,long hour,long minute,double second,double * jd)81 int grib_datetime_to_julian_d(
82     long year, long month, long day, long hour, long minute,
83     double second, double* jd)
84 {
85     double a, b = 0, dday;
86     long y, m;
87 
88     dday = (double)(hour * 3600 + minute * 60 + second) / 86400.0 + day;
89 
90     if (month < 3) {
91         y = year - 1;
92         m = month + 12;
93     }
94     else {
95         y = year;
96         m = month;
97     }
98     a = (long)(((double)y) / 100);
99 
100     if (y > 1582 ||
101         (y == 1582 && ((m > 10) || (m == 10 && day > 14)))) {
102         b = 2 - a + (long)(a / 4);
103     }
104 
105     *jd = (long)(365.25 * (y + 4716)) + (long)(30.6001 * (m + 1)) + dday + b - 1524.5;
106 
107     return GRIB_SUCCESS;
108 }
109 
grib_julian_to_date(long jdate)110 long grib_julian_to_date(long jdate)
111 {
112     long x, y, d, m, e;
113     long day, month, year;
114 
115     x = 4 * jdate - 6884477;
116     y = (x / 146097) * 100;
117     e = x % 146097;
118     d = e / 4;
119 
120     x = 4 * d + 3;
121     y = (x / 1461) + y;
122     e = x % 1461;
123     d = e / 4 + 1;
124 
125     x = 5 * d - 3;
126     m = x / 153 + 1;
127     e = x % 153;
128     d = e / 5 + 1;
129 
130     if (m < 11)
131         month = m + 2;
132     else
133         month = m - 10;
134 
135     day  = d;
136     year = y + m / 11;
137 
138     return year * 10000 + month * 100 + day;
139 }
140 
grib_date_to_julian(long ddate)141 long grib_date_to_julian(long ddate)
142 {
143     long m1, y1, a, b, c, d, j1;
144 
145     long month, day, year;
146 
147     /*Asserts(ddate > 0);*/
148 
149     year = ddate / 10000;
150     ddate %= 10000;
151     month = ddate / 100;
152     ddate %= 100;
153     day = ddate;
154 
155     /*  if (year < 100) year = year + 1900; */
156 
157     if (month > 2) {
158         m1 = month - 3;
159         y1 = year;
160     }
161     else {
162         m1 = month + 9;
163         y1 = year - 1;
164     }
165     a  = 146097 * (y1 / 100) / 4;
166     d  = y1 % 100;
167     b  = 1461 * d / 4;
168     c  = (153 * m1 + 2) / 5 + day + 1721119;
169     j1 = a + b + c;
170 
171     return (j1);
172 }
173 
174 /*
175    void basedate_to_verifydate(gribsec1 *s1,request *r)
176    {
177    int bdate,vdate,cdate,vd,vtime,vstep;
178 
179    bdate = (s1->century-1)*1000000 + s1->year * 10000 + s1->month * 100 + s1->day;
180    cdate = date_to_julian (bdate);
181    vtime = cdate * 24 + s1->p1*units[s1->time_unit];
182    vd    = vtime / 24;
183    vdate = julian_to_date (vd,mars.y2k);
184    vtime = vtime % 24;
185    vstep = 0;
186 
187    set_value(r,"DATE","%d",vdate);
188    set_value(r,"TIME","%02d00",vtime);
189    set_value(r,"STEP","%d",vstep);
190    }
191  */
192