Annotation of parser3/src/types/pa_vdate.C, revision 1.1

1.1     ! moko        1: /** @file
        !             2:        Parser: @b date parser class.
        !             3: 
        !             4:        Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com)
        !             5: */
        !             6: 
        !             7: #include "pa_vstateless_object.h"
        !             8: #include "pa_vdate.h"
        !             9: #include "pa_vint.h"
        !            10: #include "pa_vstring.h"
        !            11: 
        !            12: volatile const char * IDENT_PA_PA_VDATE_C="$Id: pa_vdate.C,v 1.1 2015/08/06 00:30:00 moko Exp $" IDENT_PA_VDATE_H;
        !            13: 
        !            14: static void set_tz(const char* tz, char* buf, size_t buf_size) {
        !            15: #ifndef WIN32
        !            16:        if(tz && *tz){
        !            17: #endif
        !            18:                snprintf(buf, buf_size, "TZ=%s", tz);
        !            19:                putenv(buf);
        !            20: #ifndef WIN32
        !            21:        } else
        !            22: #ifdef HAVE_UNSETENV
        !            23:         unsetenv("TZ");
        !            24: #else
        !            25:                putenv("TZ");
        !            26: #endif
        !            27: #endif
        !            28:        tzset();
        !            29: }
        !            30: 
        !            31: const String* VDate::get_sql_string(sql_string_type format) {
        !            32:        static const char* formats[]={
        !            33:                "%Y-%m-%d %H:%M:%S",
        !            34:                "%Y-%m-%d",
        !            35:                "%H:%M:%S"
        !            36:        };
        !            37:        static int sizes[]={
        !            38:                4+1+2+1+2 +1+ 2+1+2+1+2 +1/*terminator*/,
        !            39:                4+1+2+1+2 +1/*terminator*/,
        !            40:                2+1+2+1+2 +1/*terminator*/
        !            41:        };
        !            42:        size_t size=sizes[format];
        !            43:        char *buf=new(PointerFreeGC) char[size];
        !            44:        strftime(buf, size, formats[format], &get_localtime());
        !            45: 
        !            46:        return new String(buf);
        !            47: }
        !            48: 
        !            49: const String* VDate::get_gmt_string(){
        !            50:        return new String(date_gmt_string(gmtime(&ftime)));
        !            51: }
        !            52: 
        !            53: /// @TODO 'static' approach is NOT thread safe!
        !            54: tm&  VDate::get_localtime()
        !            55: {
        !            56:        char saved_tz[MAX_STRING];
        !            57:        static char saved_tz_pair[MAX_STRING]; // @TODO: this is NOT thread safe!
        !            58:        static char temp_tz_pair[MAX_STRING];
        !            59:        if(ftz_cstr) {
        !            60:                if(const char* ltz=getenv("TZ")) {
        !            61:                        strncpy(saved_tz, ltz, sizeof(saved_tz)-1);
        !            62:                        saved_tz[sizeof(saved_tz)-1]=0;
        !            63:                } else 
        !            64:                        saved_tz[0]=0;
        !            65:                
        !            66:                ::set_tz(ftz_cstr, temp_tz_pair, sizeof(temp_tz_pair));
        !            67:        }
        !            68:        tm *result=::localtime(&ftime);
        !            69:        if(ftz_cstr) {
        !            70:                ::set_tz(saved_tz, saved_tz_pair, sizeof(saved_tz_pair));
        !            71:        }
        !            72:        if(!result)
        !            73:                throw Exception(DATE_RANGE_EXCEPTION_TYPE, 0, "invalid datetime (after changing TZ)");
        !            74: 
        !            75:        return *result;
        !            76: }
        !            77: 
        !            78: override Value* VDate::get_element(const String& aname) {
        !            79:        // $method
        !            80:        if(Value* result=VStateless_object::get_element(aname))
        !            81:                return result;
        !            82: 
        !            83:        // $TZ
        !            84:        if(aname=="TZ") 
        !            85:                return ftz? new VString(*ftz): new VString();
        !            86: 
        !            87:        // $year month day  hour minute second  weekday
        !            88:        tm& tms=get_localtime();
        !            89: 
        !            90:        int result;
        !            91:        if(aname=="year") result=1900+tms.tm_year;
        !            92:        else if(aname=="month") result=1+tms.tm_mon;
        !            93:        else if(aname=="day") result=tms.tm_mday;
        !            94:        else if(aname=="hour") result=tms.tm_hour;
        !            95:        else if(aname=="minute") result=tms.tm_min;
        !            96:        else if(aname=="second") result=tms.tm_sec;
        !            97:        else if(aname=="weekday") result=tms.tm_wday;
        !            98:        else if(aname=="yearday") result=tms.tm_yday;
        !            99:        else if(aname=="daylightsaving") result=tms.tm_isdst;
        !           100:        else if(aname=="week") {
        !           101:                yw week = CalcWeek(tms);
        !           102:                result=week.week;
        !           103:        }
        !           104:        else if(aname=="weekyear") {
        !           105:                yw week = CalcWeek(tms);
        !           106:                result=1900+week.year;
        !           107:        } else { return bark("%s field not found", &aname); }
        !           108:        return new VInt(result);
        !           109: }
        !           110: 
        !           111: const String* VDate::get_json_string(Json_options& options) {
        !           112:        String* result=new String();
        !           113:        switch(options.date){
        !           114:                case Json_options::D_SQL:
        !           115:                        result->append_quoted(get_sql_string());
        !           116:                        break;
        !           117:                case Json_options::D_GMT:
        !           118:                        result->append_quoted(get_gmt_string());
        !           119:                        break;
        !           120:                case Json_options::D_TIMESTAMP:
        !           121:                        *result << format((int)ftime, 0);
        !           122:                        break;
        !           123:        }
        !           124:        return result;
        !           125: }

E-mail: