Tulosta
Howto handle date and date calculation

Date and date calculation

Using date command

Basic date without GNU extension include properties to print current date in many formats. Date support locales.

Never try to parse date command output without arguments, because then date use locales = output format is something.

date include special argument starting with + symbol. Using +... argument you can set output format. Read man date to get all options.

H=$(date '+%H') # current hour M=$(date '+%M') # current minute S=$(date '+%S') # current sec Y=$(date '+%Y') # current year, long format m=$(date '+%m') # current month d=$(date '+%d') # current day # set H, M and S using one date call = same time, previous solution is not - maybe eval "$( date '+H=%H M=%M S=%S' )"

Using ksh builtin printf %T

This is ksh own extension, but very fast and usable.

You can use same arguments as in date command, but printf is builtin command. Printf include using %T format special argument now, which take current time.

How to make default date using ksh ? printf "%T" now

%T format you can expand using between () rule which works same way as date arguments.

printf "%(Today is %F or you can write %d.%m.%Y ...)T" now

H=$(printf "%(%H)T" now) # hour Y=$(printf "%(%Y)T" now) # year

Example to make date calculation using ksh printf

#date printf "%T\n" now #number of weekday printf "%(%u)T\n" now printf "%(%u)T\n" "2010-10-24" # Sunday printf "%(%u)T\n" "2010-10-25" # Monday #set printout format as you can do with date printf "%(Today is %F or you can write %d.%m.%Y ...)T \n" now # save date to variable in standard format timestamp=$(printf "%(%F+%H:%M:%S)T" now) echo "timestamp:$timestamp" # convert timestring as integer using variable timestamp=$(printf "%(%Y-%m-%d+%H:%M:%S)T" now) timeint=$(printf "%(%#)T" "$timestamp") echo "timestamp:$timestamp" echo "timeint:$timeint" ((daysec=24*60*60)) ((yesterday=timeint - daysec)) ((tomorrow=timeint + daysec)) # argument is # + date integer #same = give integer using #char printf "yesterday %(%Y-%m-%d)T \n" "#$yesterday" printf "tomorrow %(%Y-%m-%d)T \n" "#$tomorrow" # sec since 1970-01-01 epoc=$(printf "%(%s)T" "2010-10-24") epoc=$(printf "%(%s)T" "2010-10-24 00:00:00") epoc=$(printf "%(%s)T" "10/24/2010 00:00:00") echo "sec since 1970-01-01 00:00 UTC: $epoc" echo "= same as timeint:$timeint" # one day is 86400 (60*60*24) # now you can calculate and after that convert back to date string ((yesterday=epoc-86400)) printf "%(%Y-%m-%d)T" "#$yesterday" printf "day of week, monday=1: %(%u)T \n" '#'$timeint printf "weeknr, monday is first day of week: %(%V)T \n" '#'$timeint oldday=$(printf "%(%#)T" "2008-08-15+00:00:00") today=$(printf "%(%#)T" "2009-08-15+00:00:00") (( diff=(today-oldday)/(24*60*60) )) echo "diff:$diff"
Example: #!/bin/ksh isodate() { # dd.mm.yyyy to yyyy-mm-dd indate="$1" oifs="$IFS" IFS="." values=($indate) IFS="$oifs" iso="${values[2]}-${values[1]}-${values[0]}" echo "$iso" } fromdate=$(isodate 01.04.2010) todate=$(isodate 24.04.2010) # datestr => epoc epoc1=$(printf "%(%#)T" "$fromdate") epoc2=$(printf "%(%#)T" "$todate") # length of day (seconds) = 86400 ((day=24*60*60)) echo $(( (epoc2-epoc1) /day))

Using GNU date command

date +%Y-%m-%d --date='28 day ago' date -d 'today 06:00:00' date '+%Y-%d-%m %H:%M' -d 'yesterday 06:00:00' date '+%u' -d 2010-10-24 # daynr of week (Sunday) date '+%u' -d 2010-10-25 # daynr of week (Monday) Epoc calculation epoc=$(date -d Jan-10-2011 +%s) epoc=$(date -u +%s) today echo $epoc (( yesterday=epoc-86400 )) datestr=$(date -d "1970-01-01 $epoc seconds" ) echo $datestr datestr=$(date -d "1970-01-01 $epoc seconds" '+%Y-%m-%d %H:%M:%S' ) echo $datestr echo "yesterday:" date -d "1970-01-01 $yesterday seconds" '+%Y-%m-%d %H:%M:%S' date -d @$epoc '+%Y-%m-%d %H:%M:%S' # or example from="20100401" to="20100501" start=$(date --date="$from" +"%s") end=$(date --date="$to" +"%s") days=$(( (end - start) / 86400 )) echo $days

Date calculation - gnu date, ksh print, calculating

Using GNU date command: from="20100401" to="20100503" start=$(date --date="$from" +"%s") end=$(date --date="$to" +"%s") days=$(( (end - start) / 86400 )) echo $days from="04/01/11" to="05/03/11" start=$(date --date="$from" +"%s") end=$(date --date="$to" +"%s") days=$(( (end - start) / 86400 )) echo $days
Using ksh93 printf # length of day (seconds) = 86400 ((day=24*60*60)) fromdate="04/01/11" todate="05/04/11" # datestr => epoc epoc1=$(printf "%(%#)T" "$fromdate") epoc2=$(printf "%(%#)T" "$todate") echo $(( (epoc2-epoc1) /day)) fromdate="2011-04-01" todate="2011-05-04" # datestr => epoc epoc1=$(printf "%(%#)T" "$fromdate") epoc2=$(printf "%(%#)T" "$todate") echo $(( (epoc2-epoc1) /day))
Using calculating in any posix shell (ksh93, bash, dash, ...)
oifs="$IFS"

JulianDate()
{
 IFS="-"
 array=($1)
 IFS="$oifs"
 scale=0
 d=${array[2]}
 m=${array[1]}
 y=${array[0]}
echo $((d-32075+1461*(y+4800+(m-14)/12)/4+367*(m-2-(m-14)/12*12)/12-3*((y+4900+(y-14)/12)/100)/4 ))
}

fromdate=$( JulianDate 2011-04-01 ) # ISO yyyy-mm-dd
todate=$( JulianDate 2011-05-04 )

diff=$((todate - fromdate))
echo $diff

Convert Datestr to Julian and Julian to Datestr

Input format yyyymmdd or ISO format yyyy-mm-dd #!/usr/bin/ksh or bash # datecalc.sh # Algorithm by Henry F. Fliegel and Thomas C. Van Flandern # oifs="$IFS" ########################### Julian2Date() { # arg1 = julian date # output format yyyymmdd jd="$1" ((l = jd + 68569 )) ((n = ( 4 * l ) / 146097 )) ((l = l - ( 146097 * n + 3 ) / 4 )) ((i = ( 4000 * ( l + 1 ) ) / 1461001 )) ((l = l - ( 1461 * i ) / 4 + 31 )) ((j = ( 80 * l ) / 2447 )) ((d = l - ( 2447 * j ) / 80 )) ((l = j / 11 )) ((m = j + 2 - ( 12 * l ) )) ((y = 100 * ( n - 49 ) + i + l )) (( m<10 )) && m="0$m" (( d<10 )) && d="0$d" echo "$y$m$d" } ############################# Julian2DateISO() { # arg1 = julian date # output ISO format yyyy-mm-dd jd="$1" jdstr=$(Julian2Date "$jd") y=${jdstr:0:4} m=${jdstr:4:2} d=${jdstr:6:2} echo "$y-$m-$d" } ########################### Date2Julian() { # arg1 format yyyymmdd day=$1 d=${day:6:2} m=${day:4:2} y=${day:0:4} (( jd = ( 1461 * ( y + 4800 + ( m - 14 ) / 12 ) ) / 4 + ( 367 * ( m - 2 - 12 * ( ( m - 14 ) / 12 ) ) ) / 12 - ( 3 * ( ( y + 4900 + ( m - 14 ) / 12 ) / 100 ) ) / 4 + d - 32075 )) echo "$jd" } ########################### Date2JulianISO() { # arg1 ISO-format yyyy-mm-dd IFS="-" array=($1) IFS="$oifs" d=${array[2]} m=${array[1]} y=${array[0]} jd=$(Date2Julian "$y$m$d") echo "$jd" } ################################################ fromdate=$(Date2Julian 20110401 ) datestr=$(Julian2Date $fromdate) echo "Julian:$fromdate $datestr" fromdate=$(Date2JulianISO 2011-04-01 ) datestr=$(Julian2DateISO $fromdate) echo "Julian $fromdate $datestr"

More FAQ, solutions, examples, ...