Howto handle date and date calculation | ||||
Date and date calculation
Using date commandBasic 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.
Using ksh builtin printf %TThis 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 ?
%T format you can expand using between () rule which works same way as date arguments.
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, calculatingUsing 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, ...)
Convert Datestr to Julian and Julian to DatestrInput 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, ...
| ||||