diff options
Diffstat (limited to 'ext/standard/datetime.c')
-rw-r--r-- | ext/standard/datetime.c | 630 |
1 files changed, 0 insertions, 630 deletions
diff --git a/ext/standard/datetime.c b/ext/standard/datetime.c deleted file mode 100644 index 872428c757..0000000000 --- a/ext/standard/datetime.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP version 4.0 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997, 1998, 1999 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 2.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://www.php.net/license/2_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andi Gutmans <andi@zend.com> | - | Zeev Suraski <zeev@zend.com> | - | Rasmus Lerdorf <rasmus@php.net> | - +----------------------------------------------------------------------+ - */ - - -/* $Id$ */ - - -#include "php.h" -#include "zend_operators.h" -#include "datetime.h" -#include "snprintf.h" -#include "php_globals.h" - -#include <time.h> -#ifdef HAVE_SYS_TIME_H -# include <sys/time.h> -#endif -#include <stdio.h> - -char *mon_full_names[] = -{ - "January", "February", "March", "April", - "May", "June", "July", "August", - "September", "October", "November", "December" -}; -char *mon_short_names[] = -{ - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; -char *day_full_names[] = -{ - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" -}; -char *day_short_names[] = -{ - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -#if !defined(HAVE_TM_ZONE) && !defined(_TIMEZONE) && !(WIN32||WINNT) -extern time_t timezone; -#endif - -static int phpday_tab[2][12] = -{ - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -}; - -#define isleap(year) (((year%4) == 0 && (year%100)!=0) || (year%400)==0) - -extern PHPAPI time_t parsedate(char *p, struct timeval *now); - - -PHP_FUNCTION(time) -{ - return_value->value.lval = (long) time(NULL); - return_value->type = IS_LONG; -} - -void _php3_mktime(INTERNAL_FUNCTION_PARAMETERS, int gm) -{ - pval *arguments[7]; - struct tm *ta, tmbuf; - time_t t; - int i, gmadjust, seconds, arg_count = ARG_COUNT(ht); - - if (arg_count > 7 || getParametersArray(ht, arg_count, arguments) == FAILURE) { - WRONG_PARAM_COUNT; - } - /* convert supplied arguments to longs */ - for (i = 0; i < arg_count; i++) { - convert_to_long(arguments[i]); - } - t = time(NULL); -#ifdef HAVE_TZSET - tzset(); -#endif - /* - ** Set default time parameters with local time values, - ** EVEN when some GMT time parameters are specified! - ** This may give strange result, with PHP gmmktime(0,0,0), - ** which is assumed to return GMT midnight time - ** for today (in localtime), so that the result time may be - ** AFTER or BEFORE the current time. - ** May be we should initialize tn using gmtime(), so that - ** default parameters for PHP gmmktime would be the current - ** GMT time values... - */ - ta = localtime_r(&t, &tmbuf); - - /* Let DST be unknown. mktime() should compute the right value - ** and behave correctly. Unless the user overrides this. - */ - ta->tm_isdst = -1; - - /* - ** Now change date values with supplied parameters. - */ - switch(arg_count) { - case 7: - ta->tm_isdst = arguments[6]->value.lval; - /* fall-through */ - case 6: - /* - ** Accept parameter in range 0..1000 interpreted as 1900..2900 - ** (if 100 is given, it means year 2000) - ** or in range 1001..9999 interpreted as is (this will store - ** negative tm_year for years in range 1001..1899) - ** This function is then Y2K ready, and accepts a wide range of - ** dates including the whole gregorian calendar. - ** But it cannot represent ancestral dates prior to year 1001. - */ - ta->tm_year = arguments[5]->value.lval - - ((arguments[5]->value.lval > 1000) ? 1900 : 0); - /* fall-through */ - case 5: - ta->tm_mday = arguments[4]->value.lval; - /* fall-through */ - case 4: - ta->tm_mon = arguments[3]->value.lval - 1; - /* fall-through */ - case 3: - ta->tm_sec = arguments[2]->value.lval; - /* fall-through */ - case 2: - ta->tm_min = arguments[1]->value.lval; - /* fall-through */ - case 1: - ta->tm_hour = arguments[0]->value.lval; - /* fall-through */ - case 0: - break; - } - - seconds = mktime(ta); - - if (gm) { -#if HAVE_TM_GMTOFF - /* - ** mktime(ta) very nicely just filled ta->tm_gmtoff with - ** the exactly right value for adjustment if we want GMT. - */ - gmadjust = ta->tm_gmtoff; -#else - /* - ** Without tm_gmtoff, the non-ANSI C run-time global 'timezone' - ** variable simply returns the current Winter GMT offset - ** in the current locale (defined in DOS/Windows compilers). - */ - gmadjust = timezone; -#endif - seconds += gmadjust; - } - - RETURN_LONG(seconds); -} - -PHP_FUNCTION(mktime) -{ - _php3_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} - -PHP_FUNCTION(gmmktime) -{ - _php3_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} - -static void -_php3_date(INTERNAL_FUNCTION_PARAMETERS, int gm) -{ - pval *format, *timestamp; - time_t the_time; - struct tm *ta, tmbuf; - int i, size = 0, length, h, beat; - char tmp_buff[16]; - - switch(ARG_COUNT(ht)) { - case 1: - if (getParameters(ht, 1, &format) == FAILURE) { - WRONG_PARAM_COUNT; - } - the_time = time(NULL); - break; - case 2: - if (getParameters(ht, 2, &format, ×tamp) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long(timestamp); - the_time = timestamp->value.lval; - break; - default: - WRONG_PARAM_COUNT; - } - convert_to_string(format); - - if (gm) { - ta = gmtime_r(&the_time, &tmbuf); - } else { - ta = localtime_r(&the_time, &tmbuf); - } - - if (!ta) { /* that really shouldn't happen... */ - php_error(E_WARNING, "unexpected error in date()"); - RETURN_FALSE; - } - for (i = 0; i < format->value.str.len; i++) { - switch (format->value.str.val[i]) { - case 'U': /* seconds since the epoch */ - size += 10; - break; - case 'F': /* month, textual, full */ - case 'l': /* day (of the week), textual */ - case 'T': /* timezone name */ - size += 9; - break; - case 'Z': /* timezone offset in seconds */ - size += 6; - break; - case 'Y': /* year, numeric, 4 digits */ - size += 4; - break; - case 'M': /* month, textual, 3 letters */ - case 'D': /* day, textual, 3 letters */ - case 'z': /* day of the year, 1 to 366 */ - size += 3; - break; - case 'y': /* year, numeric, 2 digits */ - case 'm': /* month, numeric */ - case 'n': /* month, numeric, no leading zeroes */ - case 'd': /* day of the month, numeric */ - case 'j': /* day of the month, numeric, no leading zeros */ - case 'H': /* hour, numeric, 24 hour format */ - case 'h': /* hour, numeric, 12 hour format */ - case 'G': /* hour, numeric, 24 hour format, no leading zeroes */ - case 'g': /* hour, numeric, 12 hour format, no leading zeroes */ - case 'i': /* minutes, numeric */ - case 's': /* seconds, numeric */ - case 'A': /* AM/PM */ - case 'a': /* am/pm */ - case 'S': /* standard english suffix for the day of the month (e.g. 3rd, 2nd, etc) */ - case 't': /* days in current month */ - size += 2; - break; - case '\\': - if(i < format->value.str.len-1) { - i++; - } - case 'L': /* boolean for leap year */ - case 'B': /* Swatch Beat, 3 digits */ - size += 3; - break; - case 'w': /* day of the week, numeric */ - default: - size++; - break; - } - } - - return_value->value.str.val = (char *) emalloc(size + 1); - return_value->value.str.val[0] = '\0'; - - for (i = 0; i < format->value.str.len; i++) { - switch (format->value.str.val[i]) { - case '\\': - if(i < format->value.str.len-1) { - char ch[2]; - ch[0]=format->value.str.val[i+1]; - ch[1]='\0'; - strcat(return_value->value.str.val, ch); - i++; - } - break; - case 'U': /* seconds since the epoch */ - sprintf(tmp_buff, "%ld", (long)the_time); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'F': /* month, textual, full */ - strcat(return_value->value.str.val, mon_full_names[ta->tm_mon]); - break; - case 'l': /* day (of the week), textual, full */ - strcat(return_value->value.str.val, day_full_names[ta->tm_wday]); - break; - case 'Y': /* year, numeric, 4 digits */ - sprintf(tmp_buff, "%d", ta->tm_year + 1900); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'M': /* month, textual, 3 letters */ - strcat(return_value->value.str.val, mon_short_names[ta->tm_mon]); - break; - case 'D': /* day (of the week), textual, 3 letters */ - strcat(return_value->value.str.val, day_short_names[ta->tm_wday]); - break; - case 'z': /* day (of the year) */ - sprintf(tmp_buff, "%d", ta->tm_yday); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'y': /* year, numeric, 2 digits */ - sprintf(tmp_buff, "%02d", ((ta->tm_year)%100)); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'm': /* month, numeric */ - sprintf(tmp_buff, "%02d", ta->tm_mon + 1); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'n': /* month, numeric, no leading zeros */ - sprintf(tmp_buff, "%d", ta->tm_mon + 1); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'd': /* day of the month, numeric */ - sprintf(tmp_buff, "%02d", ta->tm_mday); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'j': - sprintf(tmp_buff, "%d", ta->tm_mday); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'H': /* hour, numeric, 24 hour format */ - sprintf(tmp_buff, "%02d", ta->tm_hour); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'h': /* hour, numeric, 12 hour format */ - h = ta->tm_hour % 12; if (h==0) h = 12; - sprintf(tmp_buff, "%02d", h); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'G': /* hour, numeric, 24 hour format, no leading zeros */ - sprintf(tmp_buff, "%d", ta->tm_hour); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'g': /* hour, numeric, 12 hour format, no leading zeros */ - h = ta->tm_hour % 12; if (h==0) h = 12; - sprintf(tmp_buff, "%d", h); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'i': /* minutes, numeric */ - sprintf(tmp_buff, "%02d", ta->tm_min); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 's': /* seconds, numeric */ - sprintf(tmp_buff, "%02d", ta->tm_sec); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'A': /* AM/PM */ - strcat(return_value->value.str.val, (ta->tm_hour >= 12 ? "PM" : "AM")); - break; - case 'a': /* am/pm */ - strcat(return_value->value.str.val, (ta->tm_hour >= 12 ? "pm" : "am")); - break; - case 'S': /* standard english suffix, e.g. 2nd/3rd for the day of the month */ - if (ta->tm_mday >= 10 && ta->tm_mday <= 19) { - strcat(return_value->value.str.val, "th"); - } else { - switch (ta->tm_mday % 10) { - case 1: - strcat(return_value->value.str.val, "st"); - break; - case 2: - strcat(return_value->value.str.val, "nd"); - break; - case 3: - strcat(return_value->value.str.val, "rd"); - break; - default: - strcat(return_value->value.str.val, "th"); - break; - } - } - break; - case 't': /* days in current month */ - sprintf(tmp_buff, "%2d", phpday_tab[isleap((ta->tm_year+1900))][ta->tm_mon] ); - strcat(return_value->value.str.val, tmp_buff); - break; - case 'w': /* day of the week, numeric EXTENSION */ - sprintf(tmp_buff, "%01d", ta->tm_wday); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - case 'Z': /* timezone offset in seconds */ -#if HAVE_TM_GMTOFF - sprintf(tmp_buff, "%ld", ta->tm_gmtoff ); -#else - sprintf(tmp_buff, "%ld", timezone); -#endif - strcat(return_value->value.str.val, tmp_buff); - break; - case 'L': /* boolean for leapyear */ - sprintf(tmp_buff, "%d", (isleap((ta->tm_year+1900)) ? 1 : 0 ) ); - strcat(return_value->value.str.val, tmp_buff); - break; - case 'T': /* timezone name */ -#if HAVE_TM_ZONE - strcat(return_value->value.str.val, ta->tm_zone); -#else - strcat(return_value->value.str.val, tzname[0]); -#endif - break; - case 'B': /* Swatch Beat a.k.a. Internet Time */ - beat = (((((long)the_time)-(((long)the_time) - - ((((long)the_time) % 86400) + 3600))) * 10) / 864); - if (beat > 999) beat = 0; - sprintf(tmp_buff, "%03d", beat); /* SAFE */ - strcat(return_value->value.str.val, tmp_buff); - break; - default: - length = strlen(return_value->value.str.val); - return_value->value.str.val[length] = format->value.str.val[i]; - return_value->value.str.val[length + 1] = '\0'; - break; - } - } - return_value->value.str.len = strlen(return_value->value.str.val); - return_value->type = IS_STRING; -} - -PHP_FUNCTION(date) -{ - _php3_date(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} - -PHP_FUNCTION(gmdate) -{ - _php3_date(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} - -PHP_FUNCTION(getdate) -{ - pval *timestamp_arg; - struct tm *ta, tmbuf; - time_t timestamp; - - if (ARG_COUNT(ht) == 0) { - timestamp = time(NULL); - } else if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, ×tamp_arg) == FAILURE) { - WRONG_PARAM_COUNT; - } else { - convert_to_long(timestamp_arg); - timestamp = timestamp_arg->value.lval; - } - - ta = localtime_r(×tamp, &tmbuf); - if (!ta) { - php_error(E_WARNING, "Cannot perform date calculation"); - return; - } - if (array_init(return_value) == FAILURE) { - php_error(E_ERROR, "Unable to initialize array"); - return; - } - add_assoc_long(return_value, "seconds", ta->tm_sec); - add_assoc_long(return_value, "minutes", ta->tm_min); - add_assoc_long(return_value, "hours", ta->tm_hour); - add_assoc_long(return_value, "mday", ta->tm_mday); - add_assoc_long(return_value, "wday", ta->tm_wday); - add_assoc_long(return_value, "mon", ta->tm_mon + 1); - add_assoc_long(return_value, "year", ta->tm_year + 1900); - add_assoc_long(return_value, "yday", ta->tm_yday); - add_assoc_string(return_value, "weekday", day_full_names[ta->tm_wday], 1); - add_assoc_string(return_value, "month", mon_full_names[ta->tm_mon], 1); - add_index_long(return_value, 0, timestamp); -} - -/* Return date string in standard format for http headers */ -char *php3_std_date(time_t t) -{ - struct tm *tm1, tmbuf; - char *str; - PLS_FETCH(); - - tm1 = gmtime_r(&t, &tmbuf); - str = emalloc(81); - if (PG(y2k_compliance)) { - snprintf(str, 80, "%s, %02d-%s-%04d %02d:%02d:%02d GMT", - day_full_names[tm1->tm_wday], - tm1->tm_mday, - mon_short_names[tm1->tm_mon], - tm1->tm_year+1900, - tm1->tm_hour, tm1->tm_min, tm1->tm_sec); - } else { - snprintf(str, 80, "%s, %02d-%s-%02d %02d:%02d:%02d GMT", - day_full_names[tm1->tm_wday], - tm1->tm_mday, - mon_short_names[tm1->tm_mon], - ((tm1->tm_year)%100), - tm1->tm_hour, tm1->tm_min, tm1->tm_sec); - } - - str[79]=0; - return (str); -} - -/* - * CheckDate(month, day, year); - * returns True(1) if it is valid date - * - */ -#define isleap(year) (((year%4) == 0 && (year%100)!=0) || (year%400)==0) -PHP_FUNCTION(checkdate) -{ - pval *month, *day, *year; - int m, d, y; - - if (ARG_COUNT(ht) != 3 || - getParameters(ht, 3, &month, &day, &year) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long(day); - convert_to_long(month); - convert_to_long(year); - y = year->value.lval; - m = month->value.lval; - d = day->value.lval; - - if (y < 100) - y += 1900; - - if (y < 0 || y > 32767) { - RETURN_FALSE; - } - if (m < 1 || m > 12) { - RETURN_FALSE; - } - if (d < 1 || d > phpday_tab[isleap(y)][m - 1]) { - RETURN_FALSE; - } - RETURN_TRUE; /* True : This month,day,year arguments are valid */ -} - - -#if HAVE_STRFTIME - -PHP_FUNCTION(strftime) -{ - pval *format_arg, *timestamp_arg; - char *format,*buf; - time_t timestamp; - struct tm *ta, tmbuf; - int max_reallocs = 5; - size_t buf_len=64, real_len; - - switch (ARG_COUNT(ht)) { - case 1: - if (getParameters(ht, 1, &format_arg)==FAILURE) { - RETURN_FALSE; - } - time(×tamp); - break; - case 2: - if (getParameters(ht, 2, &format_arg, ×tamp_arg)==FAILURE) { - RETURN_FALSE; - } - convert_to_long(timestamp_arg); - timestamp = timestamp_arg->value.lval; - break; - default: - WRONG_PARAM_COUNT; - break; - } - - convert_to_string(format_arg); - if (format_arg->value.str.len==0) { - RETURN_FALSE; - } - format = format_arg->value.str.val; - ta = localtime_r(×tamp, &tmbuf); - - buf = (char *) emalloc(buf_len); - while ((real_len=strftime(buf,buf_len,format,ta))==buf_len || real_len==0) { - buf_len *= 2; - buf = (char *) erealloc(buf, buf_len); - if(!--max_reallocs) break; - } - - if(real_len && real_len != buf_len) { - buf = (char *) erealloc(buf,real_len+1); - RETURN_STRINGL(buf, real_len, 0); - } - efree(buf); - RETURN_FALSE; -} -#endif - -/* {{{ proto int strtotime(string time, int now) - Convert string representation of date and time to a timestamp */ -PHP_FUNCTION(strtotime) -{ - pval *timep, *nowp; - int ac; - struct timeval tv; - - ac = ARG_COUNT(ht); - - if (ac < 1 || ac > 2 || getParameters(ht, ac, &timep, &nowp)==FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string(timep); - if (ac == 2) { - convert_to_long(nowp); - tv.tv_sec = nowp->value.lval; - tv.tv_usec = 0; - RETURN_LONG(parsedate(timep->value.str.val, &tv)); - } else { - RETURN_LONG(parsedate(timep->value.str.val, NULL)); - } -} - -/* }}} */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ |