前回の記事 では、strtotime("-1 month") を使用して前月の今日の日を見つけると、strtotime 関数で問題が発生することを説明しました。 ,
ということで、この記事を書くことにも繋がります この記事には以下の内容が含まれています
• strtotime関数の使い方
• strtotime関数の実装の基本原則
• strtotime(”-1 month”)の評価が失敗する理由
strtotime 関数のいくつかの使用法
1. strtotime("JAN") と strtotime(" January")
これら 2 つの使用法の効果は両方とも、指定された月の今日の日を返します。指定した月の今日は、翌月に延期されます。 たとえば、2011 年 3 月 31 日の 2 月を計算するには、コードは次のとおりです。
コードをコピーします コードは次のとおりです:
echo date("Y-m-d H:i:s", strtotime(" feb", strtotime("2011- 03-31")));
プログラムは次のように出力します: 2011-03-03 00:00:00。 見た目の観点からは、この結果は必ずしも望ましいものではないかもしれませんが、この解決策を決定するものは何でしょうか。 strtotime 関数は、月を計算するときにのみ月を計算します。これは、月を指定した月の値に直接設定することと同じであり、jan や January などは対応する内部値を持ちます。
2. 最初のキーワード
first は、確認値を指定できる週、日などのキーワードと組み合わせて使用できます。たとえば、2011 年の最初の日曜日を検索します。
コードをコピー コードは次のとおりです:
echo date("Y-m-d H:i:s", strtotime("second sunday", strtotime("2011-01-01"))), "< br />";
PHP ソース コードでは、first、week、day の組み合わせは別々に使用されています。つまり、first day は処理操作に対応します。最終的な C 実装では、day の値が指定されています。コードは次のように、フィールドは 1 として指定されます:
コードをコピーします。 コードは次のとおりです: Switch (Time-& GT; Relative.firs_last_day_of) { ケース 1: / * 最初 * /
時間 -& gt; Break;
}
3. 前と次のキーワード
は first と似ており、前のキーワードは組み合わせて使用できます。指定した時刻の曜日または前日を示すには、week と day を使用します。コードは次のとおりです:
コードをコピーします
コードは次のとおりです:
echo date("Y-m-d H:i:s", strtotime("previous sunday", strtotime("2011-02- 01"))) , "
";
プログラムは次のように出力します: 2011-01-30 00:00:00 プログラムは 2011-02-01 より前の日曜日を検索します。 次のキーワードは前のキーワードの逆で、次の曜日または翌日を意味します。
4. 最後のキーワード
最後のキーワードは、前のキーワードまたは最後のキーワードとして使用できます。先週の日曜日の日付を確認するには:
コードをコピーします
コードは次のとおりです:
echo date("Y-m-d H:i:s", strtotime("last sunday", strtotime("2011- 02-05" ))), "
";
プログラムは次のように出力します: 2011-01-30 00:00:00 プログラムが最後の場合、そのアプリケーション シナリオは最終日です指定された日付が位置する月。これは date("t") の結果と同等です。たとえば、2000 年 2 月の最後の日:
コードをコピーします
コードは次のとおりです:
echo date("Y-m-d H:i:s", strtotime("last day", strtotime(" 2000-02- 01"))), "
";
first、previous、last、およびこのキーワードは、re ファイル内の同じグループに属します。 5. 前後のキーワード
これら 2 つのキーワードは、その日の時間帯での前後の操作です。 呼び出し形式は次のとおりです。
コードをコピーします。
echo date("Y-m-d H:i:s", strtotime("back of 24", strtotime("2011-02-01"))), "
";
echo date("Y-m-d"; H:i:s", strtotime("front of 24", strtotime("2011-02-01"))), "
";
•back は、時間を指定した時間に設定することを意味します値 1 時間後の 15 分の位置。 24:00の場合は翌日の0:15までカウントされます。
•front は、指定された時間値の 45 分前に時間を設定することを意味します。 0時なら前日の23時45分として計算されます。
上記のコード出力: 2011-02-02 00:15:00 2011-02-01 23:45:00。 配列の後に後部と前部が続く場合は、0 以上、24 以下である必要があります。
strtotime関数の基本的な実装原理
公式ドキュメントでは、strtotime関数について次のように説明しています: この関数は、米国英語の日付形式を含む文字列を受け入れ、それをUnixタイムスタンプ(1970年1月1日以降)に解析しようとします。 00:00:00 GMT)、その値は、now パラメータで指定された時刻を基準としています。このパラメータが指定されていない場合は、現在のシステム時刻が使用されます。
これは、PHP4 から存在する標準の PHP 組み込み関数です。 strtotime 関数は拡張機能としてロードされ、その完全な実装は ext/date ディレクトリで入手できます。 標準の組み込み関数として、その定義形式も次のように標準です:
コードをコピー コードは次のとおりです:
PHP_FUNCTION(strtotime)
// 2 番目の入力があるかどうかを処理します。パラメータの有無 Processing
// 関連する関数を呼び出して文字列の解析と結果の計算を実装する
// 結果を返す
}
入力処理では、まず両方のパラメータが存在する状況を特定し、この状態にない場合は処理します。 , 2 番目のパラメータが存在しない場合は、エラーが報告され、FALSE が返されます。
strtotime 関数の最初のパラメータは文字列です。この文字列は複雑であるため、PHP は字句解析と同じツール re2c を使用します。 /ext/date/lib ディレクトリでは、parse_date.re ファイルから元の re ファイルを確認できます。 ユーザーがパラメータの形式で文字列を渡すと、その文字列は処理のためにこのプログラムに渡され、異なる文字列に応じて異なる処理関数が照合されます。 strtotime("yesterday") が呼び出された場合、文字列を分析すると、昨日の文字列と一致します。この文字列に対応する関数は次のとおりです。
コードをコピーします コードは次のとおりです。 「昨日」
昨日」); TIMELIB_ TIMELIB_DEINIT
return
}
いくつかのキーの構造:
コードをコピーします
コードは次のとおりです:
typedef struct Scanner {
int fd;
uchar *lim、*str、*ptr、*cur、*tok、*pos;
unsigned int 行、len;
struct timelib_error_container *エラー;
struct timelib_time *time;
const timelib_tzdb *tzdb;
} スキャナー。
typedef struct timelib_time {
timelib_sll y, m, d; /* 年、月、日 */
timelib_sll h, i, s; /* 時、分、秒 */
double f; /* 分数 */
int z; /* GMT オフセット (分単位) */
char *tz_abbr; /* タイムゾーンの省略形 (表示のみ) */
timelib_tzinfo *tz_info; /* タイムゾーン構造 */
signed int dst; /* DST ゾーンを解析しているかどうかを示すフラグ */
timelib_rel_time相対;
timelib_sll sse; /* エポックからの秒数 */
unsigned int have_time, have_date, have_zone, have_relative, have_weeknr_day;
unsigned int sse_uptodate; /* !0 sse メンバーが日付/時刻メンバーと最新の場合 */
unsigned int tim_uptodate; /* 日時メンバーが sse メンバーと最新の場合は !0 */
unsigned int is_localtime; /* 現在の構造体が現地時間を表す場合は 1、GMT の場合は 0 */
unsigned int zone_type; /* 1 時間オフセット、
* 3 タイムゾーン識別子、
* 2 タイムゾーンの省略形 */
} timelib_time;
typedef struct timelib_rel_time {
timelib_sll y, m, d; /* 年、月、日 */
timelib_sll h, i, s; /* 時、分、秒 */
int 平日; /* 曜日を「次の月曜日」に格納します */
int Weekday_behavior; /* 0: 前に進むときに、現在の日は「カウントされません」。 1: 現在の日を *カウントする必要があります */
int first_last_day_of;
int 反転; /* 差を反転する必要があるかどうか */
timelib_sll days; /* Y-M-D の差ではなく、*日* の数が含まれます */
timelib_special special;
unsigned int have_weekday_relative、have_special_relative;
} timelib_rel_time;
strtotime(”-1 month”) が評価に失敗した理由
strtotime(”-1 month”) メソッドは前月と比較した次の月の日数の評価に失敗しますが、本質的には、これは間違いではありません。 PHP の実装には何も問題はありません。ニーズによってこの方法を使用できないというだけなので、これを評価失敗と呼びます。
その実装プロセスを見てみましょう。2 番目のパラメータがないため、プログラムはデフォルトの現在時刻を使用します。 最初のパラメータは、-1 month 文字列で渡されます。この文字列に対応する re ファイル内の正規表現は次のとおりです。
コードをコピーします コードは次のとおりです。 |' 秒'|'分'|'分'|'時'|'日'|'二週間'|'月'|'年') '週' | relnumber = ([+-]*[ /t]*[0-9]+);
relative = relnumber space? (reltextunit | 'week' ); 最後に、相対は一連の操作に対応します。プログラムは前の -1 と次の月文字列を認識します。月は操作タイプ TIMELIB_MONTH に対応します。 この後、認識された番号と操作の種類に基づいて、次のように操作が実行されます。
コードをコピー
コードは次のとおりです:
case TIMELIB_MONTH: s->time->relative.m += amount * relunit->multiplier; 上記のコードは、月から 1 を引いた相対値を直接記録します。 ただし、2 月に 31 日がない 3 月 31 日のような状況では、プログラムは自動的に翌月までの日付を計算します。
http://www.bkjia.com/PHPjc/327115.html
www.bkjia.com
true
http://www.bkjia.com/PHPjc/327115.html技術記事 PHP を使用して前月の今日の日を計算する方法に関する前回の記事で、strtotime("-1 month") を使用して前月の今日の日を見つけると、strtotime 関数でいくつかの問題が発生することを説明しました。 .