In front of the
< How to use PHP to calculate the one months of today >In the article, we mentioned that the Strtotime function is going to be a bit of a situation when you use Strtotime ("-1 month") for one months today.
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:
Copy Code code as follows:
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:
Copy Code code as follows:
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:
Copy Code code as follows:
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:
Copy Code code as follows:
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:
Copy Code code as follows:
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:
Copy Code code as follows:
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:
Copy Code code 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/>";
The back represents the position of the one hour after the specified hour value is set to 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:
Copy Code code as follows:
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:
Copy Code code as follows:
' 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:
Copy Code code as follows:
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 was up to date with the Date/time members * *
unsigned int tim_uptodate; /*!0 If the date/time members are up to date with the SSE member */
unsigned int is_localtime; /* 1 If the current struct represents localtime, 0 if it was in GMT */
unsigned int zone_type; /* 1 time 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;
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:
Copy Code code as follows:
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:
Copy Code code as follows:
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.