Annotation of parser3/src/types/pa_vdate.h, revision 1.38.6.2

1.1       parser      1: /** @file
                      2:        Parser: @b date parser class decl.
                      3: 
1.38.6.1  paf         4:        Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)
1.8       paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       parser      6: */
                      7: 
                      8: #ifndef PA_VDATE_H
                      9: #define PA_VDATE_H
1.11      paf        10: 
1.38.6.2! paf        11: static const char * const IDENT_VDATE_H="$Date: 2005/08/05 13:03:04 $";
1.1       parser     12: 
                     13: #include "classes.h"
                     14: #include "pa_common.h"
                     15: #include "pa_vstateless_object.h"
                     16: #include "pa_vint.h"
                     17: 
1.9       paf        18: // defines
                     19: 
                     20: #define VDATE_TYPE "date"
1.20      paf        21: 
1.9       paf        22: // externs
                     23: 
1.25      paf        24: extern Methoded* date_class;
1.1       parser     25: 
1.27      paf        26: inline void set_tz(const char* tz, char* buf, size_t buf_size) {
1.38      paf        27:        if(tz){
                     28:            snprintf(buf, buf_size, "TZ=%s", tz);
                     29:            putenv(buf);
                     30:        } else
                     31:            putenv("TZ");
1.27      paf        32:        tzset();
                     33: }
                     34: 
1.1       parser     35: /// value of type 'date'. implemented with @c time_t
1.25      paf        36: class VDate: public VStateless_object {
1.1       parser     37: public: // Value
                     38: 
1.25      paf        39:        override const char* type() const { return VDATE_TYPE; }
                     40:        override VStateless_class *get_class() { return date_class; }
1.10      paf        41:        
1.1       parser     42:        /// VDate: ftime -> float days
1.28      paf        43:        override Value& as_expr_result(bool /*return_string_as_is=false*/) { return *new VDouble(as_double()); }
1.1       parser     44: 
                     45:        /// VDate: ftime -> float days
1.25      paf        46:        override double as_double() const { return ((double)ftime)/ SECS_PER_DAY; }
1.1       parser     47:        /// VDate: 0 or !0
1.25      paf        48:        override bool as_bool() const { return ftime!=0; }
1.1       parser     49: 
1.38.6.2! paf        50:        tm& get_localtime()
1.35      paf        51:        {
                     52:                const char* saved_tz=0;
                     53:                static char saved_tz_pair[MAX_STRING];
                     54:                static char temp_tz_pair[MAX_STRING];
                     55:                if(ftz_cstr) {
                     56:                        saved_tz=getenv("TZ");
                     57:                        ::set_tz(ftz_cstr, temp_tz_pair, sizeof(temp_tz_pair));
                     58:                }
                     59:                tm *result=::localtime(&ftime);
1.38      paf        60:                if(ftz_cstr) {
1.35      paf        61:                        ::set_tz(saved_tz, saved_tz_pair, sizeof(saved_tz_pair));
1.38      paf        62:                }                       
1.35      paf        63:                if(!result)
                     64:                        throw Exception(0,
                     65:                                0,
                     66:                                "invalid datetime (after changing TZ)");
                     67: 
1.38.6.2! paf        68:                return *result;
1.35      paf        69:        }
                     70: 
1.1       parser     71: 
1.15      paf        72:        /// VDate: method,field
1.25      paf        73:        override Value* get_element(const String& aname, Value& aself, bool looking_up) {
1.15      paf        74:                // $method
1.25      paf        75:                if(Value* result=VStateless_object::get_element(aname, aself, looking_up))
1.1       parser     76:                        return result;
                     77: 
1.27      paf        78:                // $TZ
                     79:                if(aname=="TZ") 
1.37      paf        80:                        return ftz? new VString(*ftz): new VString();
1.27      paf        81: 
1.1       parser     82:                // $year month day  hour minute second  weekday
1.38.6.2! paf        83:                tm& tms=get_localtime();
1.27      paf        84: 
1.1       parser     85:                int result;
1.38.6.2! paf        86:                if(aname=="year") result=1900+tms.tm_year;
        !            87:                else if(aname=="month") result=1+tms.tm_mon;
        !            88:                else if(aname=="day") result=tms.tm_mday;
        !            89:                else if(aname=="hour") result=tms.tm_hour;
        !            90:                else if(aname=="minute") result=tms.tm_min;
        !            91:                else if(aname=="second") result=tms.tm_sec;
        !            92:                else if(aname=="weekday") result=tms.tm_wday;
        !            93:                else if(aname=="yearday") result=tms.tm_yday;
        !            94:                else if(aname=="daylightsaving") result=tms.tm_isdst;
        !            95:                else if(aname=="week") result=week_no(tms);
1.26      paf        96:                else { return bark("%s field not found", &aname); }
1.25      paf        97:                return new VInt(result);
1.1       parser     98:        }
                     99: 
                    100: public: // usage
                    101: 
1.27      paf       102:        VDate(time_t adate) : 
                    103:                ftz(0),
                    104:                ftz_cstr(0) {
1.33      paf       105:                set_time(adate);
1.27      paf       106:        }
1.1       parser    107: 
1.32      paf       108:        VDate(tm tmIn) : 
                    109:                ftime(0),
                    110:                ftz(0),
                    111:                ftz_cstr(0) {
                    112:                set_time(tmIn);
                    113:        }
                    114: 
1.19      paf       115:        time_t get_time() const { return ftime; }
1.32      paf       116:        void set_time(time_t atime) { 
                    117:                if(atime<0)
                    118:                        throw Exception(0,
                    119:                                0,
                    120:                                "invalid datetime");
                    121:                ftime=atime; 
                    122:        }
                    123:        void set_time(tm tmIn) { 
                    124:                time_t t=mktime(&tmIn);
                    125:                if(t<0) {
                    126:                        // on some platforms mktime does not fix spring daylightsaving time hole
                    127:                        // in russia -- last sunday of march, 2am->3am hole
                    128:                        // trying to recover:
                    129:                        tmIn.tm_hour--;
                    130:                        t=mktime(&tmIn);
                    131:                }
                    132:                set_time(t);
                    133:        }
1.27      paf       134:        void set_tz(const String* atz) { 
1.30      paf       135:                if((ftz=atz))
1.27      paf       136:                        ftz_cstr=ftz->cstr();
1.38.6.2! paf       137:        }
        !           138: 
        !           139:        static int week_no(tm& tms) {
        !           140:                // http://www.merlyn.demon.co.uk/weekinfo.htm
        !           141:                int weekyear=tms.tm_year+1900;
        !           142:                const int FirstThurs[] = {7,5,4,3,2,7,6,5,4,2,1,7,6,4,3,2,1,6,5,4,3,1,7,6,5,3,2,1};
        !           143:                return 1 + (tms.tm_yday-(FirstThurs[weekyear % 28]-3))/7;
1.27      paf       144:        }
1.1       parser    145: 
                    146: private:
                    147: 
                    148:        time_t ftime;
1.27      paf       149:        const String* ftz;
                    150:        const char* ftz_cstr;
1.1       parser    151: 
                    152: };
                    153: 
                    154: #endif

E-mail: