获得N天前的日期(0<=N<=28)
时间:2007-05-10 来源:xiaophedap
今天一个朋友需要这样一个程序:每天定时创建一个目录,该目录的名称是10天前的日期。
这段需求可以拆分如下:
1. 每天定义创建一个目录
解决方案:这个需求可以用crontab功能来实现
2. 该目录的名称是10天前的日期
解决方案:这个需求可以看成是获得今天日期10天前的日期。
获得10天前的日期这里面包含三个需要考虑的情况:
1. 今天的日期是10号以上,则10天起的日期,只要直接相减就行,但如果是10号或者10号以下,则10天前就到上个月了
2. 考虑到有些情况到上个月了,那么就要考虑有些情况会到上一年
3. 考虑到年,就要考虑闰年或者非闰年了
综合以上考虑,就能够获得以下程序:
#!/bin/sh
#
#--------------------------------------------------------------------------------
#FileName : 10daysago.sh
#FileType : sh
#DESCRIPTION : Get the date of N days ago
#Date : 2007-05-10 15:19
#Copyright : 0.1
#--------------------------------------------------------------------------------
# # 变量定义 ---------------------------------------------------------------------- # 定义N天(N <= 28)前的日期,这里根据用户需求,定为10天
N=10 # 定义今天的日期
CURRENT_DATE=`date +%Y%m%d` # 定义获得年的标示
CURRENT_YEAR=`date +%Y` # 定义去年的标示
LAST_YEAR=`expr $CURRENT_YEAR - 1` # 定义获得月的标示
CURRENT_MONTH=`date +%m` # 定义上个月的标示
if [ $CURRENT_MONTH -gt 1 ]
# 如果本月不是1月份
then
LAST_MONTH=`expr $CURRENT_MONTH - 1`
# 如果本月是1月份
else
LAST_MONTH=12
fi # 定义获得天的标示
CURRENT_DAY=`date +%d` # 判断是否闰年:0表示非闰年,1表示闰年
# LEAP_YEAR_CHECK=$(($CURRENT_YEAR%4==0&&$CURRENT_YEAR%100!=0||$CURRENT_YEAR%400==0))
if [ `expr $CURRENT_YEAR % 4` -eq 0 ]
then
if [ `expr $CURRENT_YEAR % 400` -eq 0 ]
then
LEAP_YEAR_CHECK=1
elif [ `expr $CURRENT_YEAR % 100` -ne 0 ]
then
LEAP_YEAR_CHECK=1
else
LEAP_YEAR_CHECK=0
fi
else
LEAP_YEAR_CHECK=0
fi # 定义上个月的天数
# 说明:如果是闰年,则2月份是29天,否则为28天
LAST_MONTH_DAYS=0
if [ $CURRENT_MONTH -gt 1 ]
# 如果大于1月份
then
case $LAST_MONTH in
1|3|5|7|8|10|12)
LAST_MONTH_DAYS=31
;;
4|6|9|11)
LAST_MONTH_DAYS=30
;;
2)
if [ $LEAP_YEAR_CHECK -eq 0 ]
then
LAST_MONTH_DAYS=28
else
LAST_MONTH_DAYS=29
fi
;;
*)
echo "Error: The month must be in the range from 1 to 12."
;;
esac
# 如果是1月份,则上个月为第12月,天数一定为31
else
LAST_MONTH_DAYS=31
fi # 定义最终的年
BEFORE_YEAR=0 # 定义最终的月
BEFORE_MONTH=0 # 定义最终的天
BEFORE_DAY=0 # 定义距离今天N天前的日期
BN_DAYS_AGO=0 # 变量定义完成 ------------------------------------------------------------------ # 程序开始
# -------------------------------------------------------------------------------
# ------------------------------------------------------------------------------- # 如果今天天数大于N
if [ $CURRENT_DAY -gt $N ]
then
# 年份BEFORE_YEAR = 今年CURRENT_YEAR
# 月份BEFORE_MONTH = 本月CURRENT_MONTH
# 天数BEFORE_DAY = 今天天数CURRENT_DAY - N
BEFORE_YEAR=$CURRENT_YEAR
BEFORE_MONTH=$CURRENT_MONTH
BEFORE_DAY=`expr $CURRENT_DAY - $N`
# 如果今天天数小于等于N
else
# 如果当前月份不是1月份
if [ $CURRENT_MONTH -ne 1 ]
then
# 年份BEFORE_YEAR = 今年CURRENT_YEAR
# 月份BEFORE_MONTH = 前一个月LAST_MONTH
# 天数BEFORE_DAY = 前一个月的天数LAST_MONTH_DAYS - (N - 今天天数CURRENT_DAY)
BEFORE_YEAR=$CURRENT_YEAR
BEFORE_MONTH=$LAST_MONTH
BEFORE_DAY=`expr $LAST_MONTH_DAYS - $N + $CURRENT_DAY`
# 如果当前月份是1月份
else
# 年份BEFORE_YEAR = 前一年LAST_YEAR
# 月份BEFORE_MONTH = 前一个月LAST_MONTH
# 天数BEFORE_DAY = 前一个月的天数LAST_MONTH_DAYS - (N - 今天天数CURRENT_DAY)
BEFORE_YEAR=$LAST_YEAR
BEFORE_MONTH=$LAST_MONTH
BEFORE_DAY=`expr $LAST_MONTH_DAYS - $N + $CURRENT_DAY`
fi
fi
BN_DAYS_AGO=$BEFORE_YEAR$BEFORE_MONTH$BEFORE_DAY
echo $BN_DAYS_AGO # -------------------------------------------------------------------------------
# 正常退出
exit 0 # 程序结束
# -------------------------------------------------------------------------------
# ------------------------------------------------------------------------------- 一位朋友提出一个很好的建议,可以在手动运行该程序的时候使用:把这个N=10,改成N=$1,这样就能使用第一个参数来定义获得N天前的日期。 另外,还可以进一步优化这个版本,这个程序获得的日期如果是5月8号,那么获得的最终结果就是200758(以2007年5月18日来为例子),而如果以2007年11月21日,则得到的结果是20071111,这样,如果将200758改写为20070508,则更加容易让人明白,而且对于今后的统计分类工作,将省事很多。这个优化,将在下一个笔记中给出这个函数。 当然,如果你的操作系统不是HP-UX,而是Linux,或者使用的date命令是GNU的,那么恭喜你,不用这么麻烦的程序了,只需要: #a=`date +%Y-%m-%d` #date -d "$a -10 days" 是不是方便很多呢?
#--------------------------------------------------------------------------------
#FileName : 10daysago.sh
#FileType : sh
#DESCRIPTION : Get the date of N days ago
#Date : 2007-05-10 15:19
#Copyright : 0.1
#--------------------------------------------------------------------------------
# # 变量定义 ---------------------------------------------------------------------- # 定义N天(N <= 28)前的日期,这里根据用户需求,定为10天
N=10 # 定义今天的日期
CURRENT_DATE=`date +%Y%m%d` # 定义获得年的标示
CURRENT_YEAR=`date +%Y` # 定义去年的标示
LAST_YEAR=`expr $CURRENT_YEAR - 1` # 定义获得月的标示
CURRENT_MONTH=`date +%m` # 定义上个月的标示
if [ $CURRENT_MONTH -gt 1 ]
# 如果本月不是1月份
then
LAST_MONTH=`expr $CURRENT_MONTH - 1`
# 如果本月是1月份
else
LAST_MONTH=12
fi # 定义获得天的标示
CURRENT_DAY=`date +%d` # 判断是否闰年:0表示非闰年,1表示闰年
# LEAP_YEAR_CHECK=$(($CURRENT_YEAR%4==0&&$CURRENT_YEAR%100!=0||$CURRENT_YEAR%400==0))
if [ `expr $CURRENT_YEAR % 4` -eq 0 ]
then
if [ `expr $CURRENT_YEAR % 400` -eq 0 ]
then
LEAP_YEAR_CHECK=1
elif [ `expr $CURRENT_YEAR % 100` -ne 0 ]
then
LEAP_YEAR_CHECK=1
else
LEAP_YEAR_CHECK=0
fi
else
LEAP_YEAR_CHECK=0
fi # 定义上个月的天数
# 说明:如果是闰年,则2月份是29天,否则为28天
LAST_MONTH_DAYS=0
if [ $CURRENT_MONTH -gt 1 ]
# 如果大于1月份
then
case $LAST_MONTH in
1|3|5|7|8|10|12)
LAST_MONTH_DAYS=31
;;
4|6|9|11)
LAST_MONTH_DAYS=30
;;
2)
if [ $LEAP_YEAR_CHECK -eq 0 ]
then
LAST_MONTH_DAYS=28
else
LAST_MONTH_DAYS=29
fi
;;
*)
echo "Error: The month must be in the range from 1 to 12."
;;
esac
# 如果是1月份,则上个月为第12月,天数一定为31
else
LAST_MONTH_DAYS=31
fi # 定义最终的年
BEFORE_YEAR=0 # 定义最终的月
BEFORE_MONTH=0 # 定义最终的天
BEFORE_DAY=0 # 定义距离今天N天前的日期
BN_DAYS_AGO=0 # 变量定义完成 ------------------------------------------------------------------ # 程序开始
# -------------------------------------------------------------------------------
# ------------------------------------------------------------------------------- # 如果今天天数大于N
if [ $CURRENT_DAY -gt $N ]
then
# 年份BEFORE_YEAR = 今年CURRENT_YEAR
# 月份BEFORE_MONTH = 本月CURRENT_MONTH
# 天数BEFORE_DAY = 今天天数CURRENT_DAY - N
BEFORE_YEAR=$CURRENT_YEAR
BEFORE_MONTH=$CURRENT_MONTH
BEFORE_DAY=`expr $CURRENT_DAY - $N`
# 如果今天天数小于等于N
else
# 如果当前月份不是1月份
if [ $CURRENT_MONTH -ne 1 ]
then
# 年份BEFORE_YEAR = 今年CURRENT_YEAR
# 月份BEFORE_MONTH = 前一个月LAST_MONTH
# 天数BEFORE_DAY = 前一个月的天数LAST_MONTH_DAYS - (N - 今天天数CURRENT_DAY)
BEFORE_YEAR=$CURRENT_YEAR
BEFORE_MONTH=$LAST_MONTH
BEFORE_DAY=`expr $LAST_MONTH_DAYS - $N + $CURRENT_DAY`
# 如果当前月份是1月份
else
# 年份BEFORE_YEAR = 前一年LAST_YEAR
# 月份BEFORE_MONTH = 前一个月LAST_MONTH
# 天数BEFORE_DAY = 前一个月的天数LAST_MONTH_DAYS - (N - 今天天数CURRENT_DAY)
BEFORE_YEAR=$LAST_YEAR
BEFORE_MONTH=$LAST_MONTH
BEFORE_DAY=`expr $LAST_MONTH_DAYS - $N + $CURRENT_DAY`
fi
fi
BN_DAYS_AGO=$BEFORE_YEAR$BEFORE_MONTH$BEFORE_DAY
echo $BN_DAYS_AGO # -------------------------------------------------------------------------------
# 正常退出
exit 0 # 程序结束
# -------------------------------------------------------------------------------
# ------------------------------------------------------------------------------- 一位朋友提出一个很好的建议,可以在手动运行该程序的时候使用:把这个N=10,改成N=$1,这样就能使用第一个参数来定义获得N天前的日期。 另外,还可以进一步优化这个版本,这个程序获得的日期如果是5月8号,那么获得的最终结果就是200758(以2007年5月18日来为例子),而如果以2007年11月21日,则得到的结果是20071111,这样,如果将200758改写为20070508,则更加容易让人明白,而且对于今后的统计分类工作,将省事很多。这个优化,将在下一个笔记中给出这个函数。 当然,如果你的操作系统不是HP-UX,而是Linux,或者使用的date命令是GNU的,那么恭喜你,不用这么麻烦的程序了,只需要: #a=`date +%Y-%m-%d` #date -d "$a -10 days" 是不是方便很多呢?
相关阅读 更多 +