преобразовать дату и время в строку (convert date and time to a string)
Обоснование (Rationale)
The %Y
conversion specification to strftime() was frequently
assumed to be a four-digit year, but the ISO C standard does not
specify that %Y
is restricted to any subset of allowed values
from the tm_year field. Similarly, the %C
conversion
specification was assumed to be a two-digit field and the first
part of the output from the %F
conversion specification was
assumed to be a four-digit field. With tm_year being a signed 32
or more-bit int
and with many current implementations supporting
64-bit time_t
types in one or more programming environments,
these assumptions are clearly wrong.
POSIX.1‐2008 now allows the format specifications %0xC
, %0xF
,
%0xG
, and %0xY
(where 'x'
is a string of decimal digits used to
specify printing and scanning of a string of x decimal digits)
with leading zero fill characters. Allowing applications to set
the field width enables them to agree on the number of digits to
be printed and scanned in the ISO 8601:2004 standard expanded
representation of a year (for %F
, %G
, and %Y
) or all but the last
two digits of the year (for %C
). This is based on a feature in
some versions of GNU libc
's strftime(). The GNU version allows
specifying space, zero, or no-fill characters in strftime()
format strings, but does not allow any flags to be specified in
strptime() format strings. These implementations also allow these
flags to be specified for any numeric field. POSIX.1‐2008 only
requires the zero fill flag ('0'
) and only requires that it be
recognized when processing %C
, %F
, %G
, and %Y
specifications when
a minimum field width is also specified. The '0'
flag is the only
flag needed to produce and scan the ISO 8601:2004 standard year
fields using the extended format forms. POSIX.1‐2008 also allows
applications to specify the same flag and field width specifiers
to be used in both strftime() and strptime() format strings for
symmetry. Systems may provide other flag characters and may
accept flags in conjunction with conversion specifiers other than
%C
, %F
, %G
, and %Y
; but portable applications cannot depend on
such extensions.
POSIX.1‐2008 now also allows the format specifications %+xC
,
%+xF
, %+xG
, and %+xY
(where 'x'
is a string of decimal digits
used to specify printing and scanning of a string of 'x'
decimal
digits) with leading zero fill characters and a leading '+'
sign
character if the year being converted is more than four digits or
a minimum field width is specified that allows room for more than
four digits for the year. This allows date providers and
consumers to agree on a specific number of digits to represent a
year as required by the ISO 8601:2004 standard expanded
representation formats. The expanded representation formats all
require the year to begin with a leading '+'
or '-'
sign. (All
of these specifiers can also provide a leading '-'
sign for
negative years. Since negative years and the year 0 don't fit
well with the Gregorian or Julian calendars, the normal ranges of
dates start with year 1. The ISO C standard allows tm_year to
assume values corresponding to years before year 1, but the use
of such years provided unspecified results.)
Some earlier version of this standard specified that applications
wanting to use strptime() to scan dates and times printed by
strftime() should provide non-digit characters between fields to
separate years from months and days. It also supported %F
to
print and scan the ISO 8601:2004 standard extended format,
complete representation date for years 1 through 9999 (i.e.,
YYYY-MM-DD). However, many applications were written to print
(using strftime()) and scan (using strptime()) dates written
using the basic format complete representation (four-digit years)
and truncated representation (two-digit years) specified by the
ISO 8601:2004 standard representation of dates and times which do
not have any separation characters between fields. The
ISO 8601:2004 standard also specifies basic format expanded
representation where the creator and consumer of these fields
agree beforehand to represent years as leading zero-filled
strings of an agreed length of more than four digits to represent
a year (again with no separation characters when year, month, and
day are all displayed). Applications producing and consuming
expanded representations are encouraged to use the '+'
flag and
an appropriate maximum field width to scan the year including the
leading sign. Note that even without the '+'
flag, years less
than zero may be represented with a leading <hyphen-minus> for
%F
, %G
, and %Y
conversion specifications. Using negative years
results in unspecified behavior.
If a format specification %+xF
with the field width x greater
than 11 is specified and the width is large enough to display the
full year, the output string produced will match the
ISO 8601:2004 standard subclause 4.1.2.4 expanded representation,
extended format date representation for a specific day. (For
years in the range [1,99999], %+12F
is sufficient for an agreed
five-digit year with a leading sign using the ISO 8601:2004
standard expanded representation, extended format for a specific
day "<+/->YYYYY-MM-DD"
.) Note also that years less than 0 may
produce a leading <hyphen-minus> character ('-'
) when using %Y
or
%C
whether or not the '0'
or '+'
flags are used.
The difference between the '0'
flag and the '+'
flag is whether
the leading '+'
character will be provided for years >9999 as
required for the ISO 8601:2004 standard extended representation
format containing a year. For example:
┌───────┬──────────────────────────┬─────────────┬────────────┐
│ │ │ strftime()
│ strptime()
│
│ Year
│ Conversion Specification
│ Output
│ Scan Back
│
├───────┼──────────────────────────┼─────────────┼────────────┤
│1970 │ %Y │ 1970 │ 1970 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│1970 │ %+4Y │ 1970 │ 1970 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│27 │ %Y │ 27 or 0027 │ 27 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│270 │ %Y │ 270 or 0270 │ 270 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│270 │ %+4Y │ 0270 │ 270 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│17 │ %C%y │ 0017 │ 17 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│270 │ %C%y │ 0270 │ 270 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│12345 │ %Y │ 12345 │ 1234* │
├───────┼──────────────────────────┼─────────────┼────────────┤
│12345 │ %+4Y │ +12345 │ 123* │
├───────┼──────────────────────────┼─────────────┼────────────┤
│12345 │ %05Y │ 12345 │ 12345 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│270 │ %+5Y or %+3C%y │ +0270 │ 270 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│12345 │ %+5Y or %+3C%y │ +12345 │ 1234* │
├───────┼──────────────────────────┼─────────────┼────────────┤
│12345 │ %06Y or %04C%y │ 012345 │ 12345 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│12345 │ %+6Y or %+4C%y │ +12345 │ 12345 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│123456 │ %08Y or %06C%y │ 00123456 │ 123456 │
├───────┼──────────────────────────┼─────────────┼────────────┤
│123456 │ %+8Y or %+6C%y │ +0123456 │ 123456 │
└───────┴──────────────────────────┴─────────────┴────────────┘
In the cases above marked with a * in the strptime() scan back
field, the implied or specified number of characters scanned by
strptime() was less than the number of characters output by
strftime() using the same format; so the remaining digits of the
year were dropped when the output date produced by strftime() was
scanned back in by strptime().