没有 GNU 工具的日期计算

Mat*_*teo 7 date

我必须在 shell 脚本中执行一些日期计算和转换。例如计算格式化为Nov 28 20:27:19 2012 GMT今天的日期之间的天数差异。

有几种可能性(GNU dategawkperl等),但我希望能够在没有 GNU 工具的系统上运行它(例如,BSD、Solaris 等)

目前我拥有的最便携的解决方案是 Perl,但它可能需要安装额外的模块来进行日期转换。

我应该选择什么?

编辑:查看评论我意识到我需要澄清我正在编写的工具将公开分发。我不是在寻找在我的机器上执行计算或如何安装 GNU 工具的方法。

我想使用可能在大多数机器上找到的工具。

mgj*_*gjk 3

过去我必须在 shell 脚本中通过暴力解析和计算来完成此操作。

在 shell 脚本中手动执行此操作非常容易出错且速度缓慢。您需要考虑每月的天数、闰年、时区。对于不同的区域设置和不同的语言,它会失败。

我修复了我的一个旧脚本,这可能需要针对不同的 shell 环境进行修改,但不应该有任何东西不能更改以在任何 shell 中工作。

#!/bin/sh 

datestring="Nov 28 20:27:19 2012 GMT"
today=`date`

function date2epoch {

month=$1
day=$2
time=$3
year=$4
zone=$5

# assume 365 day years
epochtime=$(( (year-1970) * 365 * 24 * 60 * 60 ))

# adjust for leap days
i=1970
while [[ $i -lt $4 ]]
do
    if [[ 0 -eq $(( i % 400 )) ]]
    then
        #echo $i is a leap year
        # divisible by 400 is a leap year
        epochtime=$((epochtime+24*60*60))
    elif [[ 0 -eq $(( i % 100 )) ]]
    then
        #echo $i is not a leap year
        epochtime=$epochtime
    elif [[ 0 -eq $(( i % 4 )) ]]
    then
        #echo $i is a leap year
        # divisible by 4 is a leap year
        epochtime=$((epochtime+24*60*60))
    #   epoch=`expr $epoch + 24 * 60 * 60`
    fi

    i=$((i+1))
done    

dayofyear=0
for imonth in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
do
    if [[ $month == $imonth ]]
    then
        break
    fi

    case $imonth in
    'Feb')
        if [[ 0 -eq $(( year % 400 )) ]]
        then
            days=29
        elif [[ 0 -eq $(( year % 100 )) ]]
        then
            days=28
        elif [[ 0 -eq $(( year % 4 )) ]]
        then
            days=29
        fi
    ;;

    Jan|Mar|May|Jul|Aug|Oct|Dec) days=31 ;;
    *) days=30 ;;
    esac

    #echo $imonth has $days days
    dayofyear=$((dayofyear + days))
done
## add the day of the month 
dayofyear=$((dayofyear+day))
#echo $dayofyear

########## Add the day fo year (-1) to the epochtime
#(-1, since eg. Jan 1 is not 24 hours into Jan1 )

epochtime=$((epochtime + (dayofyear -1) * 24*60*60))
#echo $epochtime
################## hours, minutes, seconds
OFS=$IFS
IFS=":"
set -- $time
hours=$1
minutes=$2
seconds=$3
epochtime=$((epochtime + (hours * 60 * 60) + (minutes * 60) + seconds))
IFS=$OFS

################## Time zone

case $zone in
'GMT') zonenumber=0
break;;
'EST') zonenumber=-5
break;;
'EDT') zonenumber=-4
break;;
esac

epochtime=$((epochtime + zonenumber * 60 * 60 ))

echo $epochtime
}

result=`date2epoch $datestring`

echo $result
Run Code Online (Sandbox Code Playgroud)

我可能在某个地方犯了错误,也许有更好的方法。如果您发现错误或更好的方法,请告诉我。

一旦你有了纪元时间,你就可以做一些有用的计算...尽管在没有 gnu utils 的情况下将其转换回日期...需要反向执行上述操作...