Path: utzoo!utgpu!cunews!bnrgate!brchh104!brchs1!bnr.ca!rice.edu!sun-spots-request From: knutson%sw.mcc.com@mcc.com (Jim Knutson) Newsgroups: comp.sys.sun Subject: Re: CRON problem after Daylight time change Keywords: No Digest Subjects during Flush Message-ID: <3966@brchh104.bnr.ca> Date: 27 Jun 91 20:22:00 GMT Sender: news@brchh104.bnr.ca Organization: Sunspots, Flush Mode Lines: 171 Approved: sun-spots@rice.edu X-Original-Date: Wed, 12 Jun 91 13:28:33 CDT I posted this to sun-managers a while back. It will restart cron appropriately at each time change. # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by knutson on Wed Jun 12 13:25:51 CDT 1991 # Contents: dstcronfix echo x - dstcronfix sed 's/^@//' > "dstcronfix" <<'@//E*O*F dstcronfix//' #!/bin/sh # @(#)dstcronfix 1.3 4/15/91 # # NAME # dstcronfix - restart cron when DST changes # # SYNOPSIS # dstcronfix # # DESCRIPTION # dstcronfix determines when the next DST change takes place and # then schedules an at job to restart cron after the change has # taken place. # # The at job is scheduled to start just before the time change. # It then waits until the time change has occured before killing # and restarting cron. It also reschedules itself for the next # DST change. # # The leadtime for scheduling is set in the script and should be # set to a value which will allow cron to run it before the DST # change occurs. For SunOS 4.0 and greater, at/cron have a 1 # minute granularity. Other systems which execute atrun from # cron must set the lead time to account for the granularity in # running atrun. # # SEE ALSO # at(1), cron(8), zdump(8) # # AUTHOR # Jim Knutson # # BUGS # Restarts cron twice in the fall. # TIMEZONE=US/Central LEADTIME=1 # number of minutes of lead time TMP=/tmp/.dst$$ PATH=/usr/bin:/usr/ucb:/usr/etc # return month number for a given month name monthnum() { case "$1" in Jan) echo 01;; Feb) echo 02;; Mar) echo 03;; Apr) echo 04;; May) echo 05;; Jun) echo 06;; Jul) echo 07;; Aug) echo 08;; Sep) echo 09;; Oct) echo 10;; Nov) echo 11;; Dec) echo 12;; esac } # compare two dates of the form "MMM YY HH:MM:SS YYYY" and # return <0 if date1 < date2, 0 if date1 = date2, >0 if date1 > date2 datecmp() { eval `echo "$1" | sed 's/:/ /g' | awk '{printf "mon1=%s day1=%s hr1=%s min1=%s sec1=%s yr1=%s\n",$1,$2,$3,$4,$5,$6}'` eval `echo "$2" | sed 's/:/ /g' | awk '{printf "mon2=%s day2=%s hr2=%s min2=%s sec2=%s yr2=%s\n",$1,$2,$3,$4,$5,$6}'` diff=`expr $yr1 - $yr2` if [ $diff -ne 0 ]; then echo $diff return fi mm1=`monthnum $mon1` mm2=`monthnum $mon2` diff=`expr $mm1 - $mm2` if [ $diff -ne 0 ]; then echo $diff return fi diff=`expr $day1 - $day2` if [ $diff -ne 0 ]; then echo $diff return fi diff=`expr $hr1 - $hr2` if [ $diff -ne 0 ]; then echo $diff return fi diff=`expr $min1 - $min2` if [ $diff -ne 0 ]; then echo $diff return fi diff=`expr $sec1 - $sec2` echo $diff return } # translate a date of the form "MMM DD HH:MM:SS YYYY" into a # form suitable for use with the at command. atdate () { eval `echo $* | sed 's/:/ /g' | awk '{printf "mon=%s day=%s hr=%s min=%s sec=%s yr=%s\n",$1,$2,$3,$4,$5,$6}'` min=`expr $min - $LEADTIME` if [ $min -lt 0 ]; then echo "`basename $0`: too much lead time" fi echo "$hr:$min $mon $day" } # get seconds from a date of the form "MMM DD HH:MM:SS YYYY" seconds() { expr "$*" : '.*:..:\(..\) .*' } # get DST change data trap "rm -f $TMP; exit 1" 2 3 zdump -v $TIMEZONE >$TMP # save the current date for comparison set `head -1 $TMP` NOW="$3 $4 $5 $6" THISYEAR=$6 # look at the DST change data and find the next change sed -e '1d' -e 's/isdst=//' -e 's/.*= ... //' $TMP | \ while read timeinfo; do set $timeinfo # speed things up by ignoring old years if [ $THISYEAR -gt $4 ]; then continue fi DATE="$1 $2 $3 $4" # if this DST change is in the future if [ `datecmp "$NOW" "$DATE"` -lt 0 ]; then # schedule at job to fix cron and start the cycle all over again at `atdate $DATE` <