WSL/SLF GitLab Repository

Commit 8c40e39c authored by Fierz's avatar Fierz
Browse files

- Date.*: allow to handle undefined Dates (== 0. for now), add new members...

- Date.*: allow to handle undefined Dates (== 0. for now), add new members undef, setUndef(), isUndef(), and rndJulianDate()
- IOUtils.*: replaced TZ with time_zone and TIME_ZONE
- ImisIO.*: correct typo seperateDrift to separateDrift
parent cf280875
This diff is collapsed.
/***********************************************************************************/
/* Copyright 2009 WSL Institute for Snow and Avalanche Research SLF-DAVOS */
/***********************************************************************************/
/* This file is part of MeteoIO.
MeteoIO is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MeteoIO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with MeteoIO. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __DATE_H__
#define __DATE_H__
#include <meteoio/IOExceptions.h>
#include <string>
#include <sstream>
#include <utility>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <ctime>
///Using the following namespace for the comparison operator overloading
//using namespace rel_ops;
namespace mio {
/**
* @class Date
* @brief A class to handle timestamps.
* This class handles conversion between different time display formats (ISO, numeric) as well as different
* time representation (julian date, modified julian date, etc). It also handles time zones as well as
* very basic Daylight Saving Time (DST). Since the activation dates of DST are political and not technical,
* it can not be automatically calculated. Therefore, it has to be provided by the caller: when the dst flag
* is set, the dst time shift is automatically applied. When the dst flag ceases to be set, the dst time shift
* is no longer applied. This is very crude, but please keep in mind that using DST for monitoring data is
* usually a bad idea...
*
* Internally, the date is stored as true julian date in GMT.
* The maximal precision is 1 minute (that can be easily brought to 1 seconds if
* it would appear necessary/useful, with the limitation that leap seconds are currently not handled).
*
* Please see Date::FORMATS for supported display formats and http://en.wikipedia.org/wiki/Julian_day for
* the various date representation definitions. The following data representation are currently supported:
* - julian date, see Date::getJulianDate
* - modified julian date, see Date::getModifiedJulianDate
* - truncated julian date, see Date::getTruncatedJulianDate
* - Unix date, see Date::getUnixDate
* - Excel date, see Date::getExcelDate
*
* @ingroup data_str
* @author Mathias Bavay
* @date 2010-04-15
*/
#ifdef _POPC_
class DateDummy {}; //HACK for POPC
class Date : POPBase {
public:
void Serialize(POPBuffer &buf, bool pack);
#else
class Date {
#endif
public:
///Keywords for selecting the date formats
typedef enum {
ISO, ///< ISO 8601 extended format combined date: YYYY-MM-DDTHH:mm:SS (fields might be dropped, in the least to the most significant order)
FULL, ///< ISO 8601 followed by the julian date (in parenthesis)
NUM, ///< ISO 8601 basic format date: YYYYMMDDHHmmSS (fields might be dropped, in the least to the most significant order)
DIN ///<DIN5008 format: DD.MM.YYYY HH:MM
} FORMATS;
static const int daysLeapYear[];
static const int daysNonLeapYear[];
static const double DST_shift;
static const float MJD_offset;
static const float Unix_offset;
static const float Excel_offset;
Date();
Date(const double& julian_in, const double& in_timezone, const bool& in_dst=false);
Date(const int& year, const int& month, const int& day, const int& hour, const int& minute, const double& in_timezone, const bool& in_dst=false);
Date(const time_t&, const double& in_timezone, const bool& in_dst=false);
Date(const Date& in_date);
void setFromSys();
void setTimeZone(const double& in_timezone, const bool& in_dst=false);
void setDate(const double& julian_in, const double& in_timezone, const bool& _dst=false);
void setDate(const int& year, const int& month, const int& day, const int& hour, const int& minute, const double& in_timezone, const bool& _dst=false);
void setDate(const time_t& in_time, const double& in_timezone, const bool& _dst=false);
void setModifiedJulianDate(const double& julian_in, const double& in_timezone, const bool& _dst=false);
void setUnixDate(const time_t& in_time, const double& in_timezone, const bool& _dst=false);
void setExcelDate(const double excel_in, const double& in_timezone, const bool& _dst=false);
double getTimeZone() const;
bool getDST() const;
double getJulianDate(const bool& gmt=false) const;
double getModifiedJulianDate(const bool& gmt=false) const;
double getTruncatedJulianDate(const bool& gmt=false) const;
time_t getUnixDate(const bool& gmt=false) const;
double getExcelDate(const bool& gmt=false) const;
void getDate(double& julian_out, const bool& gmt=false) const;
void getDate(int& year, int& month, int& day, const bool& gmt=false) const;
void getDate(int& year, int& month, int& day, int& hour, const bool& gmt=false) const;
void getDate(int& year, int& month, int& day, int& hour, int& minute, const bool& gmt=false) const;
int getYear(const bool& gmt=false) const;
int getJulianDayNumber() const;
bool isLeapYear() const;
const std::string toString(FORMATS type, const bool& gmt=false) const;
friend std::ostream& operator<<(std::ostream& os, const Date& date);
//Operator Prototypes
bool operator==(const Date&) const;
bool operator!=(const Date&) const;
bool operator<(const Date&) const;
bool operator<=(const Date&) const;
bool operator>(const Date&) const;
bool operator>=(const Date&) const;
///Intervals arithmetic
///Can be used to add an interval to an existing Date object.
///Construct a Date object representing the interval e.g. Date(1.0) for 1 day and add that to another Date object.
Date& operator+=(const Date&);
Date& operator-=(const Date&);
Date& operator+=(const double&);
Date& operator-=(const double&);
Date& operator*=(const double&);
Date& operator/=(const double&);
const Date operator+(const Date&) const;
const Date operator-(const Date&) const;
const Date operator+(const double&) const;
const Date operator-(const double&) const;
const Date operator*(const double&) const;
const Date operator/(const double&) const;
protected:
double localToGMT(const double& in_julian)const;
double GMTToLocal(const double& in_gmt_julian) const;
double calculateJulianDate(const int& in_year, const int& in_month, const int& in_day, const int& in_hour, const int& in_minute) const;
void calculateValues(const double& julian, int& out_year, int& out_month, int& out_day, int& out_hour, int& out_minute) const;
long getJulianDayNumber(const int&, const int&, const int&) const;
bool isLeapYear(const int&) const;
void plausibilityCheck(const int& in_year, const int& in_month, const int& in_day, const int& in_hour, const int& in_minute) const;
double timezone;
bool dst;
double gmt_julian;
int gmt_year, gmt_month, gmt_day, gmt_hour, gmt_minute;
static const double undefined;
};
typedef Date Duration; //so that later, we can implement a true Interval/Duration class
} //end namespace
#endif
/***********************************************************************************/
/* Copyright 2009 WSL Institute for Snow and Avalanche Research SLF-DAVOS */
/***********************************************************************************/
/* This file is part of MeteoIO.
MeteoIO is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MeteoIO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with MeteoIO. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __DATE_H__
#define __DATE_H__
#include <meteoio/IOExceptions.h>
#include <string>
#include <sstream>
#include <utility>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <ctime>
///Using the following namespace for the comparison operator overloading
//using namespace rel_ops;
namespace mio {
/**
* @class Date
* @brief A class to handle timestamps.
* This class handles conversion between different time display formats (ISO, numeric) as well as different
* time representation (julian date, modified julian date, etc). It also handles time zones as well as
* very basic Daylight Saving Time (DST). Since the activation dates of DST are political and not technical,
* it can not be automatically calculated. Therefore, it has to be provided by the caller: when the dst flag
* is set, the dst time shift is automatically applied. When the dst flag ceases to be set, the dst time shift
* is no longer applied. This is very crude, but please keep in mind that using DST for monitoring data is
* usually a bad idea...
*
* Internally, the date is stored as true julian date in GMT.
* The maximal precision is 1 minute (that can be easily brought to 1 seconds if
* it would appear necessary/useful, with the limitation that leap seconds are currently not handled).
*
* Please see Date::FORMATS for supported display formats and http://en.wikipedia.org/wiki/Julian_day for
* the various date representation definitions. The following data representation are currently supported:
* - julian date, see Date::getJulianDate
* - modified julian date, see Date::getModifiedJulianDate
* - truncated julian date, see Date::getTruncatedJulianDate
* - Unix date, see Date::getUnixDate
* - Excel date, see Date::getExcelDate
*
* @ingroup data_str
* @author Mathias Bavay
* @date 2010-04-15
*/
#ifdef _POPC_
class DateDummy {}; //HACK for POPC
class Date : POPBase {
public:
void Serialize(POPBuffer &buf, bool pack);
#else
class Date {
#endif
public:
///Keywords for selecting the date formats
typedef enum {
ISO, ///< ISO 8601 extended format combined date: YYYY-MM-DDTHH:mm:SS (fields might be dropped, in the least to the most significant order)
FULL, ///< ISO 8601 followed by the julian date (in parenthesis)
NUM, ///< ISO 8601 basic format date: YYYYMMDDHHmmSS (fields might be dropped, in the least to the most significant order)
DIN ///<DIN5008 format: DD.MM.YYYY HH:MM
} FORMATS;
static const int daysLeapYear[];
static const int daysNonLeapYear[];
static const double DST_shift;
static const float MJD_offset;
static const float Unix_offset;
static const float Excel_offset;
Date();
Date(const double& julian_in, const double& in_timezone, const bool& in_dst=false);
Date(const int& year, const int& month, const int& day, const int& hour, const int& minute, const double& in_timezone, const bool& in_dst=false);
Date(const time_t&, const double& in_timezone, const bool& in_dst=false);
Date(const Date& in_date);
void setFromSys(const double& in_timezone);
void setTimeZone(const double& in_timezone, const bool& in_dst=false);
void setDate(const double& julian_in, const double& in_timezone, const bool& _dst=false);
void setDate(const int& year, const int& month, const int& day, const int& hour, const int& minute, const double& in_timezone, const bool& _dst=false);
void setDate(const time_t& in_time, const double& in_timezone, const bool& _dst=false);
void setModifiedJulianDate(const double& julian_in, const double& in_timezone, const bool& _dst=false);
void setUnixDate(const time_t& in_time, const double& in_timezone, const bool& _dst=false);
void setExcelDate(const double excel_in, const double& in_timezone, const bool& _dst=false);
void setUndef(const bool& flag);
bool isUndef() const;
double getTimeZone() const;
bool getDST() const;
double getJulianDate(const bool& gmt=false) const;
double getModifiedJulianDate(const bool& gmt=false) const;
double getTruncatedJulianDate(const bool& gmt=false) const;
time_t getUnixDate(const bool& gmt=false) const;
double getExcelDate(const bool& gmt=false) const;
void getDate(double& julian_out, const bool& gmt=false) const;
void getDate(int& year, int& month, int& day, const bool& gmt=false) const;
void getDate(int& year, int& month, int& day, int& hour, const bool& gmt=false) const;
void getDate(int& year, int& month, int& day, int& hour, int& minute, const bool& gmt=false) const;
int getYear(const bool& gmt=false) const;
int getJulianDayNumber() const;
bool isLeapYear() const;
double rndJulianDate() const;
const std::string toString(FORMATS type, const bool& gmt=false) const;
friend std::ostream& operator<<(std::ostream& os, const Date& date);
//Operator Prototypes
bool operator==(const Date&) const;
bool operator!=(const Date&) const;
bool operator<(const Date&) const;
bool operator<=(const Date&) const;
bool operator>(const Date&) const;
bool operator>=(const Date&) const;
///Intervals arithmetic
///Can be used to add an interval to an existing Date object.
///Construct a Date object representing the interval e.g. Date(1.0) for 1 day and add that to another Date object.
Date& operator+=(const Date&);
Date& operator-=(const Date&);
Date& operator+=(const double&);
Date& operator-=(const double&);
Date& operator*=(const double&);
Date& operator/=(const double&);
const Date operator+(const Date&) const;
const Date operator-(const Date&) const;
const Date operator+(const double&) const;
const Date operator-(const double&) const;
const Date operator*(const double&) const;
const Date operator/(const double&) const;
protected:
double localToGMT(const double& in_julian)const;
double GMTToLocal(const double& in_gmt_julian) const;
double calculateJulianDate(const int& in_year, const int& in_month, const int& in_day, const int& in_hour, const int& in_minute) const;
void calculateValues(const double& julian, int& out_year, int& out_month, int& out_day, int& out_hour, int& out_minute) const;
long getJulianDayNumber(const int&, const int&, const int&) const;
bool isLeapYear(const int&) const;
void plausibilityCheck(const int& in_year, const int& in_month, const int& in_day, const int& in_hour, const int& in_minute) const;
double timezone;
bool dst;
double gmt_julian;
int gmt_year, gmt_month, gmt_day, gmt_hour, gmt_minute;
bool undef;
};
typedef Date Duration; //so that later, we can implement a true Interval/Duration class
} //end namespace
#endif
......@@ -330,7 +330,7 @@ template<> bool IOUtils::convertString<bool>(bool& t, const std::string& str, st
return true;
}
bool IOUtils::convertString(Date& t, const std::string& str, const double& TZ, std::ios_base& (*f)(std::ios_base&))
bool IOUtils::convertString(Date& t, const std::string& str, const double& time_zone, std::ios_base& (*f)(std::ios_base&))
{
std::string s = str;
trim(s); //delete trailing and leading whitespaces and tabs
......@@ -341,17 +341,17 @@ bool IOUtils::convertString(Date& t, const std::string& str, const double& TZ, s
//HACK: we read the seconds, but we ignore them...
if (sscanf(s.c_str(), "%u-%u-%u %u:%u:%u%31s", &year, &month, &day, &hour, &minute, &second, rest) >= 6) {
t.setDate(year, month, day, hour, minute, TZ);
t.setDate(year, month, day, hour, minute, time_zone);
} else if (sscanf(s.c_str(), "%u-%u-%uT%u:%u:%u%31s", &year, &month, &day, &hour, &minute, &second, rest) >= 6) {
t.setDate(year, month, day, hour, minute, TZ);
t.setDate(year, month, day, hour, minute, time_zone);
} else if (sscanf(s.c_str(), "%u-%u-%u %u:%u%31s", &year, &month, &day, &hour, &minute, rest) >= 5) {
t.setDate(year, month, day, hour, minute, TZ);
t.setDate(year, month, day, hour, minute, time_zone);
} else if (sscanf(s.c_str(), "%u-%u-%uT%u:%u%31s", &year, &month, &day, &hour, &minute, rest) >= 5) {
t.setDate(year, month, day, hour, minute, TZ);
t.setDate(year, month, day, hour, minute, time_zone);
} else if (sscanf(s.c_str(), "%u-%u-%u%31s", &year, &month, &day, rest) >= 3) {
t.setDate(year, month, day, 0, 0, TZ);
t.setDate(year, month, day, 0, 0, time_zone);
} else if (sscanf(s.c_str(), "%u:%u%31s", &hour, &minute, rest) >= 2) {
t.setDate( ((double)hour)/24. + ((double)minute)/24./60. , TZ);
t.setDate( ((double)hour)/24. + ((double)minute)/24./60. , time_zone);
} else {
//try to read purely numerical date, potentially surrounded by other chars
const unsigned int in_len = str.length();
......@@ -384,7 +384,7 @@ bool IOUtils::convertString(Date& t, const std::string& str, const double& TZ, s
}
}
t.setDate( year, month, day, hour, minute, TZ );
t.setDate( year, month, day, hour, minute, time_zone );
}
std::string tmp(rest);
......@@ -423,8 +423,8 @@ void IOUtils::getProjectionParameters(const Config& cfg, std::string& coordin, s
}
void IOUtils::getTimeZoneParameters(const Config& cfg, double& tz_in, double& tz_out) {
cfg.getValue("TZ", "Input", tz_in, Config::nothrow);
cfg.getValue("TZ", "Output", tz_out, Config::nothrow);
cfg.getValue("TIME_ZONE", "Input", tz_in, Config::nothrow);
cfg.getValue("TIME_ZONE", "Output", tz_out, Config::nothrow);
}
unsigned int IOUtils::seek(const Date& soughtdate, const std::vector<MeteoData>& vecM, const bool& exactmatch){
......
......@@ -45,10 +45,10 @@
#endif
#ifndef C_TO_K
#define C_TO_K( T ) ( T + 273.15 ) // Celsius to Kelvin
#define C_TO_K( T ) ( T + 273.15 ) // degree Celsius to kelvin
#endif
#ifndef K_TO_C
#define K_TO_C( T ) ( T - 273.15 ) // Kelvin to Celsius
#define K_TO_C( T ) ( T - 273.15 ) // kelvin to degree Celsius
#endif
namespace mio {
......@@ -190,7 +190,7 @@ namespace IOUtils {
template<> bool convertString<bool>(bool& t, const std::string& str, std::ios_base& (*f)(std::ios_base&));
template<> bool convertString<Coords>(Coords& t, const std::string& str, std::ios_base& (*f)(std::ios_base&));
bool convertString(Date& t, const std::string& str, const double& TZ, std::ios_base& (*f)(std::ios_base&) = std::dec);
bool convertString(Date& t, const std::string& str, const double& time_zone, std::ios_base& (*f)(std::ios_base&) = std::dec);
/**
* @brief Returns, with the requested type, the value associated to a key (template function).
......
......@@ -770,16 +770,16 @@ void ImisIO::getImisData (const std::string& stat_abk, const std::string& stao_n
vecMeteoData.clear();
//First check whether this is a station with seperate wind drift data
bool seperateDriftStation = false;
//First check whether this is a station with separate wind drift data
bool separateDriftStation = false;
map<string,string>::const_iterator it = mapDriftStation.find(stat_abk+stao_nr);
if (it != mapDriftStation.end())
seperateDriftStation = true;
separateDriftStation = true;
try {
Statement *stmt = NULL;
ResultSet *rs = NULL;
if (!seperateDriftStation){
if (!separateDriftStation){
stmt = conn->createStatement(sqlQueryMeteoData);
} else {
stmt = conn->createStatement(sqlQueryMeteoDataDrift);
......@@ -793,7 +793,7 @@ void ImisIO::getImisData (const std::string& stat_abk, const std::string& stao_n
stmt->setDate(3, begindate); // set 3rd variable's value (begin date)
stmt->setDate(4, enddate); // set 4th variable's value (enddate)
if (seperateDriftStation){
if (separateDriftStation){
string drift_stat_abk="", drift_stao_nr="";
parseStationName(it->second, drift_stat_abk, drift_stao_nr);
nrOfColumns += 2; //two extra columns for drift wind and direction
......@@ -824,7 +824,7 @@ void ImisIO::convertUnits(MeteoData& meteo)
{
meteo.standardizeNodata(plugin_nodata);
//converts C to Kelvin, converts ilwr to ea, converts RH to [0,1]
//converts degC to Kelvin, converts ilwr to ea, converts RH to [0,1]
if(meteo.ta!=IOUtils::nodata) {
meteo.ta=C_TO_K(meteo.ta);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment