Deep analysis of PHP strtotime functions

Source: Internet
Author: User
Tags current time echo date php source code

The PHP strtotime function resolves the date-time description of any English text to a UNIX timestamp [converts system time to UNIX timestamp]

First, get the Unix timestamp strtotime ("2009-1-22″" example) for the specified date as follows:

Echo strtotime ("2009-1-22") Results: 1232553600
Note: Return January 22, 2009 0:0 0 seconds time stamp

Second, obtain the English text date time example as follows:

Easy to compare, using date to convert the timestamp to the system time with the specified timestamp

The code is as follows Copy Code

(1) Print tomorrow at this time the timestamp strtotime ("+1 Day")
Current Time: Echo Date ("Y-m-d h:i:s", Time ()) Result: 2009-01-22 09:40:25
Specified time: echo date ("Y-m-d h:i:s", Strtotime ("+1 Day") Results: 2009-01-23 09:40:25

(2) Print the timestamp strtotime ("-1 day") at this time yesterday
Current Time: Echo Date ("Y-m-d h:i:s", Time ()) Result: 2009-01-22 09:40:25
Specified time: echo date ("Y-m-d h:i:s", Strtotime ("1 day")) Results: 2009-01-21 09:40:25

(3) Print the timestamp strtotime ("+1 Week") at this time next week
Current Time: Echo Date ("Y-m-d h:i:s", Time ()) Result: 2009-01-22 09:40:25
Specified time: echo date ("Y-m-d h:i:s", Strtotime ("+1 Week") Results: 2009-01-29 09:40:25

(4) Print the timestamp strtotime ("-1 week") at this time last week
Current Time: Echo Date ("Y-m-d h:i:s", Time ()) Result: 2009-01-22 09:40:25
Specified time: echo date ("Y-m-d h:i:s", Strtotime ("1 week")) Results: 2009-01-15 09:40:25

(5) Print a timestamp strtotime ("next Thursday") that specifies the next day of the week
Current Time: Echo Date ("Y-m-d h:i:s", Time ()) Result: 2009-01-22 09:40:25
Specified time: echo date ("Y-m-d h:i:s", Strtotime ("next Thursday") Results: 2009-01-29 00:00:00

(6) Print a timestamp strtotime ("last Thursday") that specifies the previous week
Current Time: Echo Date ("Y-m-d h:i:s", Time ()) Result: 2009-01-22 09:40:25
Specified time: echo date ("Y-m-d h:i:s", Strtotime ("last Thursday") Results: 2009-01-15 00:00:00

The above example shows that Strtotime can resolve the date-time description of any English text to a Unix timestamp, and we combine the mktime () or date () format date time to get the specified timestamp to achieve the required DateTime.

Now let's delve into its source code.
Source Location: \ext\date\php_date.c

The code is as follows Copy Code

/* {{{proto int strtotime (string time [, int now])
Convert string representation of date and time to a timestamp * *
Php_function (Strtotime)
{
Char *times, *initial_ts;
int Time_len, Error1, Error2;
struct Timelib_error_container *error;
Long preset_ts = 0, ts;

Timelib_time *t, *now;
Timelib_tzinfo *tzi;

Tzi = Get_timezone_info (Tsrmls_c);

if (ZEND_PARSE_PARAMETERS_EX (Zend_parse_params_quiet, Zend_num_args () tsrmls_cc, "SL", &times, &time_len, &PRESET_TS)!= failure) {
/* We have an initial timestamp * *
now = Timelib_time_ctor ();

Initial_ts = Emalloc (25);
snprintf (Initial_ts, "@%ld UTC", preset_ts);
t = Timelib_strtotime (Initial_ts, strlen (initial_ts), NULL, Date_timezonedb, Php_date_parse_tzfile_wrapper); /* We ignore the error here, as this should never fail * *
Timelib_update_ts (t, Tzi);
Now->tz_info = Tzi;
Now->zone_type = timelib_zonetype_id;
Timelib_unixtime2local (now, T->sse);
Timelib_time_dtor (t);
Efree (INITIAL_TS);
else if (Zend_parse_parameters (Zend_num_args () tsrmls_cc, "S|l", &times, &time_len, &preset_ts)!= FAILURE ) {
/* We have no initial timestamp * *
now = Timelib_time_ctor ();
Now->tz_info = Tzi;
Now->zone_type = timelib_zonetype_id;
Timelib_unixtime2local (now, (TIMELIB_SLL) time (NULL));
} else {
Return_false;
}

if (!time_len) {
Timelib_time_dtor (now);
Return_false;
}

t = Timelib_strtotime (times, Time_len, &error, Date_timezonedb, Php_date_parse_tzfile_wrapper);
Error1 = error->error_count;
Timelib_error_container_dtor (Error);
Timelib_fill_holes (t, now, Timelib_no_clone);
Timelib_update_ts (t, Tzi);
ts = timelib_date_to_int (t, &error2);

Timelib_time_dtor (now);
Timelib_time_dtor (t);

if (Error1 | | error2) {
Return_false;
} else {
Return_long (TS);
}
}
/* }}} */

Strtotime function in the use of Strtotime ("-1 month") for one months today, there will be some situation,

So it also leads to writing this article, which includes the following:

Some usages of strtotime function
The realization principle of strtotime function
Strtotime ("-1 month") The reason for the evaluation failure
Some usages of strtotime function
1, Strtotime ("the") and Strtotime ("January")

The effects of these two usages are the same, which are returned today for the specified month, and are postponed to the next one months if the specified month is not today. In 2011-03-31, as calculated in February, the code:

echo Date ("Y-m-d h:i:s", Strtotime ("Feb", Strtotime ("2011-03-31"));
The program will output: 2011-03-03 00:00:00. On the surface, the result may not necessarily be what we want, but it is a solution, so what is the decision? The Strtotime function calculates the month only when the month is calculated, which is equivalent to setting the month directly to the value of the specified month, whereas Jan,january will have a corresponding internal value.

2, the single keyword

First is an auxiliary keyword that can be used in combination with the week, day can specify the value of the keyword combinations, such as a 2011-year of one Sunday:

echo Date ("Y-m-d h:i:s", Strtotime ("Second Sunday", Strtotime ("2011-01-01")), "<br/>";
In the PHP source code, for the combination of the week and day is separate, that is, a processing operation, in the final C implementation, the value of the day is specified as 1, that is, the D field in the time structure is specified as 1, the following code:

The code is as follows Copy Code
Switch (time->relative.first_last_day_of) {
Case 1:/* A/*
Time->d = 1;
Break
Case 2:/* Last */
time->d = 0;
time->m++;
Break
}

3, Previous and Next keywords

Similar to first, the previous keyword can be used in combination with the week and day, representing the one weeks or days before the specified time. As shown in the following code:

echo Date ("Y-m-d h:i:s", Strtotime ("Previous Sunday", Strtotime ("2011-02-01")), "<br/>";
Program output: 2011-01-30 00:00:00
The procedure is to ask for a Sunday before 2011-02-01.

The next keyword, in contrast to previous, represents the next one weeks or the following day.

4, last keyword

The last keyword can be either previous or final. If you ask for the date of the last Sunday:

The code is as follows Copy Code
echo Date ("Y-m-d h:i:s", Strtotime ("Last Sunday", Strtotime ("2011-02-05")), "<br/>";

Program output: 2011-01-30 00:00:00

When the program is last, the scenario is the last day of the month on which the specified date is, equivalent to the result of date ("T"). For the last day of February 2000:

The code is as follows Copy Code
echo Date ("Y-m-d h:i:s", Strtotime ("Last Day", Strtotime ("2000-02-01")), "<br/>";

The previous, last, and this keywords belong to the same group in the re file.

5, Back and front keywords

These two keywords are the forward and backward operations of the hour of the day, and the calling format is as follows:

echo Date ("Y-m-d h:i:s", Strtotime ("Back of", Strtotime ("2011-02-01")), "<br/>";
echo Date ("Y-m-d h:i:s", Strtotime ("front of", Strtotime ("2011-02-01")), "<br/>";
Back indicates the position of the one hour after the time setting specifies the hour value of 15 points. If it is 24 o ' 0:15, Count to the next day.
Front represents the position of 45 points in the first one hours of the specified hour value for the time setting. If it's 0, it's 23:45 the day before.
The above code output: 2011-02-02-00:15:00 2011-02-01 23:45:00. Where back of and front of the array must be greater than or equal to 0 and less than or equal to 24.

The realization principle of strtotime function
Official documentation for the Strtotime function, this function expects to accept a string containing the U.S. English date format and tries to resolve it to a Unix timestamp (the number of seconds since January 1 1970 00:00:00 GMT), with a value relative to the time given by the now parameter, If this parameter is not supplied, the current time of the system is used.

This is a standard PHP built-in function that already exists from PHP4. The Strtotime function is loaded in an extended way and has its full implementation in the Ext/date directory. As a standard built-in function, its definition format is also standard, as follows:

The code is as follows Copy Code

Php_function (Strtotime)
Processing input, if there is no processing for the second parameter

Call correlation function to implement parsing and result calculation of string

return results
}

In the input processing, first identify the existence of two parameters and processing, if not this state, processing the second parameter does not exist, if none, then the error, return false.

The first parameter of the Strtotime function is a string, and because of its complexity, PHP uses the same tools as its lexical parsing: re2c. In the/ext/date/lib directory, we can see the original re file from the Parse_date.re file. When the user passes in a string as a parameter, this string is handed to the program to handle, matching different handler functions for its string. As Strtotime ("Yesterday") calls, parsing a string matches the yesterday string, which corresponds to the following function:

The code is as follows Copy Code

' Yesterday '
{
Debug_output ("Yesterday");
Timelib_init;
Timelib_have_relative ();
Timelib_unhave_time ();

S->TIME->RELATIVE.D =-1;
Timelib_deinit;
return timelib_relative;
}
Here are a few key structures:

typedef struct SCANNER {
int FD;
Uchar *lim, *str, *ptr, *cur, *tok, *pos;
unsigned int line, Len;
struct Timelib_error_container *errors;

struct Timelib_time *time;
Const TIMELIB_TZDB *TZDB;
} Scanner;

typedef struct TIMELIB_TIME {
Timelib_sll y, M, D; * * year, Month, day * *
Timelib_sll h, I, S; * Hour, MInute, Second * *
Double F; * Fraction * *
int z; * GMT offset in minutes * *
Char *tz_abbr; /* Timezone abbreviation (display only) * *
Timelib_tzinfo *tz_info; /* Timezone Structure * *
signed int DST; /* Flag If we were parsing a DST zone * *
Timelib_rel_time relative;

TIMELIB_SLL SSE; /* Seconds since Epoch * *

unsigned int have_time, have_date, Have_zone, have_relative, Have_weeknr_day;

    unsigned int   sse_uptodate/*!0 If the SSE member are up to date with the Date/time memb ERS */
    unsigned int   tim_uptodate;/*!0 If the date/time members are up to date with th E SSE member */
    unsigned int   is_localtime/*  1 If the current struct represents LocalTime, 0 if it is in GMT */
    unsigned int   zone_type;   /*  1 ti Me offset,
                                   *  3 TimeZone identifier,
                                    *  2 TimeZone abbreviation */
} timelib_time;

typedef struct TIMELIB_REL_TIME {
Timelib_sll y, M, D; * * Years, Months and Days * *
Timelib_sll h, I, S; /* Hours, MInutes and Seconds * *

int weekday; /* Stores the day in ' next Monday ' *
int weekday_behavior; /* 0:the current day should *not* is counted when advancing forwards; 1:the current day *should* be counted * *

int first_last_day_of;
int invert; /* Whether The difference should be inverted * *
TIMELIB_SLL days; /* Contains The number of *days*, instead of y-m-d differences *

Timelib_special Special;
unsigned int have_weekday_relative, have_special_relative;
} timelib_rel_time;

S->TIME->RELATIVE.D =-1 means that the relative days of the current time are-1. This is only the intermediate result of intermediate lexical parsing, but the final result is computed through these intermediate results.

Strtotime ("-1 month") The reason for the evaluation failure
Although Strtotime ("-1 Month") This method fails for the last one months compared to the number of days in the first one months, it is inherently not wrong. There is nothing wrong with PHP being implemented like this. It's just that our needs dictate that we can't use this method, so we call it the evaluation failure.

We look at its implementation, because there is no second argument, so the program uses the default current time. The first argument passes in a -1 month string, and the regular in the re file corresponding to this string is:

The code is as follows Copy Code

Reltextunit = (' sec ' | ' Second ' | ' Min ' | ' Minute ' | ' Hour ' | ' Day ' | ' Fortnight ' | ' Forthnight ' | ' Month ' | ' Year ') ' s '? | ' Weeks ' | Daytext;

Relnumber = ([+-]*[\t]*[0-9]+);
relative = Relnumber space? (Reltextunit | ' Week ');

The final relative will correspond to a series of operations, the program will recognize the preceding-1 and subsequent MONTH strings, MONTH corresponding to one type of operation: Timelib_month. After that, the following code is executed based on the number and type of action identified:

The code is as follows Copy Code
Case TIMELIB_MONTH:S->TIME->RELATIVE.M + = Amount * relunit->multiplier; Break

As the code above, it is the direct record of the month relative value minus one. However, for cases similar to those of March 31, there was no number 31st in February, and the program automatically calculated the date to the next one months.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.