Annotation of embedaddon/php/ext/date/lib/unixtime2tm.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2010 The PHP Group                                |
        !             6:    +----------------------------------------------------------------------+
        !             7:    | This source file is subject to version 3.01 of the PHP license,      |
        !             8:    | that is bundled with this package in the file LICENSE, and is        |
        !             9:    | available through the world-wide-web at the following url:           |
        !            10:    | http://www.php.net/license/3_01.txt                                  |
        !            11:    | If you did not receive a copy of the PHP license and are unable to   |
        !            12:    | obtain it through the world-wide-web, please send a note to          |
        !            13:    | license@php.net so we can mail you a copy immediately.               |
        !            14:    +----------------------------------------------------------------------+
        !            15:    | Authors: Derick Rethans <derick@derickrethans.nl>                    |
        !            16:    +----------------------------------------------------------------------+
        !            17:  */
        !            18: 
        !            19: /* $Id: unixtime2tm.c 319767 2011-11-24 17:13:47Z derick $ */
        !            20: 
        !            21: #include "timelib.h"
        !            22: 
        !            23: #include <stdio.h>
        !            24: 
        !            25: #ifdef HAVE_STDLIB_H
        !            26: #include <stdlib.h>
        !            27: #endif
        !            28: 
        !            29: #ifdef HAVE_STRING_H
        !            30: #include <string.h>
        !            31: #else
        !            32: #include <strings.h>
        !            33: #endif
        !            34: 
        !            35: static int month_tab_leap[12] = { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
        !            36: static int month_tab[12] =      { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
        !            37: 
        !            38: 
        !            39: /* Converts a Unix timestamp value into broken down time, in GMT */
        !            40: void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts)
        !            41: {
        !            42:        timelib_sll days, remainder, tmp_days;
        !            43:        timelib_sll cur_year = 1970;
        !            44:        timelib_sll i;
        !            45:        timelib_sll hours, minutes, seconds;
        !            46:        int *months;
        !            47: 
        !            48:        days = ts / SECS_PER_DAY;
        !            49:        remainder = ts - (days * SECS_PER_DAY);
        !            50:        if (ts < 0 && remainder == 0) {
        !            51:                days++;
        !            52:                remainder -= SECS_PER_DAY;
        !            53:        }
        !            54:        TIMELIB_DEBUG(printf("days=%lld, rem=%lld\n", days, remainder););
        !            55: 
        !            56:        if (ts >= 0) {
        !            57:                tmp_days = days + 1;
        !            58: 
        !            59:                if (tmp_days >= DAYS_PER_LYEAR_PERIOD || tmp_days <= -DAYS_PER_LYEAR_PERIOD) {
        !            60:                        cur_year += YEARS_PER_LYEAR_PERIOD * (tmp_days / DAYS_PER_LYEAR_PERIOD);
        !            61:                        tmp_days -= DAYS_PER_LYEAR_PERIOD * (tmp_days / DAYS_PER_LYEAR_PERIOD);
        !            62:                }
        !            63: 
        !            64:                while (tmp_days >= DAYS_PER_LYEAR) {
        !            65:                        cur_year++;
        !            66:                        if (timelib_is_leap(cur_year)) {
        !            67:                                tmp_days -= DAYS_PER_LYEAR;
        !            68:                        } else {
        !            69:                                tmp_days -= DAYS_PER_YEAR;
        !            70:                        }
        !            71:                }
        !            72:        } else {
        !            73:                tmp_days = days;
        !            74: 
        !            75:                /* Guess why this might be for, it has to do with a pope ;-). It's also
        !            76:                 * only valid for Great Brittain and it's colonies. It needs fixing for
        !            77:                 * other locales. *sigh*, why is this crap so complex! */
        !            78:                /*
        !            79:                if (ts <= TIMELIB_LL_CONST(-6857352000)) {
        !            80:                        tmp_days -= 11;
        !            81:                }
        !            82:                */
        !            83: 
        !            84:                while (tmp_days <= 0) {
        !            85:                        if (tmp_days < -1460970) {
        !            86:                                cur_year -= 4000;
        !            87:                                TIMELIB_DEBUG(printf("tmp_days=%lld, year=%lld\n", tmp_days, cur_year););
        !            88:                                tmp_days += 1460970;
        !            89:                        } else {
        !            90:                                cur_year--;
        !            91:                                TIMELIB_DEBUG(printf("tmp_days=%lld, year=%lld\n", tmp_days, cur_year););
        !            92:                                if (timelib_is_leap(cur_year)) {
        !            93:                                        tmp_days += DAYS_PER_LYEAR;
        !            94:                                } else {
        !            95:                                        tmp_days += DAYS_PER_YEAR;
        !            96:                                }
        !            97:                        }
        !            98:                }
        !            99:                remainder += SECS_PER_DAY;
        !           100:        }
        !           101:        TIMELIB_DEBUG(printf("tmp_days=%lld, year=%lld\n", tmp_days, cur_year););
        !           102: 
        !           103:        months = timelib_is_leap(cur_year) ? month_tab_leap : month_tab;
        !           104:        if (timelib_is_leap(cur_year) && cur_year < 1970) {
        !           105:                tmp_days--;
        !           106:        }
        !           107:        i = 11;
        !           108:        while (i > 0) {
        !           109:                TIMELIB_DEBUG(printf("month=%lld (%d)\n", i, months[i]););
        !           110:                if (tmp_days > months[i]) {
        !           111:                        break;
        !           112:                }
        !           113:                i--;
        !           114:        }
        !           115:        TIMELIB_DEBUG(printf("A: ts=%lld, year=%lld, month=%lld, day=%lld,", ts, cur_year, i + 1, tmp_days - months[i]););
        !           116: 
        !           117:        /* That was the date, now we do the tiiiime */
        !           118:        hours = remainder / 3600;
        !           119:        minutes = (remainder - hours * 3600) / 60;
        !           120:        seconds = remainder % 60;
        !           121:        TIMELIB_DEBUG(printf(" hour=%lld, minute=%lld, second=%lld\n", hours, minutes, seconds););
        !           122: 
        !           123:        tm->y = cur_year;
        !           124:        tm->m = i + 1;
        !           125:        tm->d = tmp_days - months[i];
        !           126:        tm->h = hours;
        !           127:        tm->i = minutes;
        !           128:        tm->s = seconds;
        !           129:        tm->z = 0;
        !           130:        tm->dst = 0;
        !           131:        tm->sse = ts;
        !           132:        tm->sse_uptodate = 1;
        !           133:        tm->tim_uptodate = 1;
        !           134:        tm->is_localtime = 0;
        !           135: }
        !           136: 
        !           137: void timelib_update_from_sse(timelib_time *tm)
        !           138: {
        !           139:        timelib_sll sse;
        !           140: 
        !           141:        sse = tm->sse;
        !           142:        
        !           143:        switch (tm->zone_type) {
        !           144:                case TIMELIB_ZONETYPE_ABBR:
        !           145:                case TIMELIB_ZONETYPE_OFFSET: {
        !           146:                        int z = tm->z;
        !           147:                        signed int dst = tm->dst;
        !           148:                        
        !           149:                        timelib_unixtime2gmt(tm, tm->sse - (tm->z * 60) + (tm->dst * 3600));
        !           150: 
        !           151:                        tm->z = z;
        !           152:                        tm->dst = dst;
        !           153:                        goto cleanup;
        !           154:                }
        !           155: 
        !           156:                case TIMELIB_ZONETYPE_ID: {
        !           157:                        timelib_time_offset *gmt_offset;
        !           158:                        
        !           159:                        gmt_offset = timelib_get_time_zone_info(tm->sse, tm->tz_info);
        !           160:                        timelib_unixtime2gmt(tm, tm->sse + gmt_offset->offset);
        !           161:                        timelib_time_offset_dtor(gmt_offset);
        !           162:                        
        !           163:                        goto cleanup;
        !           164:                }
        !           165: 
        !           166:                default:
        !           167:                        timelib_unixtime2gmt(tm, tm->sse);
        !           168:                        goto cleanup;
        !           169:        }
        !           170: cleanup:
        !           171:        tm->sse = sse;
        !           172:        tm->is_localtime = 1;
        !           173:        tm->have_zone = 1;
        !           174: }
        !           175: 
        !           176: void timelib_unixtime2local(timelib_time *tm, timelib_sll ts)
        !           177: {
        !           178:        timelib_time_offset *gmt_offset;
        !           179:        timelib_tzinfo      *tz = tm->tz_info;
        !           180: 
        !           181:        switch (tm->zone_type) {
        !           182:                case TIMELIB_ZONETYPE_ABBR:
        !           183:                case TIMELIB_ZONETYPE_OFFSET: {
        !           184:                        int z = tm->z;
        !           185:                        signed int dst = tm->dst;
        !           186:                        
        !           187:                        timelib_unixtime2gmt(tm, ts - (tm->z * 60) + (tm->dst * 3600));
        !           188: 
        !           189:                        tm->z = z;
        !           190:                        tm->dst = dst;
        !           191:                        break;
        !           192:                }
        !           193: 
        !           194:                case TIMELIB_ZONETYPE_ID:
        !           195:                        gmt_offset = timelib_get_time_zone_info(ts, tz);
        !           196:                        timelib_unixtime2gmt(tm, ts + gmt_offset->offset);
        !           197: 
        !           198:                        /* we need to reset the sse here as unixtime2gmt modifies it */
        !           199:                        tm->sse = ts; 
        !           200:                        tm->dst = gmt_offset->is_dst;
        !           201:                        tm->z = gmt_offset->offset;
        !           202:                        tm->tz_info = tz;
        !           203: 
        !           204:                        timelib_time_tz_abbr_update(tm, gmt_offset->abbr);
        !           205:                        timelib_time_offset_dtor(gmt_offset);
        !           206:                        break;
        !           207: 
        !           208:                default:
        !           209:                        tm->is_localtime = 0;
        !           210:                        tm->have_zone = 0;
        !           211:                        return;
        !           212:        }
        !           213: 
        !           214:        tm->is_localtime = 1;
        !           215:        tm->have_zone = 1;
        !           216: }
        !           217: 
        !           218: void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz)
        !           219: {
        !           220:        timelib_time_offset *gmt_offset;
        !           221: 
        !           222:        gmt_offset = timelib_get_time_zone_info(t->sse, tz);
        !           223:        t->z = gmt_offset->offset;
        !           224: /*
        !           225:        if (t->dst != gmt_offset->is_dst) {
        !           226:                printf("ERROR (%d, %d)\n", t->dst, gmt_offset->is_dst);
        !           227:                exit(1);
        !           228:        }
        !           229: */
        !           230:        t->dst = gmt_offset->is_dst;
        !           231:        t->tz_info = tz;
        !           232:        if (t->tz_abbr) {
        !           233:                free(t->tz_abbr);
        !           234:        }
        !           235:        t->tz_abbr = strdup(gmt_offset->abbr);
        !           236:        timelib_time_offset_dtor(gmt_offset);
        !           237: 
        !           238:        t->have_zone = 1;
        !           239:        t->zone_type = TIMELIB_ZONETYPE_ID;
        !           240: }
        !           241: 
        !           242: /* Converts the time stored in the struct to localtime if localtime = true,
        !           243:  * otherwise it converts it to gmttime. This is only done when necessary
        !           244:  * ofcourse. */
        !           245: int timelib_apply_localtime(timelib_time *t, unsigned int localtime)
        !           246: {
        !           247:        if (localtime) {
        !           248:                /* Converting from GMT time to local time */
        !           249:                TIMELIB_DEBUG(printf("Converting from GMT time to local time\n"););
        !           250: 
        !           251:                /* Check if TZ is set */
        !           252:                if (!t->tz_info) {
        !           253:                        TIMELIB_DEBUG(printf("E: No timezone configured, can't switch to local time\n"););
        !           254:                        return -1;
        !           255:                }
        !           256: 
        !           257:                timelib_unixtime2local(t, t->sse);
        !           258:        } else {
        !           259:                /* Converting from local time to GMT time */
        !           260:                TIMELIB_DEBUG(printf("Converting from local time to GMT time\n"););
        !           261: 
        !           262:                timelib_unixtime2gmt(t, t->sse);
        !           263:        }
        !           264:        return 0;
        !           265: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>