|
|
| version 1.7, 2001/09/21 14:46:09 | version 1.10, 2001/10/09 13:17:45 |
|---|---|
| Line 2 | Line 2 |
| Parser: @b date parser class. | Parser: @b date parser class. |
| Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) | Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) |
| $Id$ | |
| */ | */ |
| static const char *RCSId="$Id$"; | |
| #include "classes.h" | #include "classes.h" |
| #include "pa_request.h" | #include "pa_request.h" |
| #include "pa_vdouble.h" | #include "pa_vdouble.h" |
| #include "pa_vdate.h" | #include "pa_vdate.h" |
| #include "pa_vtable.h" | |
| // defines | // defines |
| Line 42 static void _set(Request& r, const Strin | Line 43 static void _set(Request& r, const Strin |
| time_t time; | time_t time; |
| if(params->size()==1) // ^set(float days) | if(params->size()==1) // ^set(float days) |
| time=(time_t)(params->as_double(0, r)*SECS_PER_DAY); | time=(time_t)(params->as_double(0, "float days must be double", r)*SECS_PER_DAY); |
| else if(params->size()>=3) { // ^set(y;m;d[;h[;m[;s]]]) | else if(params->size()>=3) { // ^set(y;m;d[;h[;m[;s]]]) |
| tm tmIn={0}; | tm tmIn={0}; |
| tmIn.tm_isdst=-1; | tmIn.tm_isdst=-1; |
| int year=params->as_int(0, r); | int year=params->as_int(0, "year must be int", r); |
| if(year<70) // 0..69 -> 100..169 [2000..2069] | if(year<70) // 0..69 -> 100..169 [2000..2069] |
| year+=100; | year+=100; |
| if(year>=1900) | if(year>=1900) |
| year-=1900; | year-=1900; |
| tmIn.tm_year=year; | tmIn.tm_year=year; |
| tmIn.tm_mon=params->as_int(1, r)-1; | tmIn.tm_mon=params->as_int(1, "month must be int", r)-1; |
| tmIn.tm_mday=params->as_int(2, r); | tmIn.tm_mday=params->as_int(2, "mday must be int", r); |
| if(params->size()>3) tmIn.tm_hour=params->as_int(3, r); | if(params->size()>3) tmIn.tm_hour=params->as_int(3, "hour must be int", r); |
| if(params->size()>4) tmIn.tm_min=params->as_int(4, r); | if(params->size()>4) tmIn.tm_min=params->as_int(4, "minutes must be int", r); |
| if(params->size()>5) tmIn.tm_sec=params->as_int(5, r); | if(params->size()>5) tmIn.tm_sec=params->as_int(5, "seconds must be int", r); |
| time=mktime(&tmIn); | time=mktime(&tmIn); |
| if(time<0) | if(time<0) |
| PTHROW(0, 0, | PTHROW(0, 0, |
| Line 103 static void _roll(Request& r, const Stri | Line 104 static void _roll(Request& r, const Stri |
| &what, | &what, |
| "must be year|month|day"); | "must be year|month|day"); |
| *offset=params->as_int(1, r); | *offset=params->as_int(1, "offset must be int", r); |
| if(!(*offset==1 || *offset==-1)) | if(!(*offset==1 || *offset==-1)) |
| PTHROW(0, 0, | PTHROW(0, 0, |
| &method_name, | &method_name, |
| Line 122 static void _roll(Request& r, const Stri | Line 123 static void _roll(Request& r, const Stri |
| vdate->set_time(t); | vdate->set_time(t); |
| } | } |
| static Table *fill_month_days(Request& r, | |
| const String& method_name, MethodParams *params, bool rus){ | |
| Pool& pool=r.pool(); | |
| Table *result=new(pool) Table(pool, &method_name, 0/*&columns*/); | |
| int year=params->as_int(1, "year must be int", r); | |
| int month=max(1, min(params->as_int(2, "month must be int", r), 12)) -1; | |
| tm tmIn={0, 0, 0, 1, month, year-1900}; | |
| time_t t=mktime(&tmIn); | |
| if(t<0) | |
| PTHROW(0, 0, | |
| &method_name, | |
| "invalid date"); | |
| tm *tmOut=localtime(&t); | |
| int weekDay1=tmOut->tm_wday; | |
| if(rus) | |
| weekDay1=weekDay1?weekDay1-1:6; //sunday last | |
| int monthDays=getMonthDays(year, month); | |
| for(int _day=1-weekDay1; _day<=monthDays;) { | |
| Array& row=*new(pool) Array(pool, 7); | |
| for(int wday=0; wday<7; wday++, _day++) { | |
| String *cell=new(pool) String(pool); | |
| if(_day>=1 && _day<=monthDays) { | |
| char *buf=(char *)pool.malloc(2+1); | |
| cell->APPEND_CLEAN(buf, sprintf(buf, "%02d", _day), | |
| method_name.origin().file, method_name.origin().line); | |
| } | |
| row+=cell; | |
| } | |
| *result+=&row; | |
| } | |
| return result; | |
| } | |
| static Table *fill_week_days(Request& r, | |
| const String& method_name, MethodParams *params, bool rus){ | |
| Pool& pool=r.pool(); | |
| Array& columns=*new(pool) Array(pool, 4); | |
| Table *result=new(pool) Table(pool, &method_name, &columns); | |
| int year=params->as_int(1, "year must be int", r); | |
| int month=max(1, min(params->as_int(2, "month must be int", r), 12)) -1; | |
| int day=params->as_int(3, "day must be int", r); | |
| tm tmIn={0, 0, 18, day, month, year-1900}; | |
| time_t t=mktime(&tmIn); | |
| if(t<0) | |
| PTHROW(0, 0, | |
| &method_name, | |
| "invalid date"); | |
| tm *tmOut=localtime(&t); | |
| int baseWeekDay=tmOut->tm_wday; | |
| if(rus) | |
| baseWeekDay=baseWeekDay?baseWeekDay-1:6; //sunday last | |
| t-=baseWeekDay*SECS_PER_DAY; | |
| for(int curWeekDay=0; curWeekDay<7; curWeekDay++, t+=SECS_PER_DAY) { | |
| tm *tmOut=localtime(&t); | |
| Array& row=*new(pool) Array(pool, 4); | |
| #define WDFILL(size, value) { \ | |
| char *buf=(char *)pool.malloc(size+1); \ | |
| String *cell=new(pool) String(pool); \ | |
| cell->APPEND_CLEAN(buf, sprintf(buf, "%0"#size"d", value), \ | |
| method_name.origin().file, \ | |
| method_name.origin().line); \ | |
| row+=cell; \ | |
| } | |
| WDFILL(4, 1900+tmOut->tm_year); | |
| WDFILL(2, 1+tmOut->tm_mon); | |
| WDFILL(2, tmOut->tm_mday); | |
| WDFILL(2, tmOut->tm_wday); | |
| *result+=&row; | |
| } | |
| return result; | |
| } | |
| static void _calendar(Request& r, const String& method_name, MethodParams *params) { | |
| Pool& pool=r.pool(); | |
| const String& what=params->as_string(0, "format must be strig"); | |
| bool rus=false; | |
| if(what=="rus") | |
| rus=true; | |
| else if(what=="eng") | |
| rus=false; | |
| else | |
| PTHROW(0, 0, | |
| &what, | |
| "must be rus|eng"); | |
| Table *table; | |
| if(params->size()==1+2) | |
| table=fill_month_days(r, method_name, params, rus); | |
| else // 1+3 | |
| table=fill_week_days(r, method_name, params, rus); | |
| VTable& result=*new(pool) VTable(pool, table); | |
| result.set_name(method_name); | |
| r.write_no_lang(result); | |
| } | |
| // constructor | // constructor |
| MDate::MDate(Pool& apool) : Methoded(apool) { | MDate::MDate(Pool& apool) : Methoded(apool) { |
| Line 140 MDate::MDate(Pool& apool) : Methoded(apo | Line 249 MDate::MDate(Pool& apool) : Methoded(apo |
| // ^roll(year|month|day;+/- 1) | // ^roll(year|month|day;+/- 1) |
| add_native_method("roll", Method::CT_DYNAMIC, _roll, 2, 2); | add_native_method("roll", Method::CT_DYNAMIC, _roll, 2, 2); |
| // ^date:calendar[month|montheng;year;month] = table | |
| // ^date:calendar[week|weekeng;year;month;day] = table | |
| add_native_method("calendar", Method::CT_STATIC, _calendar, 3, 4); | |
| } | } |
| // global variable | // global variable |