2013-03-25 12:04:10 +00:00
|
|
|
/*
|
2020-01-28 14:32:34 +00:00
|
|
|
* (C) Copyright 2005- ECMWF.
|
2013-03-25 12:04:10 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2022-07-29 12:21:04 +00:00
|
|
|
#include "grib_api_internal.h"
|
2023-12-16 12:53:34 +00:00
|
|
|
#include "eccodes.h"
|
2013-03-25 12:04:10 +00:00
|
|
|
|
|
|
|
#define EPSILON 1e-12
|
2020-01-29 12:05:02 +00:00
|
|
|
#define DBL_EQUAL(a, b) (fabs((a) - (b)) <= (EPSILON)*fabs((a)))
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2024-02-28 13:54:02 +00:00
|
|
|
static bool Check(
|
2020-01-29 12:05:02 +00:00
|
|
|
const long year1, const long month1, const long day1, const long hour1, const long min1, const long sec1,
|
|
|
|
const long year2, const long month2, const long day2, const long hour2, const long min2, const long sec2)
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2013-09-23 14:56:08 +00:00
|
|
|
if (year1 != year2 || month1 != month2 || day1 != day2 || hour1 != hour2 || min1 != min2 || sec1 != sec2) {
|
2024-02-28 13:54:02 +00:00
|
|
|
return false;
|
2013-09-23 14:56:08 +00:00
|
|
|
}
|
2024-02-28 13:54:02 +00:00
|
|
|
return true;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2017-08-25 16:30:00 +00:00
|
|
|
static void TestDateTime(const long year, const long month, const long day, const long hour, const long min, const long sec)
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2013-09-23 14:56:08 +00:00
|
|
|
double jd = 0.0;
|
|
|
|
long year1, month1, day1, hour1, min1, sec1; /*generated ones*/
|
|
|
|
long jdlong1, jdlong2, date;
|
|
|
|
|
|
|
|
/* Convert the input values to a double */
|
2023-12-16 12:53:34 +00:00
|
|
|
codes_datetime_to_julian(year, month, day, hour, min, sec, &jd);
|
2013-09-23 14:56:08 +00:00
|
|
|
|
|
|
|
/* Convert the double back to the input values and compare */
|
2023-12-16 12:53:34 +00:00
|
|
|
codes_julian_to_datetime(jd, &year1, &month1, &day1, &hour1, &min1, &sec1);
|
2013-09-23 14:56:08 +00:00
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
if (!Check(year, month, day, hour, min, sec, year1, month1, day1, hour1, min1, sec1)) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"Failed julian<->datetime\nInput: year=%ld mon=%ld day=%ld time=%ld:%ld:%ld\n"
|
2013-09-23 14:56:08 +00:00
|
|
|
"Output: year=%ld mon=%ld day=%ld time=%ld:%ld:%ld\n",
|
|
|
|
year, month, day, hour, min, sec,
|
2020-01-29 12:05:02 +00:00
|
|
|
year1, month1, day1, hour1, min1, sec1);
|
|
|
|
exit(1);
|
2013-09-23 14:56:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Now test the conversion from long -> long */
|
2020-01-29 12:05:02 +00:00
|
|
|
jdlong1 = (long)(jd + 0.5); /* round up */
|
|
|
|
date = grib_julian_to_date(jdlong1);
|
|
|
|
jdlong2 = grib_date_to_julian(date);
|
|
|
|
if (jdlong1 != jdlong2) {
|
2013-09-23 14:56:08 +00:00
|
|
|
fprintf(stderr, "Failed julian<->date\nInput: year=%ld mon=%ld day=%ld time=%ld:%ld:%ld\n",
|
|
|
|
year, month, day, hour, min, sec);
|
2020-01-29 12:05:02 +00:00
|
|
|
exit(1);
|
2013-09-23 14:56:08 +00:00
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2017-08-25 16:30:00 +00:00
|
|
|
static void Test0()
|
2015-08-28 15:43:00 +00:00
|
|
|
{
|
|
|
|
long year, month, day, hour, min, sec;
|
|
|
|
double jd;
|
|
|
|
|
|
|
|
printf("Test0...\n");
|
|
|
|
/* Test a specific date */
|
|
|
|
year = 1801;
|
|
|
|
month = 1;
|
|
|
|
day = 30;
|
|
|
|
hour = 18;
|
|
|
|
min = 26;
|
|
|
|
sec = 24;
|
|
|
|
|
2023-12-16 12:53:34 +00:00
|
|
|
codes_datetime_to_julian(year, month, day, hour, min, sec, &jd);
|
2024-12-20 12:58:07 +00:00
|
|
|
ECCODES_ASSERT(DBL_EQUAL(jd, 2378891.268333));
|
2020-01-29 12:05:02 +00:00
|
|
|
printf("%ld %ld %ld %ld:%ld:%ld -> %f\n", year, month, day, hour, min, sec, jd);
|
|
|
|
|
|
|
|
grib_julian_to_datetime(jd, &year, &month, &day, &hour, &min, &sec);
|
2024-12-20 12:58:07 +00:00
|
|
|
ECCODES_ASSERT(year == 1801);
|
|
|
|
ECCODES_ASSERT(month == 1);
|
|
|
|
ECCODES_ASSERT(day == 30);
|
|
|
|
ECCODES_ASSERT(hour == 18);
|
|
|
|
ECCODES_ASSERT(min == 26);
|
|
|
|
ECCODES_ASSERT(sec == 24);
|
2020-01-29 12:05:02 +00:00
|
|
|
printf("%ld %ld %ld %ld:%ld:%ld -> %f\n", year, month, day, hour, min, sec, jd);
|
2015-08-28 15:43:00 +00:00
|
|
|
}
|
|
|
|
|
2017-08-25 16:30:00 +00:00
|
|
|
static void Test1()
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2013-09-23 14:56:08 +00:00
|
|
|
long year, month, day, hour, min, sec;
|
|
|
|
double jd;
|
|
|
|
|
|
|
|
/* Test a specific date */
|
2015-08-28 15:43:00 +00:00
|
|
|
printf("Test1...\n");
|
2020-01-29 12:05:02 +00:00
|
|
|
year = 1957;
|
2013-09-23 14:56:08 +00:00
|
|
|
month = 10;
|
2020-01-29 12:05:02 +00:00
|
|
|
day = 4;
|
|
|
|
hour = 19;
|
|
|
|
min = 26;
|
|
|
|
sec = 24;
|
|
|
|
|
|
|
|
grib_datetime_to_julian(year, month, day, hour, min, sec, &jd);
|
2024-12-20 12:58:07 +00:00
|
|
|
ECCODES_ASSERT(DBL_EQUAL(jd, 2436116.31));
|
2020-01-29 12:05:02 +00:00
|
|
|
printf("%ld %ld %ld %ld:%ld:%ld -> %f\n", year, month, day, hour, min, sec, jd);
|
|
|
|
|
|
|
|
grib_julian_to_datetime(jd, &year, &month, &day, &hour, &min, &sec);
|
2024-12-20 12:58:07 +00:00
|
|
|
ECCODES_ASSERT(year == 1957);
|
|
|
|
ECCODES_ASSERT(month == 10);
|
|
|
|
ECCODES_ASSERT(day == 4);
|
|
|
|
ECCODES_ASSERT(hour == 19);
|
|
|
|
ECCODES_ASSERT(min == 26);
|
|
|
|
ECCODES_ASSERT(sec == 24);
|
2020-01-29 12:05:02 +00:00
|
|
|
printf("%ld %ld %ld %ld:%ld:%ld -> %f\n", year, month, day, hour, min, sec, jd);
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2017-08-25 16:30:00 +00:00
|
|
|
static void Test2()
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2013-09-23 14:56:08 +00:00
|
|
|
long year, month, day, hour, minute, second;
|
2020-01-29 12:05:02 +00:00
|
|
|
int i, last;
|
2013-09-23 14:56:08 +00:00
|
|
|
double jd;
|
2020-01-29 12:05:02 +00:00
|
|
|
long jdl, date;
|
2013-09-23 14:56:08 +00:00
|
|
|
/* Test specific julian values */
|
2020-01-29 12:05:02 +00:00
|
|
|
double jds[] = {
|
|
|
|
2451545.0,
|
|
|
|
2446822.5,
|
|
|
|
2446966.0,
|
|
|
|
2447187.5,
|
|
|
|
2447332.0,
|
|
|
|
2415020.5,
|
|
|
|
2305447.5,
|
|
|
|
2305812.5,
|
|
|
|
2205512.5,
|
|
|
|
2026871.8,
|
|
|
|
0.0
|
|
|
|
};
|
|
|
|
|
|
|
|
last = sizeof(jds) / sizeof(double);
|
2013-09-23 14:56:08 +00:00
|
|
|
|
|
|
|
printf("\n");
|
2015-08-28 15:43:00 +00:00
|
|
|
printf("Test2...\n");
|
2020-01-29 12:05:02 +00:00
|
|
|
for (i = 0; i < last; i++) {
|
|
|
|
jd = jds[i];
|
|
|
|
grib_julian_to_datetime(jd, &year, &month, &day, &hour, &minute, &second);
|
|
|
|
printf("+ %ld %ld %ld %ld:%ld:%ld -> %f\n", year, month, day, hour, minute, second, jd);
|
|
|
|
grib_datetime_to_julian(year, month, day, hour, minute, second, &jd);
|
|
|
|
printf("- %ld %ld %ld %ld:%ld:%ld -> %f\n", year, month, day, hour, minute, second, jd);
|
|
|
|
|
|
|
|
if (!DBL_EQUAL(jd, jds[i])) {
|
2013-09-23 14:56:08 +00:00
|
|
|
fprintf(stderr, "i=%d: Got: %f, expected: %f\n", i, jd, jds[i]);
|
2024-12-20 12:58:07 +00:00
|
|
|
ECCODES_ASSERT(0);
|
2013-09-23 14:56:08 +00:00
|
|
|
}
|
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
jdl = (long)(jd + 0.5);
|
2023-12-16 12:53:34 +00:00
|
|
|
date = codes_julian_to_date(jdl);
|
2020-01-29 12:05:02 +00:00
|
|
|
printf("+ %ld -> %ld\n", date, jdl);
|
2023-12-16 12:53:34 +00:00
|
|
|
jdl = codes_date_to_julian(date);
|
2020-01-29 12:05:02 +00:00
|
|
|
printf("- %ld -> %ld\n", date, jdl);
|
2013-09-23 14:56:08 +00:00
|
|
|
printf("\n");
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2017-08-25 16:30:00 +00:00
|
|
|
static void Test3()
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2013-09-23 14:56:08 +00:00
|
|
|
long iyear, imnth, iday, ihr, imin, isec;
|
2015-08-28 15:43:00 +00:00
|
|
|
printf("Test3...\n");
|
2020-01-29 12:05:02 +00:00
|
|
|
for (iyear = 1950; iyear <= 2015; iyear += 5) {
|
|
|
|
for (imnth = 1; imnth <= 12; imnth += 1) {
|
|
|
|
for (iday = 1; iday <= 28; iday += 1) {
|
|
|
|
for (ihr = 1; ihr <= 23; ihr += 2) {
|
|
|
|
for (imin = 1; imin <= 59; imin += 3) {
|
|
|
|
for (isec = 1; isec <= 59; isec += 5) {
|
2013-09-23 14:56:08 +00:00
|
|
|
TestDateTime(iyear, imnth, iday, ihr, imin, isec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2020-03-13 15:17:10 +00:00
|
|
|
static void Test4()
|
|
|
|
{
|
|
|
|
const long iyear = 1582;
|
2024-02-28 13:54:02 +00:00
|
|
|
printf("Test4...\n");
|
2020-03-13 15:17:10 +00:00
|
|
|
|
|
|
|
TestDateTime(iyear, 9, 1, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 9, 2, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 9, 3, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 9, 4, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 9, 4, 16, 0, 0);
|
|
|
|
|
|
|
|
/* TODO */
|
|
|
|
/* TestDateTime(iyear, 10, 5, 1, 0, 0); */
|
|
|
|
TestDateTime(iyear, 10, 1, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 10, 2, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 10, 3, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 10, 4, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 10, 15, 1, 0, 0);
|
|
|
|
|
|
|
|
TestDateTime(iyear, 11, 1, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 11, 2, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 11, 3, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 11, 4, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 11, 5, 1, 0, 0);
|
|
|
|
TestDateTime(iyear, 11, 5, 15, 0, 0);
|
|
|
|
|
|
|
|
/* TODO
|
|
|
|
* for (imnth = 1; imnth <= 12; imnth += 1) {
|
|
|
|
* for (iday = 1; iday <= 28; iday += 1) {
|
|
|
|
* TestDateTime(iyear, imnth, iday, 1, 0, 0);
|
|
|
|
* }
|
|
|
|
* }
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
2024-02-28 13:54:02 +00:00
|
|
|
static void Test5()
|
|
|
|
{
|
|
|
|
printf("Test5...\n");
|
2024-02-28 13:55:45 +00:00
|
|
|
|
|
|
|
// Also see function is_date_valid()
|
|
|
|
|
2024-02-28 13:54:02 +00:00
|
|
|
double jd = 0.0;
|
|
|
|
long year=2017, month=2, day=29, hour=0, min=0, sec=0; // Feb 2017 had 28 days
|
|
|
|
long year1, month1, day1, hour1, min1, sec1;
|
|
|
|
|
|
|
|
codes_datetime_to_julian(year, month, day, hour, min, sec, &jd);
|
|
|
|
codes_julian_to_datetime(jd, &year1, &month1, &day1, &hour1, &min1, &sec1);
|
|
|
|
|
|
|
|
if (Check(year, month, day, hour, min, sec, year1, month1, day1, hour1, min1, sec1)) {
|
2024-12-20 12:58:07 +00:00
|
|
|
ECCODES_ASSERT(!"Bad input should have failed checks");
|
2024-02-28 13:54:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-29 12:05:02 +00:00
|
|
|
int main(int argc, char* argv[])
|
2013-03-25 12:04:10 +00:00
|
|
|
{
|
2015-08-28 15:43:00 +00:00
|
|
|
Test0();
|
2013-09-23 14:56:08 +00:00
|
|
|
Test1();
|
|
|
|
Test2();
|
|
|
|
Test3();
|
2020-03-13 15:17:10 +00:00
|
|
|
Test4();
|
2024-02-28 13:54:02 +00:00
|
|
|
Test5();
|
2015-08-28 15:43:00 +00:00
|
|
|
printf("All OK\n");
|
2013-09-23 14:56:08 +00:00
|
|
|
return 0;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|