36static char rcsid[] not_used =
"$Id$";
 
   47#include <libdap/BaseType.h> 
   48#include <libdap/Str.h> 
   49#include <libdap/debug.h> 
   61#include <libdap/Error.h> 
   65static string extract_argument(BaseType *arg)
 
   68    if (arg->type() != dods_str_c)
 
   69        throw Error(malformed_expr, 
"The Projection function requires a DODS string-type argument.");
 
   74    arg->buf2val((
void **) &sp);
 
   75    string s = sp->c_str();
 
   78    DBG(cerr << 
"s: " << s << endl);
 
   82    return static_cast<Str*
>(arg)->value();
 
   90    return _year > 0 && _month > 0 && _day > 0 && _julian_day > 0 && _day_number > 0 && _format != unknown_format;
 
 
   96    _julian_day(0), _year(0), _month(0), _day(0), _day_number(0), _format(unknown_format)
 
 
  102    string s = extract_argument(arg);
 
 
  128    string s = extract_argument(arg);
 
 
  136void DODS_Date::parse_integer_time(
string date)
 
  139    istringstream iss(date.c_str());
 
  147    pos1 = date.find(
"/");
 
  148    pos2 = date.rfind(
"/");
 
  149    if ((pos1 == date.npos) && (pos2 == date.npos)) {
 
  150        string msg = 
"I cannot understand the date string: ";
 
  151        msg += date + 
". I expected a date formatted like yyyy/mm/dd or yyyy/ddd.";
 
  152        throw Error(malformed_expr, msg);
 
  154    else if ((pos1 != pos2)) {
 
  159        _day_number = month_day_to_days(_year, _month, _day);
 
  165        _day_number = _month;
 
  166        days_to_month_day(_year, _day_number, &_month, &_day);
 
  172void DODS_Date::parse_iso8601_time(
string date)
 
  175    istringstream iss(date.c_str());
 
  183    pos1 = date.find(
"-");
 
  184    pos2 = date.rfind(
"-");
 
  185    if ((pos1 != date.npos) && (pos2 != date.npos) && (pos1 != pos2)) {
 
  190        _day_number = month_day_to_days(_year, _month, _day);
 
  194    else if (((pos1 != date.npos) && (pos2 == date.npos)) || (pos1 == pos2)) {
 
  198        _day_number = month_day_to_days(_year, _month, _day);
 
  202    else if ((pos1 == date.npos) && (date.size() == 4)) {
 
  207        _day_number = month_day_to_days(_year, _month, _day);
 
  211        string msg = 
"I cannot understand the date string: ";
 
  212        msg += date + 
". I expected an iso8601 date (ccyy-mm-dd, ccyy-mm or ccyy).";
 
  213        throw Error(malformed_expr, msg);
 
  223void DODS_Date::parse_fractional_time(
string dec_year)
 
  226    double d_year_day, d_hr_day, d_min_day, d_sec_day;
 
  227    int i_year, i_year_day, i_hr_day, i_min_day, i_sec_day;
 
  231    double d_year = strtod(dec_year.c_str(), 0);
 
  233    i_year = (int) d_year;
 
  234    double year_fraction = d_year - i_year;
 
  236    secs_in_year = days_in_year(_year) * seconds_per_day;
 
  241    d_year_day = (secs_in_year * year_fraction) / seconds_per_day + 1;
 
  242    i_year_day = (int) d_year_day;
 
  247    d_hr_day = ((d_year_day - i_year_day) * seconds_per_day) / seconds_per_hour;
 
  248    i_hr_day = (int) d_hr_day;
 
  253    d_min_day = ((d_hr_day - i_hr_day) * seconds_per_hour) / seconds_per_minute;
 
  254    i_min_day = (int) d_min_day;
 
  259    d_sec_day = (d_min_day - i_min_day) * seconds_per_minute;
 
  260    i_sec_day = (int) d_sec_day;
 
  266    if ((d_sec_day - i_sec_day) >= .5) i_sec_day++;
 
  268    if (i_sec_day == 60) {
 
  271        if (i_min_day == 60) {
 
  274            if (i_hr_day == 24) {
 
  277                if (i_year_day == (days_in_year(_year) + 1)) {
 
  285    set(i_year, i_year_day);
 
  293    if (date.find(
".") != string::npos) {
 
  294        parse_fractional_time(date);
 
  296    else if (date.find(
"/") != string::npos) {
 
  297        parse_integer_time(date);
 
  299    else if (date.find(
"-") != string::npos) {
 
  300        parse_iso8601_time(date);
 
  302    else if (date.size() == 4) {
 
  304        parse_iso8601_time(date);
 
  307        throw Error(malformed_expr, 
"Could not recognize date format");
 
 
  315    _day_number = day_num;
 
  316    days_to_month_day(_year, _day_number, &_month, &_day);
 
 
  329    _day_number = month_day_to_days(_year, _month, _day);
 
 
  342    _day_number = month_day_to_days(_year, _month, _day);
 
 
  357        return d1._julian_day == d2._julian_day ? 1 : 0;
 
 
  362    return d1._julian_day != d2._julian_day ? 1 : 0;
 
 
  367    return d1._julian_day < d2._julian_day ? 1 : 0;
 
 
  372    return d1._julian_day > d2._julian_day ? 1 : 0;
 
 
  380        return d1._julian_day <= d2._julian_day ? 1 : 0;
 
 
  389        return d1._julian_day >= d2._julian_day ? 1 : 0;
 
 
  424double DODS_Date::fraction()
 const 
  426    return _year + (_day_number - 1) / days_in_year(_year);
 
  435        oss << _year << 
"/" << _day_number;
 
  438        oss << _year << 
"/" << _month << 
"/" << _day;
 
  442            oss << _year << 
"-" << setfill(
'0') << setw(2) << _month;
 
  445            oss << _year << 
"-" << setfill(
'0') << setw(2) << _month << 
"-" << setfill(
'0') << setw(2) << _day;
 
  454        throw Error(unknown_error, 
"Invalid date format");
 
  456        assert(
"Invalid date format" && 
false);
 
 
  466    tm_rec.tm_mday = _day;
 
  467    tm_rec.tm_mon = _month - 1; 
 
  468    tm_rec.tm_year = _year - 1900; 
 
  472    tm_rec.tm_isdst = -1;
 
  474    return mktime(&tm_rec);
 
 
  487int main(
int argc, 
char *argv[])
 
  494        d1.
set((
string)argv[1]);
 
  497        d1.
set(atoi(argv[1]), atoi(argv[2]));
 
  500        d1.
set(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
 
  503        d1.
set(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), (date_format)atoi(argv[4]));
 
  506        cerr << 
"Wrong number of args!" << endl;
 
  511    cout << 
"True: d1 < epoc" << endl;
 
  513    cout << 
"False: d1 < epoc" << endl;
 
  516    cout << 
"True: d1 > epoc" << endl;
 
  518    cout << 
"False: d1 > epoc" << endl;
 
  521    cout << 
"True: d1 <= epoc" << endl;
 
  523    cout << 
"False: d1 <= epoc" << endl;
 
  526    cout << 
"True: d1 >= epoc" << endl;
 
  528    cout << 
"False: d1 >= epoc" << endl;
 
  531    cout << 
"True: d1 == epoc" << endl;
 
  533    cout << 
"False: d1 == epoc" << endl;
 
  536    cout << 
"True: d1 != epoc" << endl;
 
  538    cout << 
"False: d1 != epoc" << endl;
 
  540    cout << 
"YMD: " << d1.
get() << endl;
 
  541    cout << 
"ISO8601: " << d1.
get(iso8601) << endl;
 
  542    cout << 
"YD: " << d1.
get(yd) << endl;
 
  543    cout << 
"Julian day: " << d1.
julian_day() << endl;
 
  544    cout << 
"Seconds: " << d1.
unix_time() << endl;
 
friend int operator==(DODS_Date &d1, DODS_Date &d2)
Equality.
 
friend int operator<(DODS_Date &d1, DODS_Date &d2)
Less than.
 
friend int operator>=(DODS_Date &d1, DODS_Date &d2)
Greater than or equal.
 
friend int operator!=(DODS_Date &d1, DODS_Date &d2)
Inequality.
 
friend int operator>(DODS_Date &d1, DODS_Date &d2)
Greater than.
 
string get(date_format format=ymd) const
 
date_format format() const
 
friend int operator<=(DODS_Date &d1, DODS_Date &d2)
Less than or equal.