Just use the format 'D, d M Y H:i:s T'
(see the description of each field in documentation).
To transform the string into date, use date_create_from_format
, and from the date returned by this function, use getTimestamp
to be able to compare with the timestamp returned by filemtime
:
$data = date_create_from_format('D, d M Y H:i:s T', 'Wed, 21 Oct 2015 07:28:00 GMT');
if ($data && $data->getTimestamp() > filemtime('arquivo')) {
etc...
}
Already to convert the return of filemtime
for the format in question, use gmdate
, which is similar to date
, however the date returned is in GMT (with date
doesn’t work because it returns UTC
instead of GMT
). See the difference:
// testando com um arquivo modificado hoje
echo gmdate('D, d M Y H:i:s T', filemtime('arquivo')); // Wed, 10 Feb 2021 14:24:23 GMT
echo date('D, d M Y H:i:s T', filemtime('arquivo')); // Wed, 10 Feb 2021 14:24:23 UTC
Another alternative is to use the constant DateTimeInterface::RFC7231
as format, which by explicitly putting "GMT" at the end, works both with date
as to gmdate
:
$format = DateTimeInterface::RFC7231;
$data = date_create_from_format($format, 'Wed, 21 Oct 2015 07:28:00 GMT');
// usar $data, etc
echo gmdate($format, filemtime('arquivo')); // Wed, 10 Feb 2021 14:24:23 GMT
echo date($format, filemtime('arquivo')); // Wed, 10 Feb 2021 14:24:23 GMT
Going a little further...
How the question talks about the "value of header If-Modified-Since
", I think it’s worth going a little deeper.
If we refer to RFC 7232 (HTTP Conditional Requests), we see that the header If-Modified-Since
is defined as:
If-Modified-Since = HTTP-date
An example of the field is:
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
And the definition of HTTP-date
is in RFC 7231 (my translation and emphases):
Before 1995, there were 3 different formats used by the servers for sending timestamps. For compatibility with old implementations, all 3 are defined here. The preferential format is ... a subset of what is specified in RFC5322:
HTTP-date = IMF-fixdate / obs-date
An example of preferential format:
Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate
Examples of formats obsolete:
Sunday, 06-Nov-94 08:49:37 GMT ; obsolete RFC 850 format
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
That is, currently, one should give preference to the format quoted in the question (and that is defined in RFC5322). But RFC 7321 also cites that "A recipient that parses a timestamp value in an HTTP header field MUST Accept all three HTTP-date formats" (that is, even if the last 2 formats are obsolete, they must still be accepted).
Therefore, an alternative to accepting the 3 formats is to try one by one until it is possible to do the Parsing (or until all fail):
function parse($headerValue) {
// formatos (dando preferência para o não-obsoleto)
$formatos = [ DateTimeInterface::RFC7231, DateTimeInterface::RFC850, 'D M d H:i:s Y' ];
foreach ($formatos as $formato) {
$data = date_create_from_format($formato, $headerValue);
if ($data) return $data;
}
return FALSE;
}
$formato_saida = DateTimeInterface::RFC7231;
$values = [ 'Wed, 21 Oct 2015 07:28:00 GMT', 'Sunday, 06-Nov-94 08:49:37 GMT', 'Sun Nov 6 08:49:37 1994' ];
foreach ($values as $val) {
$data = parse($val);
if ($data) {
if ($data->getTimestamp() > filemtime('arquivo')) {
// etc...
}
$saida = gmdate($formato_saida, $data->getTimestamp());
echo "$val -> $saida\n";
} else {
echo "$val -> data inválida\n";
}
}
To make the Parsing, I preferred the preferred format... indicated in RFC, and then I try the obsolete ones. Note that the second format is RFC850
(reading the year with 2 digits), instead of the COOKIE
(which is almost the same, only he tries to read the year with 4 digits and 94
is interpreted as the year 94 instead of 1994). And for the third format, I couldn’t find a predefined constant that would fit, so I set up the format by hand.
Already to format the output, I used the RFC7231
, that always puts "GMT" at the end (the others put other values, such as "UTC" or "+00:00"). I chose to use this format, because it is the only one that RFC defines as not being obsolete (i.e., to receive I accept any format, but when sending, I use the "preferred" non-obsolete). The exit code above is:
Wed, 21 Oct 2015 07:28:00 GMT -> Wed, 21 Oct 2015 07:28:00 GMT
Sunday, 06-Nov-94 08:49:37 GMT -> Sun, 06 Nov 1994 08:49:37 GMT
Sun Nov 6 08:49:37 1994 -> Sun, 06 Nov 1994 08:49:37 GMT
A simpler alternative
The above options are for the case of you in addition to the comparison with filemtime
, also need to manipulate the date in other ways (since date_create_from_format
returns a DateTime
).
But if you only want the value of the timestamp to be able to compare with the return of filemtime
, can use strtotime
, recognizing the 3 formats defined in RFC:
$formato_saida = DateTimeInterface::RFC7231;
$values = [ 'Wed, 21 Oct 2015 07:28:00 GMT', 'Sunday, 06-Nov-94 08:49:37 GMT', 'Sun Nov 6 08:49:37 1994' ];
foreach ($values as $val) {
$timestamp = strtotime($val);
if ($timestamp === FALSE) {
echo "$val -> data inválida\n";
} else {
// comparação direta
if ($timestamp > filemtime('arquivo')) {
// etc...
}
// formatar para o formato preferencial não-obsoleto
$saida = gmdate($formato_saida, $timestamp);
echo "$val -> $saida\n";
}
}
The difference, of course, is that strtotime
accepts several other formats (some even half "esoteric", as 'last day of february this year'
), then it depends on how rigid you want to be: if you want to accept only the 3 formats indicated by RFC, use the function parse
defined above (which only specifically accepts those formats).
But if the input is controlled (for example, you guarantee that the date is obtained from header - which in that case will be available in $_SERVER['HTTP_IF_MODIFIED_SINCE']
) and that will not be in an out of standard format, use strtotime
simplifies things.
For more details, see "Handling If-modified-Since header in a PHP-script".
A detail, if the value received by the header is invalid
DateTime::createFromFormat
(procedural: date_create_from_format) will returnFALSE
, then it would be good to do the IF this way:if ($data && $data->getTimestamp() > filemtime('arquivo')) {
– Guilherme Nascimento