--- parser3/src/classes/date.C 2016/03/31 21:46:19 1.103 +++ parser3/src/classes/date.C 2025/10/04 00:22:18 1.122 @@ -1,8 +1,8 @@ /** @file Parser: @b date parser class. - Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com) - Author: Alexandr Petrosian (http://paf.design.ru) + Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ #include "classes.h" @@ -12,8 +12,9 @@ #include "pa_vdouble.h" #include "pa_vdate.h" #include "pa_vtable.h" +#include "pa_vbool.h" -volatile const char * IDENT_DATE_C="$Id: date.C,v 1.103 2016/03/31 21:46:19 moko Exp $" IDENT_PA_VDATE_H; +volatile const char * IDENT_DATE_C="$Id: date.C,v 1.122 2025/10/04 00:22:18 moko Exp $" IDENT_PA_VDATE_H; // class @@ -42,8 +43,12 @@ public: } }; - -Table date_calendar_table_template(new Date_calendar_table_template_columns); +static Table &date_calendar_table_template(){ + static Table *singleton=NULL; + if(!singleton) + singleton=new Table(new Date_calendar_table_template_columns); + return *singleton; +} // methods @@ -57,12 +62,16 @@ static void _now(Request& r, MethodParam vdate.set_time(t); } -static void _today(Request& r, MethodParams&) { +static void _today(Request& r, MethodParams& params) { VDate& vdate=GET_SELF(r, VDate); time_t t=time(0); tm today=*localtime(&t); + + if (params.count() == 1) // ^today(offset) + today.tm_mday += params.as_int(0, "offset must be int", r); + today.tm_hour=0; today.tm_min=0; today.tm_sec=0; @@ -70,7 +79,7 @@ static void _today(Request& r, MethodPar vdate.set_tm(today); } -static int to_year(int iyear) { +int to_year(int iyear) { if(iyear<0 || iyear>9999) throw Exception(DATE_RANGE_EXCEPTION_TYPE, 0, "year '%d' is out of range 0..9999", iyear); return iyear-1900; @@ -188,7 +197,8 @@ tm cstr_to_time_t(char *cstr, const char char *cur=cstr; const char *year, *month, *mday; - const char *hour, *min, *sec, *msec; + const char *hour, *min, *sec; + PA_UNUSED const char *msec; year=skip_number(&cur, "-:", &delim); if(delim != ':' || delim == ':' && strlen(year) >=4 ){ @@ -235,9 +245,9 @@ tm cstr_to_time_t(char *cstr, const char tmIn.tm_mday=tmNow->tm_mday; } - tmIn.tm_hour=hour?pa_atoi(hour):0; - tmIn.tm_min=min?pa_atoi(min):0; - tmIn.tm_sec=sec?pa_atoi(sec):0; + tmIn.tm_hour=pa_atoi(hour); + tmIn.tm_min=pa_atoi(min); + tmIn.tm_sec=pa_atoi(sec); //tmIn.tm_[msec<(adate)->get_tz()); + if(VDate* adate=dynamic_cast(¶ms[0])) + vdate.set_tz(adate->get_tz()); vdate.set_time(round(params.as_double(0, "float days must be double", r)*SECS_PER_DAY)); } } else { // ^create(y;m;d[;h[;m[;s[;TZ]]]]) @@ -273,7 +283,8 @@ static void _create(Request& r, MethodPa } static void _sql_string(Request& r, MethodParams& params) { - VDate& vdate=GET_SELF(r, VDate); + bool dynamic=&r.get_self() != date_class; + VDate& vdate=dynamic ? GET_SELF(r, VDate) : *new VDate((pa_time_t)time(0)); VDate::sql_string_type format = VDate::sql_string_datetime; if(params.count() > 0) { @@ -288,17 +299,19 @@ static void _sql_string(Request& r, Meth throw Exception(PARSER_RUNTIME, &what, "'type' must be 'date', 'time' or 'datetime'"); } - r.write_assign_lang(*vdate.get_sql_string(format)); + r.write(*vdate.get_sql_string(format)); } static void _gmt_string(Request& r, MethodParams&) { - VDate& vdate=GET_SELF(r, VDate); + bool dynamic=&r.get_self() != date_class; + VDate& vdate=dynamic ? GET_SELF(r, VDate) : *new VDate((pa_time_t)time(0)); - r.write_assign_lang(*vdate.get_gmt_string()); + r.write(*vdate.get_gmt_string()); } static void _iso_string(Request& r, MethodParams& params) { - VDate& vdate=GET_SELF(r, VDate); + bool dynamic=&r.get_self() != date_class; + VDate& vdate=dynamic ? GET_SELF(r, VDate) : *new VDate((pa_time_t)time(0)); VDate::iso_string_type format=VDate::iso_string_default; @@ -306,17 +319,17 @@ static void _iso_string(Request& r, Meth if(HashStringValue* options=params.as_hash(0)){ int valid_options=0; if(Value* vshow_ms=options->get("ms")){ - if(r.process_to_value(*vshow_ms).as_bool()) + if(r.process(*vshow_ms).as_bool()) format=VDate::iso_string_type(format|VDate::iso_string_ms); valid_options++; } if(Value* vshow_colon=options->get("colon")){ - if(!r.process_to_value(*vshow_colon).as_bool()) + if(!r.process(*vshow_colon).as_bool()) format=VDate::iso_string_type(format|VDate::iso_string_no_colon); valid_options++; } if(Value* vshow_z=options->get("z")){ - if(!r.process_to_value(*vshow_z).as_bool()) + if(!r.process(*vshow_z).as_bool()) format=VDate::iso_string_type(format|VDate::iso_string_no_z); valid_options++; } @@ -324,7 +337,7 @@ static void _iso_string(Request& r, Meth throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION); } - r.write_assign_lang(*vdate.get_iso_string(format)); + r.write(*vdate.get_iso_string(format)); } static void _roll(Request& r, MethodParams& params) { @@ -389,7 +402,7 @@ static void _roll(Request& r, MethodPara static Table& fill_month_days(Request& r, MethodParams& params, bool rus){ Table::Action_options table_options; - Table& result=*new Table(date_calendar_table_template, table_options); + Table& result=*new Table(date_calendar_table_template(), table_options); tm tmIn; memset(&tmIn, 0, sizeof(tmIn)); @@ -476,7 +489,7 @@ static Table& fill_week_days(Request& r, } static void _calendar(Request& r, MethodParams& params) { - const String& what=params.as_string(0, "format must be strig"); + const String& what=params.as_string(0, "format must be string"); bool rus=false; if(what=="rus") rus=true; @@ -491,7 +504,7 @@ static void _calendar(Request& r, Method else // 1+3 table=&fill_week_days(r, params, rus); - r.write_no_lang(*new VTable(table)); + r.write(*new VTable(table)); } static void _unix_timestamp(Request& r, MethodParams& params) { @@ -499,7 +512,7 @@ static void _unix_timestamp(Request& r, if(params.count()==0) { // ^date.unix-timestamp[] - r.write_no_lang(*new VDouble((double)vdate.get_time())); + r.write(*new VDouble((double)vdate.get_time())); } else { if(vdate.get_time()) throw Exception(PARSER_RUNTIME, 0, "date object already constructed"); @@ -522,7 +535,22 @@ static void _last_day(Request& r, Method // ^date.lastday[] tmIn=GET_SELF(r, VDate).get_tm(); } - r.write_no_lang(*new VInt(VDate::getMonthDays(tmIn.tm_year, tmIn.tm_mon))); + r.write(*new VInt(VDate::getMonthDays(tmIn.tm_year, tmIn.tm_mon))); +} + +static void _int(Request& r, MethodParams&) { + VDate& vdate=GET_SELF(r, VDate); + r.write(*new VInt(vdate.as_int())); +} + +static void _double(Request& r, MethodParams&) { + VDate& vdate=GET_SELF(r, VDate); + r.write(*new VDouble(vdate.as_double())); +} + +static void _bool(Request& r, MethodParams&) { + VDate& vdate=GET_SELF(r, VDate); + r.write(VBool::get(vdate.as_bool())); } // constructor @@ -533,7 +561,8 @@ MDate::MDate(): Methoded("date") { add_native_method("now", Method::CT_DYNAMIC, _now, 0, 1); // ^date::today[] - add_native_method("today", Method::CT_DYNAMIC, _today, 0, 0); + // ^date::today(offset int days) + add_native_method("today", Method::CT_DYNAMIC, _today, 0, 1); // ^date::create(float days) // ^date::create[date] @@ -545,13 +574,16 @@ MDate::MDate(): Methoded("date") { add_native_method("set", Method::CT_DYNAMIC, _create, 1, 7); // ^date.sql-string[] - add_native_method("sql-string", Method::CT_DYNAMIC, _sql_string, 0, 1); + // ^date:sql-string[] + add_native_method("sql-string", Method::CT_ANY, _sql_string, 0, 1); // ^date.gmt-string[] - add_native_method("gmt-string", Method::CT_DYNAMIC, _gmt_string, 0, 0); + // ^date:gmt-string[] + add_native_method("gmt-string", Method::CT_ANY, _gmt_string, 0, 0); // ^date.iso-string[$.colon(true) $.z(true) $.ms(false)] - add_native_method("iso-string", Method::CT_DYNAMIC, _iso_string, 0, 1); + // ^date:iso-string[...] + add_native_method("iso-string", Method::CT_ANY, _iso_string, 0, 1); // ^date:lastday(year;month) // ^date.lastday[] @@ -567,4 +599,13 @@ MDate::MDate(): Methoded("date") { // ^date.unix-timestamp[] // ^date::unix-timestamp(timestamp) add_native_method("unix-timestamp", Method::CT_DYNAMIC, _unix_timestamp, 0, 1); + + // date.int[default for ^string.int compatibility] + add_native_method("int", Method::CT_DYNAMIC, _int, 0, 1); + + // ^date.double[default for ^string.double compatibility] + add_native_method("double", Method::CT_DYNAMIC, _double, 0, 1); + + // ^date.bool[default for ^string.bool compatibility] + add_native_method("bool", Method::CT_DYNAMIC, _bool, 0, 1); }