0

I need to get the time difference between two unix-timestamps in hour, minute, and seconds. I can get the different in minutes and seconds correctly but the hour is always wrong.

I have two unix-timestamps and I subtract to get the difference.

1595455100 - 1595452147 = 2953 (That's the time difference between 2:09:07pm and 2:58:20pm on the same day)

Then I do date -d @2953 +'%I:%M:%S'

I get 04:49:13 but I expect to get 0:49:13

I'd also tried date -d @2953 +'%H:%M:%S' and date -d @2953 +'%T' and get 16:49:13. I've also checked differences greater than an hour, the difference in minute and seconds is still correct but the hour is still wrong.

I don't understand the Hour format and appreciate any help.

ctb116
  • 1
  • 1
  • You are getting the local time. Put `-u` option to the `date` command. – tshiono Apr 14 '22 at 03:56
  • Using `date` to print a time interval won't work when the time interval is longer than 24 hours. Watch what happens when you use 222953 and then 992953. – Jeff Holt Apr 14 '22 at 04:02
  • So long as you need only hours, minutes, and seconds, then [this](https://stackoverflow.com/a/22141974/1707353) will work. – Jeff Holt Apr 14 '22 at 04:12
  • @JeffHolt Thanks! That worked for what I needed. I am still confused why `date` doesn't work for the hour. The two timestamps I gave above were in the same 24 hour interval, 0hrs 49min and 13 secs apart. I tried also comparing two timestamps over a month apart and again minute and seconds were correct but hour was not. – ctb116 Apr 14 '22 at 04:29
  • tshiono's comment says it all. Your local timezone is not UTC and so `date` adds the time between UTC and your local timezone to the intuitive difference in the value you give it. It's not unreasonable to expect the `date` command to act that way. It was never intended to do what you are wanting. – Jeff Holt Apr 14 '22 at 04:33
  • Try `TZ=UTC0 date -d @86399 +%H:%M:%S` and then try `TZ=UTC0 date -d @86400 +%H:%M:%S` to see tshiono's point play out wrt to my comments. – Jeff Holt Apr 14 '22 at 04:36

2 Answers2

0

You don't necessarily need date for this conversion. You can use integer math and printf for fun and profit.

start=1595452147
end=1595455100
s=$((end - start))
time=$(printf %02d:%02d:%02d $((s / 3600)) $((s / 60 % 60)) $((s % 60)))
echo $time

There may be a way to do it with date too, but the above should work reliably.

Pi Marillion
  • 4,465
  • 1
  • 19
  • 20
0

The reason for wrong answer is because the timestamp @0 is not an absolute 0 of some kind. It is the fixed datetime at:

date -d@0 -u
# Thu Jan 1 00:00:00 UTC 1970

You could do:

eval echo `date -d @$(($ts1 - $ts2)) -u +'$((%d - 01)) days, %H:%M:%Ss'`
# 0 days, 00:09:20s

as long as number of days is less than 31

Himanshu Tanwar
  • 198
  • 1
  • 11