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

1.1       parser      1: /** @file
                      2:        Parser: @b date parser class decl.
                      3: 
1.53      moko        4:        Copyright (c) 2001-2012 Art. Lebedev Studio (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.56    ! moko       11: #define IDENT_PA_VDATE_H "$Id: pa_vdate.h,v 1.55 2012/05/28 19:47:52 moko Exp $"
1.1       parser     12: 
                     13: #include "classes.h"
                     14: #include "pa_common.h"
                     15: #include "pa_vstateless_object.h"
1.56    ! moko       16: #include "pa_vdouble.h"
1.1       parser     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: 
                     26: /// value of type 'date'. implemented with @c time_t
1.25      paf        27: class VDate: public VStateless_object {
1.1       parser     28: public: // Value
                     29: 
1.25      paf        30:        override const char* type() const { return VDATE_TYPE; }
                     31:        override VStateless_class *get_class() { return date_class; }
1.10      paf        32:        
1.51      misha      33:        /// VDate: json-string
1.56    ! moko       34:        override const String* get_json_string(Json_options& options);
1.51      misha      35: 
1.1       parser     36:        /// VDate: ftime -> float days
1.54      moko       37:        override Value& as_expr_result() { return *new VDouble(as_double()); }
1.1       parser     38: 
1.46      misha      39:        /// VDate: true
                     40:        override bool is_evaluated_expr() const { return true; }
                     41: 
1.1       parser     42:        /// VDate: ftime -> float days
1.25      paf        43:        override double as_double() const { return ((double)ftime)/ SECS_PER_DAY; }
1.46      misha      44: 
1.1       parser     45:        /// VDate: 0 or !0
1.25      paf        46:        override bool as_bool() const { return ftime!=0; }
1.1       parser     47: 
1.56    ! moko       48:        tm& get_localtime();
1.35      paf        49: 
1.52      misha      50:        enum sql_string_type {sql_string_datetime, sql_string_date, sql_string_time};
                     51: 
1.56    ! moko       52:        const String* get_sql_string(sql_string_type format = sql_string_datetime);
        !            53:        const String* get_gmt_string();
1.1       parser     54: 
1.15      paf        55:        /// VDate: method,field
1.56    ! moko       56:        override Value* get_element(const String& aname);
1.1       parser     57: 
                     58: public: // usage
                     59: 
1.56    ! moko       60:        VDate(time_t adate) :
1.27      paf        61:                ftz(0),
                     62:                ftz_cstr(0) {
1.33      paf        63:                set_time(adate);
1.27      paf        64:        }
1.1       parser     65: 
1.56    ! moko       66:        VDate(tm tmIn) :
1.32      paf        67:                ftime(0),
                     68:                ftz(0),
                     69:                ftz_cstr(0) {
                     70:                set_time(tmIn);
                     71:        }
                     72: 
1.19      paf        73:        time_t get_time() const { return ftime; }
1.56    ! moko       74: 
        !            75:        void set_time(time_t atime) {
        !            76:                if(atime==-1)
        !            77:                        throw Exception(DATE_RANGE_EXCEPTION_TYPE, 0, "invalid datetime");
        !            78:                ftime=atime;
1.32      paf        79:        }
1.56    ! moko       80: 
        !            81:        void set_time(tm tmIn) {
1.32      paf        82:                time_t t=mktime(&tmIn);
1.56    ! moko       83:                if(t==-1) {
1.32      paf        84:                        // on some platforms mktime does not fix spring daylightsaving time hole
                     85:                        // in russia -- last sunday of march, 2am->3am hole
                     86:                        // trying to recover:
                     87:                        tmIn.tm_hour--;
                     88:                        t=mktime(&tmIn);
                     89:                }
                     90:                set_time(t);
                     91:        }
1.56    ! moko       92: 
1.27      paf        93:        void set_tz(const String* atz) { 
1.30      paf        94:                if((ftz=atz))
1.27      paf        95:                        ftz_cstr=ftz->cstr();
1.40      paf        96:        }
                     97: 
1.44      misha      98:        struct yw {
                     99:                int year;
                    100:                int week;
                    101:        }; 
                    102:        
                    103:        static yw CalcWeek(tm& tms) {
                    104:                yw week = {tms.tm_year, 0};
                    105: 
1.40      paf       106:                // http://www.merlyn.demon.co.uk/weekinfo.htm
1.44      misha     107:                static const unsigned 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};
                    108:                int diff = tms.tm_yday-(FirstThurs[(tms.tm_year+1900) % 28]-4);
                    109:                if (diff < 0){
                    110:                        tms.tm_mday = diff;
1.45      misha     111:                        mktime(&tms); // normalize
1.44      misha     112:                        week = CalcWeek(tms);
                    113:                } else {
                    114:                        week.week = 1 + diff/7;
                    115:                        if ( week.week > 52 && ISOWeekCount(week.year) < week.week ){
                    116:                                week.year++;
                    117:                                week.week = 1;
                    118:                        }
                    119:        }
                    120:                return week;
                    121:        }
                    122: 
                    123:        static int ISOWeekCount (int year) {
                    124:                static const unsigned int YearWeeks[] = {
                    125:                        52,52,52,52,53, 52,52,52,52,52,
                    126:                        53,52,52,52,52, 52,53,52,52,52,
                    127:                        52,53,52,52,52, 52,52,53
                    128:                };
                    129:                return YearWeeks[(year+1900) % 28];
1.27      paf       130:        }
1.1       parser    131: 
                    132: private:
                    133:        time_t ftime;
1.27      paf       134:        const String* ftz;
                    135:        const char* ftz_cstr;
1.1       parser    136: 
                    137: };
                    138: 
                    139: #endif

E-mail: