[ruby/prism] Ignore shebangs in evals
[ruby.git] / doc / strftime_formatting.rdoc
blob5c7b33155df9ec7aad75509fadbd115379cde279
1 = Formats for Dates and Times
3 Several Ruby time-related classes have instance method +strftime+,
4 which returns a formatted string representing all or part of a date or time:
6 - Date#strftime.
7 - DateTime#strftime.
8 - Time#strftime.
10 Each of these methods takes optional argument +format+,
11 which has zero or more embedded _format_ _specifications_ (see below).
13 Each of these methods returns the string resulting from replacing each
14 format specification embedded in +format+ with a string form
15 of one or more parts of the date or time.
17 A simple example:
19   Time.now.strftime('%H:%M:%S') # => "14:02:07"
21 A format specification has the form:
23   %[flags][width]conversion
25 It consists of:
27 - A leading percent character.
28 - Zero or more _flags_ (each is a character).
29 - An optional _width_ _specifier_ (an integer).
30 - A _conversion_ _specifier_ (a character).
32 Except for the leading percent character,
33 the only required part is the conversion specifier, so we begin with that.
35 == Conversion Specifiers
37 === \Date (Year, Month, Day)
39 - <tt>%Y</tt> - Year including century, zero-padded:
41     Time.now.strftime('%Y')        # => "2022"
42     Time.new(-1000).strftime('%Y') # => "-1000" # Before common era.
43     Time.new(10000).strftime('%Y') # => "10000" # Far future.
44     Time.new(10).strftime('%Y')    # => "0010"  # Zero-padded by default.
46 - <tt>%y</tt> - Year without century, in range (0.99), zero-padded:
48     Time.now.strftime('%y')    # => "22"
49     Time.new(1).strftime('%y') # => "01" # Zero-padded by default.
51 - <tt>%C</tt> - Century, zero-padded:
53     Time.now.strftime('%C')        # => "20"
54     Time.new(-1000).strftime('%C') # => "-10" # Before common era.
55     Time.new(10000).strftime('%C') # => "100" # Far future.
56     Time.new(100).strftime('%C')   # => "01"  # Zero-padded by default.
58 - <tt>%m</tt> - Month of the year, in range (1..12), zero-padded:
60     Time.new(2022, 1).strftime('%m')  # => "01" # Zero-padded by default.
61     Time.new(2022, 12).strftime('%m') # => "12"
63 - <tt>%B</tt> - Full month name, capitalized:
65     Time.new(2022, 1).strftime('%B')  # => "January"
66     Time.new(2022, 12).strftime('%B') # => "December"
68 - <tt>%b</tt> - Abbreviated month name, capitalized:
70     Time.new(2022, 1).strftime('%b')  # => "Jan"
71     Time.new(2022, 12).strftime('%h') # => "Dec"
73 - <tt>%h</tt> - Same as <tt>%b</tt>.
75 - <tt>%d</tt> - Day of the month, in range (1..31), zero-padded:
77     Time.new(2002, 1, 1).strftime('%d')  # => "01"
78     Time.new(2002, 1, 31).strftime('%d') # => "31"
80 - <tt>%e</tt> - Day of the month, in range (1..31), blank-padded:
82     Time.new(2002, 1, 1).strftime('%e')  # => " 1"
83     Time.new(2002, 1, 31).strftime('%e') # => "31"
85 - <tt>%j</tt> - Day of the year, in range (1..366), zero-padded:
87     Time.new(2002, 1, 1).strftime('%j')   # => "001"
88     Time.new(2002, 12, 31).strftime('%j') # => "365"
90 === \Time (Hour, Minute, Second, Subsecond)
92 - <tt>%H</tt> - Hour of the day, in range (0..23), zero-padded:
94     Time.new(2022, 1, 1, 1).strftime('%H')  # => "01"
95     Time.new(2022, 1, 1, 13).strftime('%H') # => "13"
97 - <tt>%k</tt> - Hour of the day, in range (0..23), blank-padded:
99     Time.new(2022, 1, 1, 1).strftime('%k')  # => " 1"
100     Time.new(2022, 1, 1, 13).strftime('%k') # => "13"
102 - <tt>%I</tt> - Hour of the day, in range (1..12), zero-padded:
104     Time.new(2022, 1, 1, 1).strftime('%I')  # => "01"
105     Time.new(2022, 1, 1, 13).strftime('%I') # => "01"
107 - <tt>%l</tt> - Hour of the day, in range (1..12), blank-padded:
109     Time.new(2022, 1, 1, 1).strftime('%l')  # => " 1"
110     Time.new(2022, 1, 1, 13).strftime('%l') # => " 1"
112 - <tt>%P</tt> - Meridian indicator, lowercase:
114     Time.new(2022, 1, 1, 1).strftime('%P')  # => "am"
115     Time.new(2022, 1, 1, 13).strftime('%P') # => "pm"
117 - <tt>%p</tt> - Meridian indicator, uppercase:
119     Time.new(2022, 1, 1, 1).strftime('%p')  # => "AM"
120     Time.new(2022, 1, 1, 13).strftime('%p') # => "PM"
122 - <tt>%M</tt> - Minute of the hour, in range (0..59), zero-padded:
124     Time.new(2022, 1, 1, 1, 0, 0).strftime('%M') # => "00"
126 - <tt>%S</tt> - Second of the minute in range (0..59), zero-padded:
128     Time.new(2022, 1, 1, 1, 0, 0, 0).strftime('%S') # => "00"
130 - <tt>%L</tt> - Millisecond of the second, in range (0..999), zero-padded:
132     Time.new(2022, 1, 1, 1, 0, 0, 0).strftime('%L') # => "000"
134 - <tt>%N</tt> - Fractional seconds, default width is 9 digits (nanoseconds):
136     t = Time.now       # => 2022-06-29 07:10:20.3230914 -0500
137     t.strftime('%N')   # => "323091400"                  # Default.
139   Use {width specifiers}[rdoc-ref:strftime_formatting.rdoc@Width+Specifiers]
140   to adjust units:
142       t.strftime('%3N')  # => "323"                      # Milliseconds.
143       t.strftime('%6N')  # => "323091"                   # Microseconds.
144       t.strftime('%9N')  # => "323091400"                # Nanoseconds.
145       t.strftime('%12N') # => "323091400000"             # Picoseconds.
146       t.strftime('%15N') # => "323091400000000"          # Femptoseconds.
147       t.strftime('%18N') # => "323091400000000000"       # Attoseconds.
148       t.strftime('%21N') # => "323091400000000000000"    # Zeptoseconds.
149       t.strftime('%24N') # => "323091400000000000000000" # Yoctoseconds.
151 - <tt>%s</tt> - Number of seconds since the epoch:
153     Time.now.strftime('%s') # => "1656505136"
155 === Timezone
157 - <tt>%z</tt> - Timezone as hour and minute offset from UTC:
159     Time.now.strftime('%z') # => "-0500"
161 - <tt>%Z</tt> - Timezone name (platform-dependent):
163     Time.now.strftime('%Z') # => "Central Daylight Time"
165 === Weekday
167 - <tt>%A</tt> - Full weekday name:
169     Time.now.strftime('%A') # => "Wednesday"
171 - <tt>%a</tt> - Abbreviated weekday name:
173     Time.now.strftime('%a') # => "Wed"
175 - <tt>%u</tt> - Day of the week, in range (1..7), Monday is 1:
177     t = Time.new(2022, 6, 26) # => 2022-06-26 00:00:00 -0500
178     t.strftime('%a')          # => "Sun"
179     t.strftime('%u')          # => "7"
181 - <tt>%w</tt> - Day of the week, in range (0..6), Sunday is 0:
183     t = Time.new(2022, 6, 26) # => 2022-06-26 00:00:00 -0500
184     t.strftime('%a')          # => "Sun"
185     t.strftime('%w')          # => "0"
187 === Week Number
189 - <tt>%U</tt> - Week number of the year, in range (0..53), zero-padded,
190   where each week begins on a Sunday:
192     t = Time.new(2022, 6, 26) # => 2022-06-26 00:00:00 -0500
193     t.strftime('%a')          # => "Sun"
194     t.strftime('%U')          # => "26"
196 - <tt>%W</tt> - Week number of the year, in range (0..53), zero-padded,
197   where each week begins on a Monday:
199     t = Time.new(2022, 6, 26) # => 2022-06-26 00:00:00 -0500
200     t.strftime('%a')          # => "Sun"
201     t.strftime('%W')          # => "25"
203 === Week Dates
205 See {ISO 8601 week dates}[https://en.wikipedia.org/wiki/ISO_8601#Week_dates].
207     t0 = Time.new(2023, 1, 1) # => 2023-01-01 00:00:00 -0600
208     t1 = Time.new(2024, 1, 1) # => 2024-01-01 00:00:00 -0600
210 - <tt>%G</tt> - Week-based year:
212     t0.strftime('%G') # => "2022"
213     t1.strftime('%G') # => "2024"
215 - <tt>%g</tt> - Week-based year without century, in range (0..99), zero-padded:
217     t0.strftime('%g') # => "22"
218     t1.strftime('%g') # => "24"
220 - <tt>%V</tt> - Week number of the week-based year, in range (1..53),
221   zero-padded:
223     t0.strftime('%V') # => "52"
224     t1.strftime('%V') # => "01"
226 === Literals
228 - <tt>%n</tt> - Newline character "\n":
230     Time.now.strftime('%n') # => "\n"
232 - <tt>%t</tt> - Tab character "\t":
234     Time.now.strftime('%t') # => "\t"
236 - <tt>%%</tt> - Percent character '%':
238     Time.now.strftime('%%') # => "%"
240 === Shorthand Conversion Specifiers
242 Each shorthand specifier here is shown with its corresponding
243 longhand specifier.
245 - <tt>%c</tt> - \Date and time:
247     Time.now.strftime('%c')             # => "Wed Jun 29 08:01:41 2022"
248     Time.now.strftime('%a %b %e %T %Y') # => "Wed Jun 29 08:02:07 2022"
250 - <tt>%D</tt> - \Date:
252     Time.now.strftime('%D')       # => "06/29/22"
253     Time.now.strftime('%m/%d/%y') # => "06/29/22"
255 - <tt>%F</tt> - ISO 8601 date:
257     Time.now.strftime('%F')       # => "2022-06-29"
258     Time.now.strftime('%Y-%m-%d') # => "2022-06-29"
260 - <tt>%v</tt> - VMS date:
262     Time.now.strftime('%v')         # => "29-JUN-2022"
263     Time.now.strftime('%e-%^b-%4Y') # => "29-JUN-2022"
265 - <tt>%x</tt> - Same as <tt>%D</tt>.
267 - <tt>%X</tt> - Same as <tt>%T</tt>.
269 - <tt>%r</tt> - 12-hour time:
271     Time.new(2022, 1, 1, 1).strftime('%r')           # => "01:00:00 AM"
272     Time.new(2022, 1, 1, 1).strftime('%I:%M:%S %p')  # => "01:00:00 AM"
273     Time.new(2022, 1, 1, 13).strftime('%r')          # => "01:00:00 PM"
274     Time.new(2022, 1, 1, 13).strftime('%I:%M:%S %p') # => "01:00:00 PM"
276 - <tt>%R</tt> - 24-hour time:
278     Time.new(2022, 1, 1, 1).strftime('%R')     # => "01:00"
279     Time.new(2022, 1, 1, 1).strftime('%H:%M')  # => "01:00"
280     Time.new(2022, 1, 1, 13).strftime('%R')    # => "13:00"
281     Time.new(2022, 1, 1, 13).strftime('%H:%M') # => "13:00"
283 - <tt>%T</tt> - 24-hour time:
285     Time.new(2022, 1, 1, 1).strftime('%T')        # => "01:00:00"
286     Time.new(2022, 1, 1, 1).strftime('%H:%M:%S')  # => "01:00:00"
287     Time.new(2022, 1, 1, 13).strftime('%T')       # => "13:00:00"
288     Time.new(2022, 1, 1, 13).strftime('%H:%M:%S') # => "13:00:00"
290 - <tt>%+</tt> (not supported in Time#strftime) - \Date and time:
292     DateTime.now.strftime('%+')
293     # => "Wed Jun 29 08:31:53 -05:00 2022"
294     DateTime.now.strftime('%a %b %e %H:%M:%S %Z %Y')
295     # => "Wed Jun 29 08:32:18 -05:00 2022"
297 == Flags
299 Flags may affect certain formatting specifications.
301 Multiple flags may be given with a single conversion specified;
302 order does not matter.
304 === Padding Flags
306 - <tt>0</tt> - Pad with zeroes:
308     Time.new(10).strftime('%0Y') # => "0010"
310 - <tt>_</tt> - Pad with blanks:
312     Time.new(10).strftime('%_Y') # => "  10"
314 - <tt>-</tt> - Don't pad:
316     Time.new(10).strftime('%-Y') # => "10"
318 === Casing Flags
320 - <tt>^</tt> - Upcase result:
322     Time.new(2022, 1).strftime('%B')  # => "January" # No casing flag.
323     Time.new(2022, 1).strftime('%^B') # => "JANUARY"
325 - <tt>#</tt> - Swapcase result:
327     Time.now.strftime('%p')  # => "AM"
328     Time.now.strftime('%^p') # => "AM"
329     Time.now.strftime('%#p') # => "am"
331 === Timezone Flags
333 - <tt>:</tt> - Put timezone as colon-separated hours and minutes:
335     Time.now.strftime('%:z')  # => "-05:00"
337 - <tt>::</tt> - Put timezone as colon-separated hours, minutes, and seconds:
339     Time.now.strftime('%::z') # => "-05:00:00"
341 == Width Specifiers
343 The integer width specifier gives a minimum width for the returned string:
345   Time.new(2002).strftime('%Y')       # => "2002"     # No width specifier.
346   Time.new(2002).strftime('%10Y')     # => "0000002002"
347   Time.new(2002, 12).strftime('%B')   # => "December" # No width specifier.
348   Time.new(2002, 12).strftime('%10B') # => "  December"
349   Time.new(2002, 12).strftime('%3B')  # => "December" # Ignored if too small.
351 = Specialized Format Strings
353 Here are a few specialized format strings,
354 each based on an external standard.
356 == HTTP Format
358 The HTTP date format is based on
359 {RFC 2616}[https://www.rfc-editor.org/rfc/rfc2616],
360 and treats dates in the format <tt>'%a, %d %b %Y %T GMT'</tt>:
362   d = Date.new(2001, 2, 3) # => #<Date: 2001-02-03>
363   # Return HTTP-formatted string.
364   httpdate = d.httpdate    # => "Sat, 03 Feb 2001 00:00:00 GMT"
365   # Return new date parsed from HTTP-formatted string.
366   Date.httpdate(httpdate)  # => #<Date: 2001-02-03>
367   # Return hash parsed from HTTP-formatted string.
368   Date._httpdate(httpdate)
369   # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0}
371 == RFC 3339 Format
373 The RFC 3339 date format is based on
374 {RFC 3339}[https://www.rfc-editor.org/rfc/rfc3339]:
376   d = Date.new(2001, 2, 3) # => #<Date: 2001-02-03>
377   # Return 3339-formatted string.
378   rfc3339 = d.rfc3339      # => "2001-02-03T00:00:00+00:00"
379   # Return new date parsed from 3339-formatted string.
380   Date.rfc3339(rfc3339)    # => #<Date: 2001-02-03>
381   # Return hash parsed from 3339-formatted string.
382   Date._rfc3339(rfc3339)
383   # => {:year=>2001, :mon=>2, :mday=>3, :hour=>0, :min=>0, :sec=>0, :zone=>"+00:00", :offset=>0}
385 == RFC 2822 Format
387 The RFC 2822 date format is based on
388 {RFC 2822}[https://www.rfc-editor.org/rfc/rfc2822],
389 and treats dates in the format <tt>'%a, %-d %b %Y %T %z'</tt>]:
391   d = Date.new(2001, 2, 3) # => #<Date: 2001-02-03>
392   # Return 2822-formatted string.
393   rfc2822 = d.rfc2822      # => "Sat, 3 Feb 2001 00:00:00 +0000"
394   # Return new date parsed from 2822-formatted string.
395   Date.rfc2822(rfc2822)    # => #<Date: 2001-02-03>
396   # Return hash parsed from 2822-formatted string.
397   Date._rfc2822(rfc2822)
398   # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"+0000", :offset=>0}
400 == JIS X 0301 Format
402 The JIS X 0301 format includes the
403 {Japanese era name}[https://en.wikipedia.org/wiki/Japanese_era_name],
404 and treats dates in the format <tt>'%Y-%m-%d'</tt>
405 with the first letter of the romanized era name prefixed:
407   d = Date.new(2001, 2, 3) # => #<Date: 2001-02-03>
408   # Return 0301-formatted string.
409   jisx0301 = d.jisx0301    # => "H13.02.03"
410   # Return new date parsed from 0301-formatted string.
411   Date.jisx0301(jisx0301)  # => #<Date: 2001-02-03>
412   # Return hash parsed from 0301-formatted string.
413   Date._jisx0301(jisx0301) # => {:year=>2001, :mon=>2, :mday=>3}
415 == ISO 8601 Format Specifications
417 This section shows format specifications that are compatible with
418 {ISO 8601}[https://en.wikipedia.org/wiki/ISO_8601].
419 Details for various formats may be seen at the links.
421 Examples in this section assume:
423   t = Time.now # => 2022-06-29 16:49:25.465246 -0500
425 === Dates
427 See {ISO 8601 dates}[https://en.wikipedia.org/wiki/ISO_8601#Dates].
429 - {Years}[https://en.wikipedia.org/wiki/ISO_8601#Years]:
431   - Basic year (+YYYY+):
433       t.strftime('%Y') # => "2022"
435   - Expanded year (<tt>±YYYYY</tt>):
437       t.strftime('+%5Y') # => "+02022"
438       t.strftime('-%5Y') # => "-02022"
440 - {Calendar dates}[https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates]:
442   - Basic date (+YYYYMMDD+):
444       t.strftime('%Y%m%d') # => "20220629"
446   - Extended date (<tt>YYYY-MM-DD</tt>):
448       t.strftime('%Y-%m-%d') # => "2022-06-29"
450   - Reduced extended date (<tt>YYYY-MM</tt>):
452       t.strftime('%Y-%m') # => "2022-06"
454 - {Week dates}[https://en.wikipedia.org/wiki/ISO_8601#Week_dates]:
456   - Basic date (+YYYYWww+ or +YYYYWwwD+):
458       t.strftime('%Y%Ww')   # => "202226w"
459       t.strftime('%Y%Ww%u') # => "202226w3"
461   - Extended date (<tt>YYYY-Www</tt> or <tt>YYYY-Www-D<tt>):
463       t.strftime('%Y-%Ww')    # => "2022-26w"
464       t.strftime('%Y-%Ww-%u') # => "2022-26w-3"
466 - {Ordinal dates}[https://en.wikipedia.org/wiki/ISO_8601#Ordinal_dates]:
468   - Basic date (+YYYYDDD+):
470       t.strftime('%Y%j') # => "2022180"
472   - Extended date (<tt>YYYY-DDD</tt>):
474       t.strftime('%Y-%j') # => "2022-180"
476 === Times
478 See {ISO 8601 times}[https://en.wikipedia.org/wiki/ISO_8601#Times].
480 - Times:
482   - Basic time (+Thhmmss.sss+, +Thhmmss+, +Thhmm+, or +Thh+):
484       t.strftime('T%H%M%S.%L') # => "T164925.465"
485       t.strftime('T%H%M%S')    # => "T164925"
486       t.strftime('T%H%M')      # => "T1649"
487       t.strftime('T%H')        # => "T16"
489   - Extended time (+Thh:mm:ss.sss+, +Thh:mm:ss+, or +Thh:mm+):
491       t.strftime('T%H:%M:%S.%L') # => "T16:49:25.465"
492       t.strftime('T%H:%M:%S')    # => "T16:49:25"
493       t.strftime('T%H:%M')       # => "T16:49"
495 - {Time zone designators}[https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators]:
497   - Timezone (+time+ represents a valid time,
498     +hh+ represents a valid 2-digit hour,
499     and +mm+ represents a valid 2-digit minute):
501     - Basic timezone (<tt>time±hhmm</tt>, <tt>time±hh</tt>, or +timeZ+):
503         t.strftime('T%H%M%S%z')              # => "T164925-0500"
504         t.strftime('T%H%M%S%z').slice(0..-3) # => "T164925-05"
505         t.strftime('T%H%M%SZ')               # => "T164925Z"
507     - Extended timezone (<tt>time±hh:mm</tt>):
509         t.strftime('T%H:%M:%S%z') # => "T16:49:25-0500"
511   - See also:
513     - {Local time (unqualified)}[https://en.wikipedia.org/wiki/ISO_8601#Local_time_(unqualified)].
514     - {Coordinated Universal Time (UTC)}[https://en.wikipedia.org/wiki/ISO_8601#Coordinated_Universal_Time_(UTC)].
515     - {Time offsets from UTC}[https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC].
517 === Combined \Date and \Time
519 See {ISO 8601 Combined date and time representations}[https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations].
521 An ISO 8601 combined date and time representation may be any
522 ISO 8601 date and any ISO 8601 time,
523 separated by the letter +T+.
525 For the relevant +strftime+ formats, see
526 {Dates}[rdoc-ref:strftime_formatting.rdoc@Dates]
527 and {Times}[rdoc-ref:strftime_formatting.rdoc@Times] above.