mirror of https://github.com/ecmwf/eccodes.git
194 lines
4.3 KiB
C
194 lines
4.3 KiB
C
/*
|
|
* Copyright 2005-2018 ECMWF.
|
|
*
|
|
* This software is licensed under the terms of the Apache Licence Version 2.0
|
|
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
*
|
|
* In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
|
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
|
*/
|
|
|
|
/***************************************************************************
|
|
* Enrico Fucile *
|
|
* *
|
|
***************************************************************************/
|
|
#include "grib_api_internal.h"
|
|
|
|
#define ROUND(a) ((a) >=0 ? (long)((a)+0.5) : (long) ((a)-0.5))
|
|
int grib_julian_to_datetime(double jd,long *year,long* month,long* day,
|
|
long *hour,long *minute,long *second)
|
|
{
|
|
long z,a,alpha,b,c,d,e;
|
|
double dday;
|
|
double f;
|
|
long s;
|
|
|
|
jd+=0.5;
|
|
z=(long)jd;
|
|
f=jd-z;
|
|
|
|
if (z < 2299161) a=z;
|
|
else {
|
|
alpha=(long)((z-1867216.25)/36524.25);
|
|
a=z+1+alpha-(long)(((double)alpha)/4);
|
|
}
|
|
b=a+1524;
|
|
c=(long)((b-122.1)/365.25);
|
|
d=(long)(365.25*c);
|
|
e=(long)(((double)(b-d))/30.6001);
|
|
|
|
dday=b-d-(long)(30.6001*e)+f;
|
|
*day=(long)dday;
|
|
dday-=*day;
|
|
|
|
#if 1
|
|
/* ANF-CG 02.03.2012 */
|
|
s=ROUND((double)(dday*86400)); /* total in sec , no msec*/
|
|
*hour=(long)s/3600;
|
|
*minute=(long)((s % 3600)/60);
|
|
*second = (long)(s % 60);
|
|
#else
|
|
/* Old algorithm, now replaced by above. See GRIB-180 */
|
|
dhour=dday*24;
|
|
*hour=(long)dhour;
|
|
dhour-=*hour;
|
|
dminute=dhour*60;
|
|
*minute=(long)dminute;
|
|
*second=(long)((dminute-*minute)*60);
|
|
#endif
|
|
|
|
if (e<14) *month=e-1;
|
|
else *month=e-13;
|
|
|
|
if (*month>2) *year=c-4716;
|
|
else *year=c-4715;
|
|
|
|
return GRIB_SUCCESS;
|
|
}
|
|
|
|
int grib_datetime_to_julian(long year,long month,long day,
|
|
long hour,long minute,long second,double* jd)
|
|
{
|
|
return grib_datetime_to_julian_d(year,month,day,hour,minute,second,jd);
|
|
}
|
|
|
|
/* This version can deal with seconds provided as a double. Supporting milliseconds etc */
|
|
int grib_datetime_to_julian_d(
|
|
long year,long month,long day,long hour,long minute,
|
|
double second, double* jd)
|
|
{
|
|
double a,b,dday;
|
|
long y,m;
|
|
|
|
dday=(double)(hour*3600+minute*60+second)/86400.0+day;
|
|
|
|
if ( month < 3) {
|
|
y=year-1;
|
|
m=month+12;
|
|
} else {
|
|
y=year;
|
|
m=month;
|
|
}
|
|
a=(long)(((double)y)/100);
|
|
|
|
if ( y > 1582 ) b=2-a+(long)(a/4);
|
|
else if (y == 1582) {
|
|
if (m > 10) b=2-a+(long)(a/4);
|
|
else if (m == 10) {
|
|
if (day >14) b=2-a+(long)(a/4);
|
|
else b=0;
|
|
}
|
|
else b=0;
|
|
}
|
|
else b=0;
|
|
|
|
*jd=(long)(365.25*(y+4716))+ (long)(30.6001*(m+1))+dday+b-1524.5;
|
|
|
|
return GRIB_SUCCESS;
|
|
}
|
|
|
|
long grib_julian_to_date(long jdate)
|
|
{
|
|
long x,y,d,m,e;
|
|
long day,month,year;
|
|
|
|
x = 4 * jdate - 6884477;
|
|
y = (x / 146097) * 100;
|
|
e = x % 146097;
|
|
d = e / 4;
|
|
|
|
x = 4 * d + 3;
|
|
y = (x / 1461) + y;
|
|
e = x % 1461;
|
|
d = e / 4 + 1;
|
|
|
|
x = 5 * d - 3;
|
|
m = x / 153 + 1;
|
|
e = x % 153;
|
|
d = e / 5 + 1;
|
|
|
|
if( m < 11 )
|
|
month = m + 2;
|
|
else
|
|
month = m - 10;
|
|
|
|
day = d;
|
|
year = y + m / 11;
|
|
|
|
return year * 10000 + month * 100 + day;
|
|
}
|
|
|
|
long grib_date_to_julian(long ddate)
|
|
{
|
|
long m1,y1,a,b,c,d,j1;
|
|
|
|
long month,day,year;
|
|
|
|
/*Asserts(ddate > 0);*/
|
|
|
|
year = ddate / 10000;
|
|
ddate %= 10000;
|
|
month = ddate / 100;
|
|
ddate %= 100;
|
|
day = ddate;
|
|
|
|
/* if (year < 100) year = year + 1900; */
|
|
|
|
if (month > 2)
|
|
{
|
|
m1 = month - 3;
|
|
y1 = year;
|
|
}
|
|
else
|
|
{
|
|
m1 = month + 9;
|
|
y1 = year - 1;
|
|
}
|
|
a = 146097*(y1/100)/4;
|
|
d = y1 % 100;
|
|
b = 1461*d/4;
|
|
c = (153*m1+2)/5+day+1721119;
|
|
j1 = a+b+c;
|
|
|
|
return(j1);
|
|
}
|
|
|
|
/*
|
|
void basedate_to_verifydate(gribsec1 *s1,request *r)
|
|
{
|
|
int bdate,vdate,cdate,vd,vtime,vstep;
|
|
|
|
bdate = (s1->century-1)*1000000 + s1->year * 10000 + s1->month * 100 + s1->day;
|
|
cdate = date_to_julian (bdate);
|
|
vtime = cdate * 24 + s1->p1*units[s1->time_unit];
|
|
vd = vtime / 24;
|
|
vdate = julian_to_date (vd,mars.y2k);
|
|
vtime = vtime % 24;
|
|
vstep = 0;
|
|
|
|
set_value(r,"DATE","%d",vdate);
|
|
set_value(r,"TIME","%02d00",vtime);
|
|
set_value(r,"STEP","%d",vstep);
|
|
}
|
|
*/
|