ホームページ >バックエンド開発 >PHPチュートリアル >PHP strtotime 関数の使用法、実装原理とソース コード分析、strtotime 関数_PHP チュートリアル
ソースコードの場所: extdatephp_date.c
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”, ×, &time_len, &preset_ts) != FAILURE) {
/* 初期タイムスタンプがあります */
今 = timelib_time_ctor();
initial_ts = emalloc(25);
snprintf(initial_ts, 24, “@%ld UTC”, preset_ts);
t = timelib_strtotime(initial_ts, strlen(initial_ts), NULL, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper) /* これは失敗しないはずなので、ここではエラーを無視します */
Timelib_update_ts(t, tzi);
now->tz_info = tzi;
now->zone_type = TIMELIB_ZONETYPE_ID;
Timelib_unixtime2local(今、t->sse);
Timelib_time_dtor(t);
efree(initial_ts);
} else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, “s|l”, ×, &time_len, &preset_ts) != FAILURE) {
/* 初期タイムスタンプがありません */
今 = timelib_time_ctor();
now->tz_info = tzi;
now->zone_type = TIMELIB_ZONETYPE_ID;
Timelib_unixtime2local(現在、(timelib_sll) 時間(NULL));
} その他 {
RETURN_FALSE;
}
if (!time_len) {
Timelib_time_dtor(現在)
RETURN_FALSE;
}
t = timelib_strtotime(times, time_len, &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
error1 = エラー->エラー数;
Timelib_error_container_dtor(エラー);
Timelib_fill_holes(t、今、TIMELIB_NO_CLONE);
Timelib_update_ts(t, tzi);
ts = timelib_date_to_int(t, &error2);
timelib_time_dtor(現在);
Timelib_time_dtor(t);
if (エラー 1 || エラー 2) {
RETURN_FALSE;
} その他 {
RETURN_LONG(ts);
}
}
/* }}} */
これは、次の内容を含むこの記事を書くきっかけにもなりました:
1) .strtotime 関数の使用例
2) strtotime関数実装の基本原則
3) .strtotime(“-1 month”) の評価に失敗した理由
strtotime関数の使用例
1. strtotime(「JAN」) と strtotime(「1 月」)
これら 2 つの使用法の効果はどちらも同じです。指定した月に今日がない場合は、次の月に延期されます。 たとえば、2 月が 2011-03-31 に計算される場合、コードは次のようになります:
2.最初のキーワード
first は補助キーワードであり、2011 年の最初の日曜日を検索するなど、確認値を指定できる曜日、曜日などのキーワードと組み合わせて使用できます。
4. 最後のキーワード
最後のキーワードは、前または最後のキーワードとして使用できます。先週の日曜日の日付が必要な場合:
これら 2 つのキーワードは、その日の時間帯の順方向および逆方向の操作であり、その呼び出し形式は次のとおりです:
strtotime関数実装の基本原則
公式ドキュメントでは、strtotime 関数について次のように説明しています: この関数は、米国英語の日付形式を含む文字列を受け入れ、それを Unix タイムスタンプ (1970 年 1 月 1 日 00:00:00 GMT からの秒数) に解析しようとします。 、その値は、now パラメータで指定された時刻を基準としています。このパラメータが指定されていない場合は、現在のシステム時刻が使用されます。
// 関連関数を呼び出して文字列の解析と結果の計算を実装します
// 結果を返す
}
strtotime 関数の最初のパラメータは文字列です。この文字列は複雑であるため、PHP は字句解析と同じツール re2c を使用します。 /ext/date/lib ディレクトリでは、parse_date.re ファイルから元の re ファイルを確認できます。 ユーザーがパラメータの形式で文字列を渡すと、その文字列は処理のためにこのプログラムに渡され、異なる文字列に応じて異なる処理関数が照合されます。 たとえば、strtotime("yesterday") が呼び出された場合、文字列を分析するときに、昨日の文字列が照合されます。この文字列に対応する関数は次のとおりです。
TIMELIB_DEINIT;
TIMELIB_RELATIVE を返します;
}
struct timelib_time *time;
const timelib_tzdb *tzdb;
スキャナ;
typedef struct timelib_time {
timelib_sll y、m、d; /* 年、月、日 */
timelib_sll h、i、s; /* 時、分、秒 */
ダブル 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 平日の動作; /* 0: 前に進むときに、現在の日は「カウントされません」。 1: 現在の日を*カウントする必要があります*/
int first_last_day_of;
int 反転; /* 差を反転する必要があるかどうか */
timelib_sll 日。 /* Y-M-D の差ではなく、*日* の数が含まれます */
timelib_special スペシャル;
unsigned int have_weekday_relative, have_special_relative;
timelib_rel_time;
strtotime(“-1 month”)要求失費の原因
strtotime("-1 month") この方法は、前の月より後の月の日数を計算すると失われる可能性がありますが、この内容から言えば、問題はありません。 PHP でこのように実現することもできます。要求によってこの方法を使用できないことが決定されたため、これを要求損失と呼びます。 最初のパラメータは -1 か月の文字列であり、この文字列に対応するファイル内の正確な値は次のとおりです。 :
最終的に、相対は一連の操作に対応し、プログラムは先頭の -1 と後ろの月文字列を認識します: TIMELIB_MONTH。 この後、次のコードに示すように、識別された番号と操作の種類に基づいて操作を実行します。