1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
|
Dateutils
=========
[![Build Status](https://secure.travis-ci.org/hroptatyr/dateutils.png?branch=master)](http://travis-ci.org/hroptatyr/dateutils)
[![build status](https://gitlab.com/hroptatyr/dateutils/badges/master/build.svg)](https://gitlab.com/hroptatyr/dateutils/commits/master)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/2197/badge.svg)](https://scan.coverity.com/projects/2197)
Dateutils are a bunch of tools that revolve around fiddling with dates
and times on the command line with a strong focus on use cases that
arise when dealing with large amounts of financial data.
Dateutils are hosted primarily on github:
+ github page: <https://github.com/hroptatyr/dateutils>
+ project homepage: <http://www.fresse.org/dateutils/>
+ downloads: <https://bitbucket.org/hroptatyr/dateutils/downloads>
Below is a short list of examples that demonstrate what dateutils can
do, for full specs refer to the info and man pages. For installation
instructions refer to the INSTALL file.
Dateutils commands are prefixed with a `date` but otherwise resemble
known unix commands for reasons of intuition. The only exception being
`strptime` which is analogous to the libc function of the same name.
+ `strptime` Command line version of the C function
+ `dateadd` Add durations to dates or times
+ `dateconv` Convert dates or times between calendars
+ `datediff` Compute durations between dates or times
+ `dategrep` Grep dates or times in input streams
+ `dateround` Round dates or times to "fuller" values
+ `dateseq` Generate sequences of dates or times
+ `datesort` Sort chronologically.
+ `datetest` Compare dates or times
+ `datezone` Convert date/times to timezones in bulk
Examples
========
I love everything explained by example to get a first impression.
So here it comes.
dateseq
-------
A tool mimicking seq(1) but whose inputs are from the domain of dates
rather than integers. Typically scripts use something like
$ for i in $(seq 0 9); do
date -d "2010-01-01 +${i} days" "+%F"
done
which now can be shortened to
$ dateseq 2010-01-01 2010-01-10
with the additional benefit that the end date can be given directly
instead of being computed from the start date and an interval in
days. Also, it provides date specific features that would be a PITA
to implement using the above seq(1)/date(1) approach, like skipping
certain weekdays:
$ dateseq 2010-01-01 2010-01-10 --skip sat,sun
=>
2010-01-01
2010-01-04
2010-01-05
2010-01-06
2010-01-07
2010-01-08
dateseq also works on times:
$ dateseq 12:00:00 5m 12:17:00
=>
12:00:00
12:05:00
12:10:00
12:15:00
and also date-times:
$ dateseq --compute-from-last 2012-01-02T12:00:00 5m 2012-01-02T12:17:00
=>
2012-01-02T12:02:00
2012-01-02T12:07:00
2012-01-02T12:12:00
2012-01-02T12:17:00
dateconv
--------
A tool to convert dates between different calendric systems and/or
time zones. While other such tools usually focus on converting
Gregorian dates to, say, the Chinese calendar, dconv aims at
supporting calendric systems which are essential in financial
contexts.
To convert a (Gregorian) date into the so called ymcw representation:
$ dateconv 2012-03-04 -f "%Y-%m-%c-%w"
=>
2012-03-01-00
and vice versa:
$ dateconv 2012-03-01-Sun -i "%Y-%m-%c-%a" -f '%F'
=>
2012-03-04
where the ymcw representation means, the `%c`-th `%w` of the month in
a given year. This is useful if dates are specified like, the third
Thursday in May for instance.
dateconv can also be used to convert occurrences of dates, times or
date-times in an input stream on the fly
$ dateconv -S -i '%b/%d %Y at %I:%M %P' <<EOF
Remember we meet on Mar/03 2012 at 02:30 pm
EOF
=>
Remember we meet on 2012-03-03T14:30:00
and most prominently to convert between time zones:
$ dateconv --from-zone "America/Chicago" --zone "Asia/Tokyo" 2012-01-04T09:33:00
=>
2012-01-05T00:33:00
$ dateconv --zone "America/Chicago" now -f "%d %b %Y %T"
=>
05 Apr 2012 11:11:57
datetest
--------
A tool to perform date comparison in the shell, it's modelled after
`test(1)` but with proper command line options.
$ if datetest today --gt 2010-01-01; then
echo "yes"
fi
=>
yes
dateadd
-------
A tool to perform date arithmetic (date maths) in the shell. Given
a date and a list of durations this will compute new dates. Given a
duration and a list of dates this will compute new dates.
$ dateadd 2010-02-02 +4d
=>
2010-02-06
$ dateadd 2010-02-02 +1w
=>
2010-02-09
$ dateadd -1d <<EOF
2001-01-05
2001-01-01
EOF
=>
2001-01-04
2000-12-31
Adding durations to times:
$ dateadd 12:05:00 +10m
=>
12:15:00
and even date-times:
$ dateadd 2012-03-12T12:05:00 -1d4h
=>
2012-03-11T08:05:00
If supported by the system's zoneinfo database leap-second adjusted
calculations are possible. Use the unit `rs` to denote "real" seconds:
$ dateadd '2012-06-30 23:59:30' +30rs
=>
2012-06-30T23:59:60
as opposed to:
$ dateadd '2012-06-30 23:59:30' +30s
=>
2012-07-01T00:00:00
datediff
--------
A tool to calculate the difference between two (or more) dates. This
is somewhat the converse of dadd. Outputs will be durations that,
when added to the first date, give the second date.
Get the number of days between two dates:
$ datediff 2001-02-08 2001-03-02
=>
22
The duration format can be controlled through the `-f` switch:
$ datediff 2001-02-08 2001-03-09 -f "%m month and %d day"
=>
1 month and 1 day
datediff also accepts time stamps as input:
$ datediff 2012-03-01T12:17:00 2012-03-02T14:00:00
=>
92580s
The `-f` switch does the right thing:
$ datediff 2012-03-01T12:17:00 2012-03-02T14:00:00 -f '%dd %Ss'
=>
1d 6180s
compare to:
$ datediff 2012-03-01T12:17:00 2012-03-02T14:00:00 -f '%dd %Hh %Ss'
=>
1d 1h 2580s
If supported by the system's zoneinfo database leap-second adjusted
calculations can be made. Use the format specifier `%rS` to get the
elapsed time in "real" seconds:
datediff '2012-06-30 23:59:30' '2012-07-01 00:00:30' -f '%rS'
=>
61
dategrep
--------
A tool to extract lines from an input stream that match certain
criteria, showing either the line or the match:
$ dategrep '<2012-03-01' <<EOF
Feb 2012-02-28
Feb 2012-02-29 leap day
Mar 2012-03-01
Mar 2012-03-02
EOF
=>
Feb 2012-02-28
Feb 2012-02-29 leap day
dateround
---------
A tool to "round" dates or time stamps to a recurring point in time,
like the next/previous January or the next/previous Thursday.
Round (backwards) to the first of the current month:
$ dateround '2011-08-22' -1
=>
2011-08-01
Find the next Monday from the current date (today is 2016-01-08):
$ dateround today Mon
=>
2015-01-11
Go back to last September, then round to the end of the month:
$ dateround today -- -Sep +31d
=>
2015-09-30
Round a stream of dates strictly to the next month's first:
$ dateround -S -n 1 <<EOF
pay cable 2012-02-28
pay gas 2012-02-29
pay rent 2012-03-01
redeem loan 2012-03-02
EOF
=>
pay cable 2012-03-01
pay gas 2012-03-01
pay rent 2012-04-01
redeem loan 2012-04-01
Round a timeseries to the next minute (i.e. the seconds part is 00)
and then to the next half-past time (and convert to ISO):
$ dateround -S 0s30m -i '%d/%m/%Y %T' -f '%F %T' <<EOF
06/03/2012 14:27:12 eventA
06/03/2012 14:29:59 eventA
06/03/2012 14:30:00 eventB
06/03/2012 14:30:01 eventB
EOF
=>
2012-03-06 14:30:00 eventA
2012-03-06 14:30:00 eventA
2012-03-06 14:30:00 eventB
2012-03-06 15:30:00 eventB
Alternatively, if you divide the day into half-hours you can round to
one of those using the co-class notation:
$ dateround -S /30m -i '%d/%m/%Y %T' -f '%F %T' <<EOF
06/03/2012 14:27:12 eventA
06/03/2012 14:29:59 eventA
06/03/2012 14:30:00 eventB
06/03/2012 14:30:01 eventB
EOF
=>
2012-03-06 14:30:00 eventA
2012-03-06 14:30:00 eventA
2012-03-06 14:30:00 eventB
2012-03-06 15:00:00 eventB
This is largely identical to the previous example except, that a full
hour (being an even multiple of half-hours) is a possible rounding
target.
datesort
-----
A tool to bring the lines of a file into chronological order.
At the moment the `datesort` tool depends on `sort(1)` with support
for fields, in particular `-t` to select a separator and `-k` to sort
by a particular field.
$ datesort <<EOF
2009-06-03 caev="DVCA" secu="VOD" exch="XLON" xdte="2009-06-03" nett/GBX="5.2"
2011-11-16 caev="DVCA" secu="VOD" exch="XLON" xdte="2011-11-16" nett/GBX="3.05"
2013-11-20 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-11-20" nett/GBX="3.53"
2012-06-06 caev="DVCA" secu="VOD" exch="XLON" xdte="2012-06-06" nett/GBX="6.47"
2013-06-12 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-06-12" nett/GBX="6.92"
2010-11-17 caev="DVCA" secu="VOD" exch="XLON" xdte="2010-11-17" nett/GBX="2.85"
EOF
=>
2009-06-03 caev="DVCA" secu="VOD" exch="XLON" xdte="2009-06-03" nett/GBX="5.2"
2010-11-17 caev="DVCA" secu="VOD" exch="XLON" xdte="2010-11-17" nett/GBX="2.85"
2011-11-16 caev="DVCA" secu="VOD" exch="XLON" xdte="2011-11-16" nett/GBX="3.05"
2012-06-06 caev="DVCA" secu="VOD" exch="XLON" xdte="2012-06-06" nett/GBX="6.47"
2013-06-12 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-06-12" nett/GBX="6.92"
2013-11-20 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-11-20" nett/GBX="3.53"
datezone
--------
A tool to quickly inspect date/time values in different timezones.
The result will be a matrix that shows every date-time value in every
timezone:
$ datezone Europe/Berlin Australia/Sydney now 2014-06-30T05:00:00
=>
2014-01-30T17:37:13+01:00 Europe/Berlin
2014-01-31T03:37:13+11:00 Australia/Sydney
2014-06-30T07:00:00+02:00 Europe/Berlin
2014-06-30T15:00:00+10:00 Australia/Sydney
The `datezone` tool can also be used to obtain the next or previous DST
transition relative to a given date/time:
$ datezone --next Europe/Berlin Australia/Sydney 2013-02-19
=>
2013-03-31T02:00:00+01:00 -> 2013-03-31T03:00:00+02:00 Europe/Berlin
2013-04-07T03:00:00+11:00 -> 2013-04-07T02:00:00+10:00 Australia/Sydney
where the left time stamp denotes the current zone offset and the
right side is the zone offset after the transition. The date/time
indicates the exact moment when the transition is about to take
place.
In essence `datezone` is a better [`zdump(8)`][3].
strptime
--------
A tool that brings the flexibility of [`strptime(3)`][1] to the
command line. While (at least GNU) [`date(1)`][2] has support for
output formats, it lacks any kind of support to read arbitrary input
from the domain of dates, in particular when the input format is
specifically known beforehand and only matching dates/times shall be
considered.
With the `strptime` tool reading weird dates like `Mon, May-01/2000`
becomes a matter of
strptime -i "%a, %b-%d/%Y" "Mon, May-01/2000"
=>
2000-05-01
just as you would have done in C.
Note that `strptime` actually uses the system libc's strptime routine,
and for output the system's strftime routine. Input and output
modifiers will therefore vary between systems.
For a portable parser/printer combination use `dateconv` as described
above. Its input and output format specifiers are independent of the
C runtime.
Similar projects
================
In no particular order and without any claim to completeness:
+ dateexpr: <http://www.eskimo.com/~scs/src/#dateexpr>
+ allanfalloon's dateutils: <https://github.com/alanfalloon/dateutils>
+ yest <http://yest.sourceforge.net/>
Use the one that best fits your purpose. And in case you happen to like
mine, vote: [dateutils' openhub page](https://www.openhub.net/p/dateutils)
[1]: http://linux.die.net/man/3/strptime
[2]: http://linux.die.net/man/1/date
[3]: http://linux.die.net/man/8/zdump
<!--
Local variables:
mode: auto-fill
fill-column: 72
filladapt-mode: t
End:
-->
|