Date
Specifies date the message was generated. If the message is a file off a database or filesystem, it specifies when the file was read (Last-Modified specifies the time the file was modified). If the message is served from a cache from a previous HTTP request, it specifies the time the upstream message was initially generated (and Age specifies how long has passed since then).
Requests
The Date header is optional in requests, and generally not necessary. It may be employed in specialized applications when the server would benefit from knowing the Client's time, for example if clock drift is important to the application.
Writing Responses
A server must include the Date header in responses, unless an reasonable approximation of the current date is not known.
A layer forwarding a message must add the Date header if it does not exist, and has a reasonable approximation.
The date can be any moment during the generation of the request, but ideally represents the moment the payload was generated, and when headers are written to the client.
The date must be in the IMF-fixdate
format, described below.
strftime
This strftime template produces an HTTP compatible date, compatible with C strftime/strptime, and similar implementations:
%a, %d %b %Y %H:%M:%S %Z
The locale must be set to GMT when formatting this template. If the return value ends in anything except the 4-character string GMT
, then the value is invalid, and locale is not configured properly.
Reading Responses
Other dates in the HTTP headers should be interpreted relative to this date, if present, instead of using the local machine's clock.
Although servers are only supposed to produce the "IMF-fixdate" format, older servers might produce two other formats, described with the obs-date
production (below).
Estimating Server Time using the Date header
Clients may use HTTP headers to obtain the current time according to the server; which may be used when reading other timestamps provided by the server; even if the local client clock is drifting or very wrong.
To estimate the server time, take the value of the Date
header and add the value of the Age header in seconds, if it exists:
const messageAge = Number.parseInt(response.getHeader('Age') || 0, 10);
const messageDate = Date.parse(response.getHeader('Date'));
assert(messageDate > 0);
const serverDate = new Date(messageDate + messageAge*1000);
The produced value should always be accurate plus or minus a second, plus or minus the duration of the request.
Overview table
- Name
- Date
- Description
- Specifies the date that the origin server generated the response.
- Direction
- Both
- Specification
- RFC 7231: HTTP/1.1 Semantics and Content ยง7.1.1.2. Date
Syntax
Date = HTTP-date
HTTP-date = IMF-fixdate / obs-date
IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT
; fixed length/zone/capitalization subset of the format
; see Section 3.3 of [RFC5322]
day-name = %x4D.6F.6E ; "Mon", case-sensitive
/ %x54.75.65 ; "Tue", case-sensitive
/ %x57.65.64 ; "Wed", case-sensitive
/ %x54.68.75 ; "Thu", case-sensitive
/ %x46.72.69 ; "Fri", case-sensitive
/ %x53.61.74 ; "Sat", case-sensitive
/ %x53.75.6E ; "Sun", case-sensitive
date1 = day SP month SP year
; e.g., 02 Jun 1982
day = 2DIGIT
month = %x4A.61.6E ; "Jan", case-sensitive
/ %x46.65.62 ; "Feb", case-sensitive
/ %x4D.61.72 ; "Mar", case-sensitive
/ %x41.70.72 ; "Apr", case-sensitive
/ %x4D.61.79 ; "May", case-sensitive
/ %x4A.75.6E ; "Jun", case-sensitive
/ %x4A.75.6C ; "Jul", case-sensitive
/ %x41.75.67 ; "Aug", case-sensitive
/ %x53.65.70 ; "Sep", case-sensitive
/ %x4F.63.74 ; "Oct", case-sensitive
/ %x4E.6F.76 ; "Nov", case-sensitive
/ %x44.65.63 ; "Dec", case-sensitive
year = 4DIGIT
GMT = %x47.4D.54 ; "GMT", case-sensitive
time-of-day = hour ":" minute ":" second
; 00:00:00 - 23:59:60 (leap second)
hour = 2DIGIT
minute = 2DIGIT
second = 2DIGIT
Obsolete formats:
obs-date = rfc850-date / asctime-date
rfc850-date = day-name-l "," SP date2 SP time-of-day SP GMT
date2 = day "-" month "-" 2DIGIT
; e.g., 02-Jun-82
day-name-l = %x4D.6F.6E.64.61.79 ; "Monday", case-sensitive
/ %x54.75.65.73.64.61.79 ; "Tuesday", case-sensitive
/ %x57.65.64.6E.65.73.64.61.79 ; "Wednesday", case-sensitive
/ %x54.68.75.72.73.64.61.79 ; "Thursday", case-sensitive
/ %x46.72.69.64.61.79 ; "Friday", case-sensitive
/ %x53.61.74.75.72.64.61.79 ; "Saturday", case-sensitive
/ %x53.75.6E.64.61.79 ; "Sunday", case-sensitive
asctime-date = day-name SP date3 SP time-of-day SP year
date3 = month SP ( 2DIGIT / ( SP 1DIGIT ))
; e.g., Jun 2
Example
Date: Tue, 15 Nov 1994 08:12:31 GMT
Implementations
Node.js
V8's implementation of Date#toUTCString
function produces an IMF-fixdate compatible string.
All three versions can be parsed by V8's new Date(string)
, so test that the header matches one of the legal input formats, then pass the entire string to a new Date instance.
// String#match will return an array with:
// [full, day_name, day, month_name, year, hour, minute, second]
var IMF_fixdate = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/;
// [full, day_name, day, month_name, year, hour, minute, second]
var rfc850_date = /^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{2}) (\d\d):(\d\d):(\d\d) GMT$/;
// [full, day_name, month_name, day, hour, minute, second, year]
var asctime_date = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([ 0-9][0-9]) (\d\d):(\d\d):(\d\d) (\d{4})$/;
function parseHTTPDate(str){
if(typeof str !== 'string') throw new Error('Expected a string');
if(IMF_fixdate.test(str) || rfc850_date.test(str) || asctime_date.test(str)) return new Date(str);
throw new Error('Invalid HTTP-date');
}
PHP
All known HTTP servers that run PHP, including as PHP's builtin testing server, will produce a Date header in response by default.
If the Date header needs to be written or parsed despite this, use the DATE_RFC7231
or DateTimeInterface::RFC7231
constants available since since PHP 7.1.5:
$Date = gmdate(DATE_RFC7231); $Date = (new DateTimeImmutable())->format(DateTimeInterface::RFC7231);
The strtotime function or DateTimeImmutable class can parse a Date header:
$unixtime = strtotime("Tue, 15 Nov 1994 08:12:31 GMT"); $datetime = new DateTimeImmutable("Tue, 15 Nov 1994 08:12:31 GMT");