4

I have a program which outputs dates in the following form:

Thu Mar 5 09:15:27 2015

This is very close to the output of date in Linux, but this format does not include time zone. Assuming I can capture the string Thu Mar 5 09:15:27 2015 as date1 and the string Thu Mar 5 09:30:58 2015 as date2 in bash, how can I get the number of seconds between those two dates (without having to write my own bash/python/etc. script to do the calculation)?

3
  • 1
    Difference in what time zone?
    – choroba
    Mar 5, 2015 at 16:08
  • Not sure what you are asking here. Assume that date1 and date2 are in the same time zone, in which case the time zone is irrelevant.
    – drjrm3
    Mar 5, 2015 at 16:11
  • 2
    Irrelevant? Are you aware that Daylight Saving Time changes don't happen at the same moment in all the timezones?
    – choroba
    Mar 5, 2015 at 16:18

3 Answers 3

8

Not sure what you mean by "without calculation". The following does the calculation...

date1="Thu Mar 5 09:15:27 2015"
date2="Thu Mar 5 09:30:58 2015"

printf "%s\n" $(( $(date -d "$date2" "+%s") - $(date -d "$date1" "+%s") ))
2
  • Thanks, maybe it was confusing but I just meant having to do calculations by hand: finding nsecs1, nsecs2, nmins1, nmins2, ... etc and having to do the subtraction myself.
    – drjrm3
    Mar 5, 2015 at 16:41
  • Maybe it's the version of date or because I'm using zsh (macOS Catalina) but this doesn't work for me. Running $ date -d "Thu Mar 5 09:15:27 2015" +%s outputs usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]. The date format appears to be completely different. Oct 17, 2019 at 14:22
2

Without the timezone information, you can't always give the correct answer.

#!/bin/bash
export TZ
for TZ in America/New_York Europe/Prague ; do
    d1=$(date -d 'Mar 8 01:59:59 2015' +%s)
    d2=$(date -d 'Mar 8 03:00:01 2015' +%s)
    echo "$TZ: $((d2-d1))"
done
6
  • choroba, doesn't a missing timezone mean the locally (configured) timezone? Then the result would be consistent for the defined locale. In other words, a difference in time stamps (both from the same locale) should give the expected result.
    – Janis
    Mar 5, 2015 at 16:31
  • @Janis: If the times come from a different timezone than the locally (configured) one, this could break. Try TZ=America/New_York date -d 'Mar 8 02:00:00 2015'
    – choroba
    Mar 5, 2015 at 16:33
  • Sure. But why do you think the OP would compare time stamps from different locales? Possible, but there's no indication that the OP has such a case.
    – Janis
    Mar 5, 2015 at 16:34
  • @Janis: Note that for existing times, the script answers the question.
    – choroba
    Mar 5, 2015 at 16:41
  • 1
    @Janis No, that's not enough. Consider Oct 25 00:59:59 2015 and Oct 25 00:59:59 2015 (yes, that's the same date twice) in Europe/London. Is the difference 0… or is one from before DST was switched off and one from after, making the difference 1 hour? You need a DST indication on the time, otherwise you can't always know what it refers to. Mar 5, 2015 at 23:03
1

Note that some other shells have the feature built in:

zsh

zmodload zsh/datetime
date1='Thu Mar 5 09:15:27 2015'
date2='Thu Mar 5 09:30:58 2015'
for v (date{1,2}) strftime -rs $v '%a %b %d %T %Y' ${(P)v}
echo $((date2 - date1))

See info zsh strftime and info zsh flags for the P parameter expansion flag for details.

ksh93

date1='Thu Mar 5 09:15:27 2015'
date2='Thu Mar 5 09:30:58 2015'
echo "$(($(printf '%(%s)T - %(%s)T' "$date2" "$date1")))"

See man <(printf --nroff 2>&1) within ksh for details.

(for both, dates are assumed to be in the local timezone).

5
  • could you please comment the ${(P)v} part? I don't know how to look for it on google as it is mostly syntax characters and doesn't look like a "standard" variable substitution (what does (P) stand for?). And likewise: %(%s)T ? (the inside %s should receive the value in "$date2" ? does %(some date here)T yeld an epoch?) (I can't test using those 2 shells) Oct 20, 2022 at 6:11
  • 1
    @OlivierDulac, see edit. Oct 24, 2022 at 20:03
  • Thank you! It seems similar to bash's variable indirect expansion : ${!var} (which, if var=foo, will fetch value of $foo. and ${!v} : will expand instead to every variable names starting with v). And for the %(...)T printf construct : it is indeed from ksh93 and explained for exemple in blog.fpmurphy.com/2018/05/bash-printf-t-option.html Oct 25, 2022 at 9:45
  • 1
    Yes, though note that bash's ${!var} does almost the opposite of what ${!var} did in ksh93. bash added %(...)T to its own printf recently but doesn't do the date parsing that ksh93 does. In general you don't want to read the documentation of one shell to learn about another shell. Oct 25, 2022 at 10:00
  • I agree, and thank you for all the answer and further clarifications. Oct 25, 2022 at 16:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .