Jan Engelhardt wrote:
> There is (my default zone is /etc/localtime ->
> /usr/share/zoneinfo/Europe/Berlin):
> 
>       $ TZ=GMT date +%s -d "`date '+%Y-%m-%d %H:%M:%S'`"
>       1204325194
>       $ date +%s
>       1204321595
> 
>       (now with not-so-fast typing! :)

:-)

> I wanted to get the number of seconds since the start of the day.
> 
>       echo $[`date +%s` % 86400];

Note that the $[expression] syntax is deprecated and is scheduled for
removal from a future version of the shell.  Please convert to using
the now standard $((expression)) syntax.

  echo $(( $(date +%s) % 86400 ));

> unfortunately does not do the right thing — it would show
> 82800 instead of 0 when it is (local) midnight.

Midnight and noon are neither a.m. nor p.m. but midnight is considered
the start of the day.  Therefore normal convention would use a seconds
range of 0-86399 seconds in any given day similar to 0-59 seconds in a
minute.  Do I understand that you want to use 1-86400?  That would be
like using 1-60 seconds in a minute, right?  In which case I would
simply special case the zero case and convert it to the max value
specially.  But I probably wouldn't do it.

I can't think of any totally race free way to do this without invoking
date multiple times.  The problem is right around midnight we want to
avoid having one invocation from before and one from after.  My
technique is to get the time once and then shape that single point in
time as I need it so as to avoid any possibility of problems at
midnight.  But I don't see that as being too inefficient so I would
simply invoke date several times and not worry about it.  Perhaps
someone else will have a better optimized strategy.

  nowseconds=$(date +%s)
  dateday=$(date -d "$nowseconds" +%F) # e.g. 2008-02-29
  secondsatdaystart=$(date -d "$dateday" +%s)
  secondssincedaystart=$(( $nowseconds - $secondsatdaystart ))
  echo $secondssincedaystart

That still treats midnight as 0 seconds since day start.  I think that
is the right thing to do but if you want it the other way then you
could add a case.

  nowseconds=$(date +%s)
  dateday=$(date -d "$nowseconds" +%F) # e.g. 2008-02-29
  secondsatdaystart=$(date -d "$dateday" +%s)
  secondssincedaystart=$(( $nowseconds - $secondsatdaystart ))
  case $secondssincedaystart in (0) secondssincedaystart=86400 ;; esac
  echo $secondssincedaystart

I am also sure there are ways to optimize this further but this seemed
good enough.  I didn't test that very much but the numbers seemed
reasonable to me at brief glance at them.

Bob


_______________________________________________
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to