2

I want to convert a particular amount of seconds to a date. In my case the it's the number of seconds elapsed since 1st of January 0001.

If it were for seconds elapsed from epoch it would be easy: $ date -r nr_of_seconds. It would be awesome if there was a way of telling date to start at a particular date. Is there such an option (the -v option almost does what I need, ... I think)?

I'm on a Mac.

  • You need a geographic reference point to do that. If all your dates are post-epoch, you can just subtract the number of seconds before the epoch. – Michael Homer Aug 12 '14 at 9:43
  • 1
    @MichaelHomer The year 0001 is not post-epoch! And the problem is that most date/time functions cannot handle that. – vinc17 Aug 12 '14 at 9:45
  • 1
    @vinc17: If all your dates are post-epoch, you can subtract. If they aren't, you need a) a geographic reference point and b) (something akin to) Julian day translation for that locale. That is what I said. – Michael Homer Aug 12 '14 at 9:47
  • there are 719164 days between 1/1/0001 (UT) and 1/1/1070 (UT). But if you want to compute the seconds, remember that earth didn't always spin with the same speed. You should decide what do you mean when you say "1/1/0001". – pqnet Aug 12 '14 at 10:33
0

date -r almost does the job. All you need to do is shift the origin, which is an addition.

date -r $((number_of_seconds - epoch))

where epoch is the number of seconds between 1 January 1 and 1 January 1970. The value of epoch depends on your calendar.

In the Gregorian calendar, there are 477 leap years between 1 and 1970, so 365 * 1969 + 477 = 719162 days = 62135596800 seconds. Note that this number is greater than 232, so you'll need a shell capable of 64-bit arithmetic to handle it. Your number_of_seconds will be more than 232 anyway if it represents dates beyond the second century AD. I think bash supports 64-bit arithmetic even on older, 32-bit OSX but I'm not sure.

date -r $((number_of_seconds - 62135596800))
1

You can use this:

echo $(( `date +%s` - ` date --date=yesterday +%s ` ))
86400

You can replace 'yesterday' by any date. For example:

echo $(( `date +%s` - ` date --date='Tue Aug 9 11:44:34 CEST 2014' +%s ` ))
259209

Tested on GNU/Linux.

  • It even works with the year 0001. – vinc17 Aug 12 '14 at 9:49
  • Note that GNU date uses the Gregorian calendar (for all dates). – Stéphane Chazelas Aug 12 '14 at 10:11
  • it works with year 0001, but is it correct? – pqnet Aug 12 '14 at 10:34
  • @pqnet. good question. It disagrees with my wide_strftime on 0001-01-01 (and AFAIK, Julian and Gregorian calendars are meant to agree on that date). I remember checking against GNU cal when I wrote it so it would seem GNU date and GNU cal don't agree. – Stéphane Chazelas Aug 12 '14 at 10:38
  • @StéphaneChazelas I used aa.usno.navy.mil/data/docs/JulianDate.php to compute the value of 719164 days from 1/1/1 to 1/1/1970. It lets you input a date and yields the number of days from the from the julian epoch (somewhere around 4000 BC). Julian and Gregorian calendars agree on winter equinox of 325 AD (year of the first church council). From what I read on the page, it should be a difference of days between Julian 1/1/1 and Gregorian 1/1/1970 – pqnet Aug 12 '14 at 10:45
0

The problem is that not everyone agrees on what the pre-1923 dates are. We (westerners) are now using the Gregorian calendar. Before 1582, people were using the Julian calendar. In between 1582 and 1923, some people used one or the other.

For instance, England switched to the Gregorian calendar in 1752 and that's what the cal command uses as the switching point. See the output of cal 9 1752.

So if you find an old English document that refers to the 3rd of November 1654, that's not necessarily the same date as the same 3rd of November 1654 referred to in a French document. Both the French and English people at the time would agree on what date 0001-01-01 was (as in for instance what happened on that day), but that's not the date GNU date for instance thinks it was.

I once wrote a few POSIX shell functions for arbitrary date calculation using the same calendar switch as cal and ignoring leap seconds. You can find it at: https://github.com/stephane-chazelas/misc-scripts/blob/master/wide_strftime.sh

For instance, to know what the date was 10G seconds (assuming 86400 seconds per day, so not all seconds lasting the same amount of time) after 0001-01-01 00:00:00 GMT Julian Calendar:

$ timegm 1 1 1 0 0 0
$ wide_strftime "%c" "$((REPLY + 10000000000))"
echo "$REPLY"
$ echo "$REPLY"
Mon Nov 18 17:46:40 0317

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.