One of the primary ways used to compare dates is to convert the date to seconds and then do the comparison. The GNU date has an option +%s to convert the given date to seconds since epoch. But sometimes GNU date is not available in all the systems and they can't install it due to restrictions in the working environment. The next option is to use strftime() of gawk or perl. The same issue may exist with gawk/perl also, i.e. they may not have the required libs or things of that sort.
The following script which I call utc_to_sec will convert the given UTC date to seconds using the basic arithmetic.
The following script which I call utc_to_sec will convert the given UTC date to seconds using the basic arithmetic.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | #!/bin/bash # utc_to_sec v1.0 # Script to convert time to seconds # TZ should be UTC # # ./utc_to_sec 2014-02-20 01:42:02 # 1392860522 EXE=${0#*/} usage() { echo -e "\nConvert date to seconds since epoch" echo " Usage : $EXE yyyy-mm-dd hh:mm:ss" echo -e " ** TZ default UTC **\n" exit } do_everything() { echo $1 $2 | awk ' BEGIN{ year=hh=1; mon=mm=2; day=ss=3 m_lo[4]=m_lo[6]=m_lo[9]=m_lo[11]=1 m_hi[1]=m_hi[3]=m_hi[5]=m_hi[7]=m_hi[8]=m_hi[10]=m_hi[12]=1 } function no_of_days_in_year(input) { leap=0 if ( input%4 == 0 ){ if ( input%100 == 0 ){ if ( input%400 == 0 ){ leap=1 } } else{ leap=1 } } return (365+leap) } function no_of_days_in_month(in_mon, in_year) { if(m_hi[in_mon]) val=31 else if(m_lo[in_mon]) val=30 else { val= no_of_days_in_year(in_year)>365?29:28 } return val } function validate(a_date, a_time) { if( a_date[year]<1970 || a_date[mon]<=0 || a_date[mon]>12 || a_date[day]<=0 || a_date[day]>31 || ( m_lo[a_date[mon]] && (a_date[day]>30) ) || ( a_date[mon]==2 && a_date[day]>29 ) || a_time[hh]<0 || a_time[hh]>23 || a_time[mm]<0 || a_time[mm]>=60 || a_time[ss]<0 || a_time[ss]>=60 ){ print -1 exit } if(no_of_days_in_year(a_date[year])<=365 && a_date[mon]==2 && a_date[day]>28){ print -2 exit } } END{ split($1, a_date, /-/) split($2, a_time, /:/) validate(a_date, a_time) #no of days in a year for(i=1970; i<a_date[year]; i++) sum_days+=no_of_days_in_year(i) for(i=1; i<a_date[mon]; i++) sum_days+=no_of_days_in_month(i, a_date[year]) sum_days=sum_days+a_date[day]-1 seconds = (sum_days*24*60*60) + (a_time[hh] * 3600) + (a_time[mm] * 60) + a_time[ss] print seconds } ' } ( [[ $# -ne 2 ]] ) && usage seconds=$( do_everything $* ) [[ ${seconds:-0} -lt 0 ]] && echo "Invalid data..." && usage echo $seconds |
Output
root@maximus:~/scripts# ./utc_to_sec 2037-12-31 23:59:59 2145916799 root@maximus:~/scripts# date +%s -d "2037-12-31 23:59:59 UTC" 2145916799 root@maximus:~/scripts# ./utc_to_sec 2014-02-19 12:13:56 1392812036 root@maximus:~/scripts# date +%s -d " 2014-02-19 12:13:56 UTC" 1392812036 root@maximus:~/scripts# ./utc_to_sec 1970-01-01 00:00:00 0 root@maximus:~/scripts# date +%s -d "1970-01-01 00:00:00 UTC" 0 root@maximus:~/scripts# date +%s -d "1990-01-01 23:40:44 UTC" 631237244 root@maximus:~/scripts# ./utc_to_sec 1990-01-01 23:40:44 631237244
Execution time
root@maximus:~/scripts# time date +%s -d "2037-12-31 23:59:59 UTC" 2145916799 real 0m0.010s user 0m0.004s sys 0m0.008s root@maximus:~/scripts# time ./utc_to_sec 2037-12-31 23:59:59 2145916799 real 0m0.023s user 0m0.012s sys 0m0.004s
HTH