Crane


Search
Loading

分类

随机文章

标签云
ArchLinux
Earth
Fringe
Gtalk
Internet
LFS
Love
RegEx
STL
Trick
VHDL
abs
c
c++
code
css
echofon
firefox
fun
g++
game
gcc
geek
google
grep
hack
linux
math
md5
nginx
php
program
python
reader
script
sed
shell
tcpdump
usaco
vim
vimperator
virus
wikipedia
windows
二进制
位运算
危机边缘
哥德尔
大牛
希尔伯特
数据结构
日期
时间
星期五
正则表达式
漫画
生活
电影
程序员
算法
维基
编程
网络
美剧
菜鸟
越狱
输入法
黑色

最新评论

链接

功能

计算两个日期的差值
记得今年早些时候看到百度员工出的那个视频,中间有一幕女主角在计算自己自出生以来已经生活了多少天,只见她熟练的打开excel,在A1中输入生日,在B1中输入当天日期,在C1中输入=B1-A1,立刻得到自己来到这个世上的时间,眼看过去了这么多天,自己当初的梦想实现了多少呢,……,剧情自此展开,不再追踪。
我看到这个的时候,想着cli控们有没有什么方法能实现同样的功能呢,无所不能的shell(我记得有人说过shell是完备的)啊,需要你的力量。
想了一下,使用了coreutils中的date命令,写成了如下shell脚本:
#/bin/sh # # this scrit is used to calculate the distance between two date. # e.g. My birthday is 1988-12-29,today is 2011-04-01,I want to how # many days I have been alive in this world. # so use # daydis.sh 19881229 20110401 function error_msg(){ echo -n This is a shell script to count days between date. echo ' usage: $0 date1 date2' echo -e '\tfor example, to calculate how many days between two date,' echo -e '\te.g. from 19881229 to 20110401' echo -e '\ttry: $0 19881229 20110401' exit } from=$1 to=$2 if [ ${#from} -ne 8 ] || [ ${#to} -ne 8 ];then error_msg fi if [ $(($1-$2)) -gt 0 ] ;then error_msg fi if [ ${from:0:4} -lt 1902 ] || [ ${to:0:4} -gt 2037 ];then echo "the year of date should range from 1902 to 2037." exit fi from=`eval date -d "$1" +%s` #echo $from to=`eval date -d "$2" +%s` #echo $to secdis=`echo $(($to-$from))` #echo $secdis daydis=`echo $(($secdis/3600/24))` echo "from $1 to $2,there are $daydis day(s)."
原理是用到了日历时间,在UNIX系统中的时间定义是这样的,系统用一个time_t类型的变量来表示系统时间,它的值是从1970年1月1日00:00:00以来所经过的秒数的累计,程序中就是通过计算两个日期的这个秒数累计的差,然后把这个秒数差值转换成天数,即得到了我们要的答案。
得到一个日期的秒数累计(日历时间)可以用date命令来搞定,比如2011年4月1日,可以这样
$ date -d "20110401" +%s
1301587200
得到的那个1301587200就是一个秒数的累计,再做一些简单的算术运算就可以得到所要的结果。
PS:上面可以看到这个秒数已经累计到13亿了,而如果用一个32位整数来存放这个的话,有符号的最大也就是21亿多,貌似已经很靠近了,如果到了那一天会有什么问题呢?这就是著名的Year 2038 problem,不过不用担心,到那个时间还早着呢,这期间硬件变化,把32位的换成64位,或者干脆用一个浮点数来存这个,都不会出现这个问题。