Annotation of parser3/src/classes/date.C, revision 1.1

1.1     ! parser      1: /** @file
        !             2:        Parser: @b date parser class.
        !             3: 
        !             4:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
        !             5: 
        !             6:        Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
        !             7: 
        !             8:        $Id: date.C,v 1.28 2001/06/28 07:44:17 parser Exp $
        !             9: */
        !            10: static const char *RCSId="$Id: date.C,v 1.28 2001/06/28 07:44:17 parser Exp $"; 
        !            11: 
        !            12: #include "classes.h"
        !            13: #include "pa_request.h"
        !            14: #include "pa_vdouble.h"
        !            15: #include "pa_vdate.h"
        !            16: 
        !            17: // defines
        !            18: 
        !            19: #define DATE_CLASS_NAME "date"
        !            20: 
        !            21: // class
        !            22: 
        !            23: class MDate : public Methoded {
        !            24: public: // VStateless_class
        !            25:        Value *create_new_value(Pool& pool) { return new(pool) VDate(pool, 0); }
        !            26: 
        !            27: public:
        !            28:        MDate(Pool& pool);
        !            29: public: // Methoded
        !            30:        bool used_directly() { return true; }
        !            31: };
        !            32: 
        !            33: // methods
        !            34: 
        !            35: static void _now(Request& r, const String& method_name, MethodParams *) {
        !            36:        Pool& pool=r.pool();
        !            37:        VDate *vdate=static_cast<VDate *>(r.self);
        !            38:        vdate->set_time(time(0));
        !            39: }
        !            40: 
        !            41: static void _set(Request& r, const String& method_name, MethodParams *params) {
        !            42:        Pool& pool=r.pool();
        !            43:        VDate *vdate=static_cast<VDate *>(r.self);
        !            44: 
        !            45:        time_t time;
        !            46:        if(params->size()==1) // ^set(float days)
        !            47:                time=(time_t)(params->as_double(0, r)*SECS_PER_DAY);
        !            48:        else if(params->size()>=3) { // ^set(y;m;d[;h[;m[;s]]])
        !            49:                tm tmIn={0};
        !            50:                tmIn.tm_isdst=-1;
        !            51:                int year=params->as_int(0, r);
        !            52:                if(year<70) // 0..69 -> 100..169 [2000..2069]
        !            53:                        year+=100;
        !            54:                tmIn.tm_year=year;
        !            55:                tmIn.tm_mon=params->as_int(1, r)-1;
        !            56:                tmIn.tm_mday=params->as_int(2, r);
        !            57:                if(params->size()>3) tmIn.tm_hour=params->as_int(3, r);
        !            58:                if(params->size()>4) tmIn.tm_min=params->as_int(4, r);
        !            59:                if(params->size()>5) tmIn.tm_sec=params->as_int(5, r);
        !            60:                time=mktime(&tmIn);
        !            61:                if(time<0)
        !            62:                        PTHROW(0, 0,
        !            63:                                &method_name,
        !            64:                                "invalid datetime");
        !            65:        } else
        !            66:                PTHROW(0, 0,
        !            67:                        &method_name,
        !            68:                        "invalid params count, must be 1 or >=3");
        !            69:        vdate->set_time(time);
        !            70: }
        !            71: 
        !            72: static void _string(Request& r, const String& method_name, MethodParams *) {
        !            73:        Pool& pool=r.pool();
        !            74:        VDate *vdate=static_cast<VDate *>(r.self);
        !            75:        int size=4+1+2+1+2 +1+ 2+1+2+1+2 +1;
        !            76:        char *buf=(char *)pool.malloc(size);
        !            77:        time_t time=vdate->get_time();
        !            78:        size=strftime(buf, size, "%Y-%m-%d %H:%M:%S", gmtime(&time));
        !            79:        
        !            80:        Value& result=*new(pool) VString(*new(pool) String(pool, buf, size));
        !            81:        r.write_assign_lang(result);
        !            82: }
        !            83: 
        !            84: 
        !            85: static int isLeap(int year) {
        !            86:     return !(
        !            87:              (year % 4) || ((year % 400) && !(year % 100))
        !            88:             );
        !            89: }
        !            90: 
        !            91: static int getMonthDays(int year, int month) {
        !            92:     int monthDays[]={
        !            93:         31,
        !            94:         isLeap(year) ? 29 : 28,
        !            95:         31,
        !            96:         30,
        !            97:         31,
        !            98:         30,
        !            99:         31,
        !           100:         31,
        !           101:         30,
        !           102:         31,
        !           103:         30,
        !           104:         31
        !           105:     };
        !           106:     return monthDays[month];
        !           107: }
        !           108: 
        !           109: static void _roll(Request& r, const String& method_name, MethodParams *params) {
        !           110:        Pool& pool=r.pool();
        !           111:        VDate *vdate=static_cast<VDate *>(r.self);
        !           112: 
        !           113:        const String& what=params->as_string(0, "'what' must be string");
        !           114:     int oyear=0;
        !           115:     int omonth=0;
        !           116:     int oday=0;
        !           117:        int *offset;
        !           118:        if(what=="year") offset=&oyear;
        !           119:        else if(what=="month") offset=&omonth;
        !           120:        else if(what=="day") offset=&oday;
        !           121:        else
        !           122:                PTHROW(0, 0,
        !           123:                        &what,
        !           124:                        "must be year|month|day");
        !           125:        
        !           126:        *offset=params->as_int(1, r);
        !           127:        if(!(*offset==1 || *offset==-1))
        !           128:                PTHROW(0, 0,
        !           129:                        &method_name,
        !           130:                        "offset must be +/- 1");
        !           131: 
        !           132:        time_t tIn=vdate->get_time();
        !           133:     tm *tmIn=localtime(&tIn);
        !           134:        tmIn->tm_year+=oyear;
        !           135:        time_t t=mktime(tmIn);
        !           136:        if(t<0)
        !           137:                PTHROW(0, 0,
        !           138:                        &method_name,
        !           139:                        "invalid datetime");
        !           140:        t+=omonth*getMonthDays(tmIn->tm_year, (tmIn->tm_mon+(omonth<0?-1:0)+12)%12)*SECS_PER_DAY;
        !           141:     t+=oday*SECS_PER_DAY;
        !           142:        vdate->set_time(t);
        !           143: }
        !           144: 
        !           145: // constructor
        !           146: 
        !           147: MDate::MDate(Pool& apool) : Methoded(apool) {
        !           148:        set_name(*NEW String(pool(), DATE_CLASS_NAME));
        !           149: 
        !           150: 
        !           151:        // ^now[]
        !           152:        add_native_method("now", Method::CT_DYNAMIC, _now, 0, 0);
        !           153: 
        !           154:        // ^set(float days)
        !           155:        add_native_method("set", Method::CT_DYNAMIC, _set, 1, 6);
        !           156: 
        !           157:        // ^string[]
        !           158:        add_native_method("string", Method::CT_DYNAMIC, _string, 0, 0);
        !           159: 
        !           160:        // ^roll(year|month|day;+/- 1)
        !           161:        add_native_method("roll", Method::CT_DYNAMIC, _roll, 2, 2);
        !           162: 
        !           163: }
        !           164: // global variable
        !           165: 
        !           166: Methoded *date_class;
        !           167: 
        !           168: // creator
        !           169: 
        !           170: Methoded *MDate_create(Pool& pool) {
        !           171:        return date_class=new(pool) MDate(pool);
        !           172: }

E-mail: