Linux date seconds to date

Convert a time span in seconds to formatted time in shell

I have a variable of $i which is seconds in a shell script, and I am trying to convert it to 24 HOUR HH:MM:SS. Is this possible in shell?

7 Answers 7

Here’s a fun hacky way to do exactly what you are looking for =)

Explanation:

  • The date utility allows you to specify a time, from string, in seconds since 1970-01-01 00:00:00 UTC, and output it in whatever format you specify.
  • The -u option is to display UTC time, so it doesn’t factor in timezone offsets (since start time from 1970 is in UTC)
  • The following parts are GNU date -specific (Linux):
    • The -d part tells date to accept the time information from string instead of using now
    • The @$ part is how you tell date that $i is in seconds

    Look at Alan Tam’s answer below for how this works in a Mac/Unix : stackoverflow.com/a/21822510/243709

    I think it is worth mentioning this only works for i lower than 86400s: i=86400; date -u -d @$ +»%T» will give you 00:00:00

    Another approach: arithmetic

    i=6789 ((sec=i%60, i/=60, min=i%60, hrs=i/60)) timestamp=$(printf "%d:%02d:%02d" $hrs $min $sec) echo $timestamp 

    The -d argument applies to date from coreutils (Linux) only.

    If $i represents some date in second since the Epoch, you could display it with

    but you seems to suppose that $i is an interval (e.g. some duration) not a date, and then I don’t understand what you want.

    convertsecs() < ((h=$/3600)) ((m=($%3600)/60)) ((s=$%60)) printf "%02d:%02d:%02d\n" $h $m $s > TIME1="36" TIME2="1036" TIME3="91925" echo $(convertsecs $TIME1) echo $(convertsecs $TIME2) echo $(convertsecs $TIME3) 

    Example of my second to day, hour, minute, second converter:

    # convert seconds to day-hour:min:sec convertsecs2dhms() < ((d=$/(60*60*24))) ((h=($%(60*60*24))/(60*60))) ((m=($%(60*60))/60)) ((s=$%60)) printf "%02d-%02d:%02d:%02d\n" $d $h $m $s # PRETTY OUTPUT: uncomment below printf and comment out above printf if you want prettier output # printf "%02dd %02dh %02dm %02ds\n" $d $h $m $s > # setting test variables: testing some constant variables & evaluated variables TIME1="36" TIME2="1036" TIME3="91925" # one way to output results ((TIME4=$TIME3*2)) # 183850 ((TIME5=$TIME3*$TIME1)) # 3309300 ((TIME6=100*86400+3*3600+40*60+31)) # 8653231 s = 100 days + 3 hours + 40 min + 31 sec # outputting results: another way to show results (via echo & command substitution with backticks) echo $TIME1 - `convertsecs2dhms $TIME1` echo $TIME2 - `convertsecs2dhms $TIME2` echo $TIME3 - `convertsecs2dhms $TIME3` echo $TIME4 - `convertsecs2dhms $TIME4` echo $TIME5 - `convertsecs2dhms $TIME5` echo $TIME6 - `convertsecs2dhms $TIME6` # OUTPUT WOULD BE LIKE THIS (If none pretty printf used): # 36 - 00-00:00:36 # 1036 - 00-00:17:16 # 91925 - 01-01:32:05 # 183850 - 02-03:04:10 # 3309300 - 38-07:15:00 # 8653231 - 100-03:40:31 # OUTPUT WOULD BE LIKE THIS (If pretty printf used): # 36 - 00d 00h 00m 36s # 1036 - 00d 00h 17m 16s # 91925 - 01d 01h 32m 05s # 183850 - 02d 03h 04m 10s # 3309300 - 38d 07h 15m 00s # 1000000000 - 11574d 01h 46m 40s 

    Источник

    Convert a number of seconds elapsed to date from arbitrary start date

    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.

    @MichaelHomer The year 0001 is not post-epoch! And the problem is that most date/time functions cannot handle that.

    @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.

    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».

    3 Answers 3

    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 2 32 , so you’ll need a shell capable of 64-bit arithmetic to handle it. Your number_of_seconds will be more than 2 32 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)) 
    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 

    @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é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

    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 3 rd of November 1654, that’s not necessarily the same date as the same 3 rd 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 

    Источник

    Get current time in seconds since the Epoch on Linux, Bash

    I need something simple like date , but in seconds since 1970 instead of the current date, hours, minutes, and seconds. date doesn’t seem to offer that option. Is there an easy way?

    Some versions of date have it and some don’t. So it’s not always present. I ran ‘type -a date’ and used a different version and that worked.

    @TheBonsai that’s not part of the POSIX standard version of the ‘date’ tool. Just because your version has it (probably GNU), you shouldn’t assume everyone’s implementations do.

    7 Answers 7

    As recently corrected in the date manual:

    %s = seconds since the Epoch (1970-01-01 00:00 UTC)

    the date manpge should be changed from %s seconds since 1970-01-01 00:00:00 UTC to %s seconds since the epoch, 1970-01-01 00:00:00 UTC because I missed it in there.

    Doesn’t work for me. man date does not show %s. I must have a very old version of bash (3.2.51(1) for Solaris)?

    @livefree75 date is not built into bash , so your version of bash has nothing to do with which date implementation your system ships with.

    Get the seconds since epoch(Jan 1 1970) for any given date(e.g Oct 21 1973).

    Convert the number of seconds back to date

    The command date is pretty versatile. Another cool thing you can do with date(shamelessly copied from date —help ). Show the local time for 9AM next Friday on the west coast of the US

    date --date='TZ="America/Los_Angeles" 09:00 next Fri' 

    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 «Oct 21 1973» +%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]

    @JoshuaPinter and others on macOS, I had the same question. man date shows that the option(s) used to parse another date string are -j and -f expectedformat on macOS. ( -d is used to set daylight savings.)

    The date command above is from gnu coreutils pacakge. On mac, gnu coreutils package can be installed with brew or macports. After installing, the binary is named as gdate to distinguish it from macOS’s preinstalled /bin/date

    Pure bash solution

    Since bash 5.0 (released on 7 Jan 2019) you can use the built-in variable EPOCHSECONDS .

    $ echo $EPOCHSECONDS 1547624774 

    There is also EPOCHREALTIME which includes fractions of seconds.

    $ echo $EPOCHREALTIME 1547624774.371210 

    EPOCHREALTIME can be converted to micro-seconds (μs) by removing the decimal point. This might be of interest when using bash ‘s built-in arithmetic (( expression )) which can only handle integers.

    In all examples from above the printed time values are equal for better readability. In reality the time values would differ since each command takes a small amount of time to be executed.

    So far, all the answers use the external program date .

    Since Bash 4.2, printf has a new modifier %(dateformat)T that, when used with argument -1 outputs the current date with format given by dateformat , handled by strftime(3) ( man 3 strftime for informations about the formats).

    So, for a pure Bash solution:

    or if you need to store the result in a variable var :

    No external programs and no subshells!

    Since Bash 4.3, it’s even possible to not specify the -1 :

    (but it might be wiser to always give the argument -1 nonetheless).

    If you use -2 as argument instead of -1 , Bash will use the time the shell was started instead of the current date. This can be used to compute elapsed times

    $ printf -v beg '%(%s)T\n' -2 $ printf -v now '%(%s)T\n' -1 $ echo beg=$beg now=$now elapsed=$((now-beg)) beg=1583949610 now=1583953032 elapsed=3422 

    You want to use -2 in case you have a longer running job (think of a script to control you backups) and send a mail in the end «Backup started at $somewhen completed at $now» — which can be accomplished with -2 avoiding to store a dedicated variable at the beginning.

    With most Awk implementations:

    Wow, had to go look this one up. This is a pragmatic solution, but not necessarily good/portable. It seems that implementations of awk srand() are typically seeded with the current date/time. The second call to srand() returns the value previously used as the seed.

    POSIX compliant as well, because this is how NAWK behaves. Very nice. I was trying to remember this one and tracked down your post. Thanks.

    Would it be wrong of me to suggest awk ‘BEGIN

    This is an extension to what @pellucide has done, but for Macs:

    To determine the number of seconds since epoch (Jan 1 1970) for any given date (e.g. Oct 21 1973)

    $ date -j -f "%b %d %Y %T" "Oct 21 1973 00:00:00" "+%s" 120034800 

    Please note, that for completeness, I have added the time part to the format. The reason being is that date will take whatever date part you gave it and add the current time to the value provided. For example, if you execute the above command at 4:19PM, without the ’00:00:00′ part, it will add the time automatically. Such that «Oct 21 1973» will be parsed as «Oct 21 1973 16:19:00». That may not be what you want.

    To convert your timestamp back to a date:

    $ date -j -r 120034800 Sun Oct 21 00:00:00 PDT 1973 

    Источник

    Читайте также:  Configure git on linux
Оцените статью
Adblock
detector