实现求某天的前一天操作(C++,shell)
2012-02-09 11:31
316 查看
实现求某天的前一天操作
其实每次跟闰年打交道时,都会想起小学数学全区统考时的考题,
问:2100年是否是闰年?当时我们班几乎是全军覆没,老师特别生气地跟我们说,
书上小字部分都有说明,能被4和100整除,但不能被400整除的也不是闰年。我没讲到,你们就不知道看书吗?
当时的情景仍然历历在目,我觉得这辈子,什么是闰年估计我应该不会再出错了。呵呵~
言归正传,看看这题目应该如何来实现呢。可能最传统最常用的方式就是判断是否是闰年?以及大小月来计算吧。呵呵~
最常用的方式就是直接用程序来实现,也比较简单易理解。
程序如下:
void GetYesterday(char* today, string &yesterday)
{
int day = atoi(today + 6);
char buff[9];
strcpy(buff, today+4);
buff[2] = '\0';
int month = atoi(buff);
strcpy(buff, today);
buff[4]='\0';
int year = atoi(buff);
//当为1号时,
if(day == 1)
{
if(month == 1)
{
year -= 1;
month = 12;
day = 31;
}
else
{
month -= 1;
switch(month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 2:
if(isLeap(year))
{
day = 29;
}
else
{
day = 28;
}
break;
default:
day = 30;
break;
}
}
}
else
{
day -= 1;
}
char chbuff[9];
sprintf(chbuff, "%4d%.2d%.2d", year, month, day);
yesterday = chbuff;
}
第二种方式是在 通过shell来实现,思路也比较容易理解。(朋友提供的方案)
看一下代码,应该能看明白,先是取出年,月,日,对日做减一操作。
再判断是否为0,为0时,需要对月做减一操作,当月为0时,直接对年做减一操作,
取12月31号日期即可。若月不为0,则需要判定是否是闰年,以及大小月的关系。
#!/bin/sh
# ydate: A Bourne shell script that
# prints yestarday's date
# Output Form: Month Day Year
# From Focus on Unix: http://unix.about.com
# Set the current month day and year.
month=`date +%m`
day=`date +%d`
year=`date +%Y`
# Add 0 to month. This is a
# trick to make month an unpadded integer.
month=`expr $month + 0`
# Subtract one from the current day.
day=`expr $day - 1`
# If the day is 0 then determine the last
# day of the previous month.
if [ $day -eq 0 ]; then
# Find the preivous month.
month=`expr $month - 1`
# If the month is 0 then it is Dec 31 of
# the previous year.
if [ $month -eq 0 ]; then
month=12
day=31
year=`expr $year - 1`
# If the month is not zero we need to find
# the last day of the month.
else
case $month in
1|3|5|7|8|10|12) day=31;
4|6|9|11) day=30;
2)
if [ `expr $year % 4` -eq 0 ]; then
if [ `expr $year % 400` -eq 0 ]; then
day=29
elif [ `expr $year % 100` -eq 0 ]; then
day=28
else
day=29
fi
else
day=28
fi
;;
esac
fi
fi
# Print the month day and year.
echo $month $day $year
exit 0
第三种实现方式:
上面两种实现方式可以说是比较普遍,易于理解的。下面再一看一种,说实话,代码我第一次看时,需要没理解。后来和同事一点点分析,才明白。当时真的是感叹编写这段代码的人的思路够奇,够新。
不信,看看?呵呵~
function getYesterday
{
today=$1
if [[ -z $today ]]; then
today=`date +%Y%m%d`
fi
y_year=`echo $today | cut -c1-4`
m_month=`echo $today | cut -c5-6`
m_day=`echo $today | cut -c7-8`
date_cal=`cal $m_month $y_year`
if [ $m_day -le 1 ]; then
m_month2=`expr $m_month-1|bc`
if [ $m_month2 -le 0 ];then
m_month=12
y_year=`expr $y_year-1|bc`
date_cal=`cal $m_month $y_year`
else
date_cal=`cal $m_month2 $y_year`
m_month=$m_month2
fi
m_day=`echo $date_cal|awk '{print $NF}'`
else
m_day=`expr $m_day-1|bc`
fi
len=`expr length $m_month`
if [ $len -le 1 ];then
m_month=0$m_month
fi
if [ "$m_day" -le "9" ];then
m_day=0$m_day
fi
echo $y_year$m_month$m_day
}
看明白了吗?
咱们来分析一下代码,开始很好理解,同样地是拆分出年,月,日来。对日做判定,当日为1时,月做减1操作,判断此时当月份为0时,对年做减1操作,取12月31号即可。当此时月不为1时,
date_cal=`cal $m_month2 $y_year`取得上个月的日期表,再通过m_day=`echo $date_cal|awk '{print $NF}'`,其中echo $date_cal实现了将日期横向打印的操作,而awk '{print $NF}'实现了取每行最后一列的操作,故取出上个月的最后一天,而无需去判定是否是闰年?是大小月的问题。
很妙吧。呵呵~
这里需要注意一个问题,当单纯地执行cal $m_month2 $y_year时,是按正常周一至周日纵向来打印日期,而 用echo实现了横向打印操作。
{print $NF}实现了取每行的最后一列操作,注意和取最后一列的区别。
听同事说,可以用 boost来实现,有空我再试试看。呵呵~
PS:
就写到这儿吧,写这篇文章主要是推荐第三种方案的实现思路,特新奇,在做别的开发时,也许会用到,所以供大家参考。第二种代码是同事提供的,好像是网上找来的,如果侵犯到谁的著作权,请及时通知我,我删除即可。不过,因为没有用于赢利行为,应该会允许的吧,知识共享嘛。呵呵~
总之,谢谢第二种方案的提供者。
其实每次跟闰年打交道时,都会想起小学数学全区统考时的考题,
问:2100年是否是闰年?当时我们班几乎是全军覆没,老师特别生气地跟我们说,
书上小字部分都有说明,能被4和100整除,但不能被400整除的也不是闰年。我没讲到,你们就不知道看书吗?
当时的情景仍然历历在目,我觉得这辈子,什么是闰年估计我应该不会再出错了。呵呵~
言归正传,看看这题目应该如何来实现呢。可能最传统最常用的方式就是判断是否是闰年?以及大小月来计算吧。呵呵~
最常用的方式就是直接用程序来实现,也比较简单易理解。
程序如下:
void GetYesterday(char* today, string &yesterday)
{
int day = atoi(today + 6);
char buff[9];
strcpy(buff, today+4);
buff[2] = '\0';
int month = atoi(buff);
strcpy(buff, today);
buff[4]='\0';
int year = atoi(buff);
//当为1号时,
if(day == 1)
{
if(month == 1)
{
year -= 1;
month = 12;
day = 31;
}
else
{
month -= 1;
switch(month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 2:
if(isLeap(year))
{
day = 29;
}
else
{
day = 28;
}
break;
default:
day = 30;
break;
}
}
}
else
{
day -= 1;
}
char chbuff[9];
sprintf(chbuff, "%4d%.2d%.2d", year, month, day);
yesterday = chbuff;
}
第二种方式是在 通过shell来实现,思路也比较容易理解。(朋友提供的方案)
看一下代码,应该能看明白,先是取出年,月,日,对日做减一操作。
再判断是否为0,为0时,需要对月做减一操作,当月为0时,直接对年做减一操作,
取12月31号日期即可。若月不为0,则需要判定是否是闰年,以及大小月的关系。
#!/bin/sh
# ydate: A Bourne shell script that
# prints yestarday's date
# Output Form: Month Day Year
# From Focus on Unix: http://unix.about.com
# Set the current month day and year.
month=`date +%m`
day=`date +%d`
year=`date +%Y`
# Add 0 to month. This is a
# trick to make month an unpadded integer.
month=`expr $month + 0`
# Subtract one from the current day.
day=`expr $day - 1`
# If the day is 0 then determine the last
# day of the previous month.
if [ $day -eq 0 ]; then
# Find the preivous month.
month=`expr $month - 1`
# If the month is 0 then it is Dec 31 of
# the previous year.
if [ $month -eq 0 ]; then
month=12
day=31
year=`expr $year - 1`
# If the month is not zero we need to find
# the last day of the month.
else
case $month in
1|3|5|7|8|10|12) day=31;
4|6|9|11) day=30;
2)
if [ `expr $year % 4` -eq 0 ]; then
if [ `expr $year % 400` -eq 0 ]; then
day=29
elif [ `expr $year % 100` -eq 0 ]; then
day=28
else
day=29
fi
else
day=28
fi
;;
esac
fi
fi
# Print the month day and year.
echo $month $day $year
exit 0
第三种实现方式:
上面两种实现方式可以说是比较普遍,易于理解的。下面再一看一种,说实话,代码我第一次看时,需要没理解。后来和同事一点点分析,才明白。当时真的是感叹编写这段代码的人的思路够奇,够新。
不信,看看?呵呵~
function getYesterday
{
today=$1
if [[ -z $today ]]; then
today=`date +%Y%m%d`
fi
y_year=`echo $today | cut -c1-4`
m_month=`echo $today | cut -c5-6`
m_day=`echo $today | cut -c7-8`
date_cal=`cal $m_month $y_year`
if [ $m_day -le 1 ]; then
m_month2=`expr $m_month-1|bc`
if [ $m_month2 -le 0 ];then
m_month=12
y_year=`expr $y_year-1|bc`
date_cal=`cal $m_month $y_year`
else
date_cal=`cal $m_month2 $y_year`
m_month=$m_month2
fi
m_day=`echo $date_cal|awk '{print $NF}'`
else
m_day=`expr $m_day-1|bc`
fi
len=`expr length $m_month`
if [ $len -le 1 ];then
m_month=0$m_month
fi
if [ "$m_day" -le "9" ];then
m_day=0$m_day
fi
echo $y_year$m_month$m_day
}
看明白了吗?
咱们来分析一下代码,开始很好理解,同样地是拆分出年,月,日来。对日做判定,当日为1时,月做减1操作,判断此时当月份为0时,对年做减1操作,取12月31号即可。当此时月不为1时,
date_cal=`cal $m_month2 $y_year`取得上个月的日期表,再通过m_day=`echo $date_cal|awk '{print $NF}'`,其中echo $date_cal实现了将日期横向打印的操作,而awk '{print $NF}'实现了取每行最后一列的操作,故取出上个月的最后一天,而无需去判定是否是闰年?是大小月的问题。
很妙吧。呵呵~
这里需要注意一个问题,当单纯地执行cal $m_month2 $y_year时,是按正常周一至周日纵向来打印日期,而 用echo实现了横向打印操作。
{print $NF}实现了取每行的最后一列操作,注意和取最后一列的区别。
听同事说,可以用 boost来实现,有空我再试试看。呵呵~
PS:
就写到这儿吧,写这篇文章主要是推荐第三种方案的实现思路,特新奇,在做别的开发时,也许会用到,所以供大家参考。第二种代码是同事提供的,好像是网上找来的,如果侵犯到谁的著作权,请及时通知我,我删除即可。不过,因为没有用于赢利行为,应该会允许的吧,知识共享嘛。呵呵~
总之,谢谢第二种方案的提供者。
相关文章推荐
- shell实现交换机批量操作
- 4 weekend110的hdfs&mapreduce测试 + hdfs的实现机制初始 + hdfs的shell操作 + 无密登陆配置
- shell字符串操作(长度,查找,替换,匹配)详解(shell内置一系列操作符号实现)
- 用未公开函数实现Shell操作监视
- 在shell中利用 bc 实现小数或者整数的比较操作
- MongoDB_03之使用shell命令实现对文档数据的操作
- Robotium学习(七)- 实现用shell命令执行一些操作的方法
- shell字符串操作之cut---实现字符串截取
- Python之Fabric模块 Fabric是基于Python实现的SSH命令行工具,简化了SSH的应用程序部署及系统管理任务,它提供了系统基础的操作组件,可以实现本地或远程shell命令,包括:
- 利用未公开函数实现Shell操作监视
- shell实现:对两个文件A[用户id,操作次数]及文件B[用户id,性别],合并得到C[用户id,操作次数,性别],并统计出男女用户操作所占的比例
- shell字符串操作之cut---实现字符串截取
- shell 实现mysql写入操作
- LINUX定时执行SHELL脚本实现DB2数据库操作,crontab无法正常识别执行
- shell 实现并发操作
- Shell脚本中实现切换用户并执行命令操作
- shell脚本实现菜单操作
- until 循环:实现一个shell脚本,不停地询问用户要执行什么操作,直到用户输入quit才会退出