DATEADD(1)

πŸ’… DATEADD(1) β€” okay bestie, let's talk dateadd

So you opened the manual for dateadd, a User Commands situation, and honestly? It's a slay. Let's get into it.


✨ NAME ✨

dateadd β€” add DURATION to DATE/TIME and print the result. That's it. That's the whole vibe. πŸ’–


πŸ¦‹ SYNOPSIS πŸ¦‹

dateadd [OPTION]...  [DATE/TIME] [DURATION]

🌸 DESCRIPTION 🌸

Okay so the whole thing is: add DURATION to DATE/TIME and print the result. Iconic. But there's lore:

  • If DATE/TIME is omitted but DURATION is given β†’ read a list of DATE/TIMEs from stdin. πŸ‘€
  • If DURATION is omitted but DATE/TIME is given β†’ read a list of DURATIONs from stdin. πŸ‘€

Durations are written as nY, nMO, nW, or nD for years, months, weeks, or days respectively, or nH, nM, nS for hours, minutes, and seconds, where N is a (possibly negative) number. The unit symbols can be written lower-case as well (y, mo, w, d, h, m, s) and the unit symbol d can be omitted entirely. We love a flexible queen. ✨

⚠️ Okay this part is important, no cap: duration addition is not commutative! Order matters, bestie. The manual gives us these two receipts: 2000-03-30 +1mo +1d -> 2000-05-01 2000-03-30 +1d +1mo -> 2000-04-30 Same inputs, different order, different answer. Not me being shook. 😭

Recognized OPTIONs (here we go, buckle up πŸŽ€):

  • -h, --help β€” Print help and exit. Your "wait what does this do again" button.
  • -V, --version β€” Print version and exit. Slay.
  • -q, --quiet β€” Suppress message about date/time and duration parser errors and fix-ups. The default is to print a warning or the fixed up value and return error code 2. So like, -q is the "don't tell me, I don't wanna know" flag. πŸ™ˆ
  • -f, --format=STRING β€” Output format. This can either be a specifier string (similar to strftime()'s FMT) or the name of a calendar. Cute AND versatile.
  • -i, --input-format=STRING... β€” Input format, can be used multiple times. Each date/time will be passed to the input format parsers in the order they are given, and if a date/time can be read successfully with a given input format specifier string, that value will be used. First parser to catch it wins, basically. 🫢
  • -b, --base=DT β€” For underspecified input use DT as a fallback to fill in missing fields. Also used for ambiguous format specifiers to position their range on the absolute time line. Must be a date/time in ISO8601 format. If omitted defaults to the current date/time. It's giving "fill in the blanks" energy.
  • -e, --backslash-escapes β€” Enable interpretation of backslash escapes in the output and input format specifier strings.
  • -S, --sed-mode β€” Copy parts from the input before and after a matching date/time. Note that all occurrences of date/times within a line will be processed. Very thorough. Very main character.
  • -E, --empty-mode β€” Empty lines that cannot be parsed.
  • --locale=LOCALE β€” Format results according to LOCALE, this would only affect month and weekday names.
  • --from-locale=LOCALE β€” Interpret dates on stdin or the command line as coming from the locale LOCALE, this would only affect month and weekday names as input formats have to be specified explicitly.
  • --from-zone=ZONE β€” Interpret dates on stdin or the command line as coming from the time zone ZONE.
  • -z, --zone=ZONE β€” Convert dates printed on stdout to time zone ZONE, default: UTC. πŸ’…

πŸ”₯ FORMAT SPECS πŸ”₯

Format specs in dateutils are similar to posix' strftime(). BUT β€” and this is the plot twist β€” due to a broader range of supported calendars, dateutils must employ different rules. So not exactly the same, iykyk.

Date specs:

%a  The abbreviated weekday name
%A  The full weekday name
%_a The weekday name shortened to a single character (MTWRFAS)
%b  The abbreviated month name
%B  The full month name
%_b The month name shortened to a single character (FGHJKMNQUVXZ)
%c  The count of the weekday within the month (range 00 to 05)
%C  The count of the weekday within the year (range 00 to 53)
%d  The day of the month, 2 digits (range 00 to 31)
%D  The day of the year, 3 digits (range 000 to 366)
%F  Equivalent to %Y-%m-%d (ymd's canonical format)
%g  ISO week date year without the century (range 00 to 99)
%G  ISO week date year including the century
%j  Equivalent to %D
%m  The month in the current calendar (range 00 to 12)
%Q  The quarter of the year (range Q1 to Q4)
%q  The number of the quarter (range 01 to 04)
%s  The number of seconds since the Epoch.
%u  The weekday as number (range 01 to 07, Sunday being 07)
%U  The week count,  day of week is Sun (range 00 to 53)
%V  The ISO week count,  day of week is Mon (range 01 to 53)
%w  The weekday as number (range 00 to 06, Sunday being 00)
%W  The week count,  day of week is Mon (range 00 to 53)
%y  The year without a century (range 00 to 99)
%Y  The year including the century
%_y The year shortened to a single digit
%Z  The zone offset in hours and minutes (HH:MM) with
    a preceding sign (+ for offsets east of UTC, - for offsets
    west of UTC)

%Od The day as roman numerals
%Om The month as roman numerals
%Oy The two digit year as roman numerals
%OY The year including the century as roman numerals

%rs In time systems whose Epoch is different from the unix Epoch, this
    selects the number of seconds since then.
%rY In calendars with years that don't coincide with the Gregorian
    years, this selects the calendar's year.

%dth  The day of the month as an ordinal number, 1st, 2nd, 3rd, etc.
%mth  The month of the year as an ordinal number, 1st, 2nd, 3rd, etc.

%db The business day of the month (since last month's ultimo)
%dB Number of business days until this month's ultimo

Time specs:

%H  The hour of the day using a 24h clock, 2 digits (range 00 to 23)
%I  The hour of the day using a 12h clock, 2 digits (range 01 to 12)
%M  The minute (range 00 to 59)
%N  The nanoseconds (range 000000000 to 999999999)
%p  The string AM or PM, noon is PM and midnight is AM.
%P  Like %p but in lowercase
%S  The  (range 00 to 60, 60 is for leap seconds)
%T  Equivalent to %H:%M:%S

(Yes, %S really does say "The" and then nothing before the parenthesis in the original β€” I'm not fixing it, I'm just reporting the tea. πŸ’€)

General specs:

%n  A newline character
%t  A tab character
%%  A literal % character

Modifiers:

%O  Modifier to turn decimal numbers into Roman numerals
%r  Modifier to turn units into real units
%0  Modifier to turn on zero prefixes
%SPC  Modifier to turn on space prefixes
%-  Modifier to turn off prefixes altogether
th  Suffix, read and print ordinal numbers
b   Suffix, treat days as business days
🚨 By design dates before 1601-01-01 are not supported. So don't come at her with your medieval calendar requests, she will simply not.

For conformity here is a list of calendar designators and their corresponding format string:

ymd     %Y-%m-%d
ymcw    %Y-%m-%c-%w
ywd     %rY-W%V-%u
bizda   %Y-%m-%db
lilian     n/a
ldn        n/a
julian     n/a
jdn        n/a
matlab     n/a
mdn        n/a

These designators can be used as output format string, moreover, lilian/ldn and julian/jdn can also be used as input format string. ⭐


🧚 SPECIFYING DURATIONS 🧚

Some tools ("dadd", "dseq") need durations as their input. Durations are generally incompatible with input formats as specified by "-i|--input-format" and (at the moment) the input syntax is fixed. No wiggle room, bestie.

The general format is "+-Nunit" where "+" or "-" is the sign, "N" a number, and "unit" the unit as discussed below.

Units:

s  seconds
m  minutes
h  hours
rs real-life seconds, as in including leap  transitions

d  days
b  business days
mo months
y  years
πŸ“œ Historical lore drop: for historical reasons, we used to accept "m" in the context of date-only input as a qualifier for months. As of 0.4.4, this is no longer the case. She changed, she grew, we respect it.

πŸ’œ EXAMPLES πŸ’œ

Okay these are the fun part, let's go:

$ dadd 2012-03-01 1d
2012-03-02
$
$ dadd 2012-03-01 1mo
2012-04-01
$
$ dadd 2012-03-31 1mo
2012-04-30
$

(Notice how it clamped to April 30 instead of inventing an April 31? That's the good behavior. πŸ”₯)

$ dadd 2w2d <<EOF
2012-03-01
2012-03-02
2012-03-04
2012-03-08
2012-03-16
EOF
2012-03-17
2012-03-18
2012-03-20
2012-03-24
2012-04-01
$
$ dadd 10:01:00 1h6m
11:07:00
$
$ dadd 10:01:00 -1h6m
08:55:00
$
$ dadd 10:01:00 3605s
11:01:05
$

🫢 AUTHOR 🫢

Written by Sebastian Freundt <freundt@fresse.org>. Respect the author, bestie. πŸ‘‘


πŸŽ€ REPORTING BUGS πŸŽ€

Report bugs to: https://github.com/hroptatyr/dateutils/issues β€” go tell them, they wanna know, fr fr.


🌈 SEE ALSO 🌈

The full documentation for dateadd is maintained as a Texinfo manual. If the info and dateadd programs are properly installed at your site, the command

info (dateutils)dateadd

should give you access to the complete manual. πŸ¦‹


And that's the whole thing, bestie β€” go forth and add durations responsibly. This has been dateadd, from dateutils version 0.4.11, dated January 2024, page DATEADD(1). Periodt. πŸ’…βœ¨