当前位置:IT教程网教程中心程序开发Shell → 教程内容

如何用date获得前一天的日期,忘了

减小字体 增大字体 作者:佚名  来源:不详  发布时间:2006-12-27 13:50:00

好象有date 有-24 有+%y%m%d等,谢了。
还有有办法获得3天前的日期吗?

广告位置


 michaelds 回复于:2002-04-02 10:18:40
唉,在b shell没有这个用法了,要想用纯shell做几天前后的运算,只有自己想办法了,+%y%m%d用于控制输出格式,作用有限,要想做的话,参见这个帖子大家的发言:
http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=11&topic=91&show=30

 nkliyong 回复于:2002-04-02 10:28:21
我的确在哪儿看到用一条命令就可以取昨天或明天的日期,
参数中有-24或+24。没那么复杂

 nkliyong 回复于:2002-04-02 10:52:41
好象用到了参数TZ=-24;export TZ什么的

 valentine 回复于:2002-04-02 11:03:55
改变时区,应该可以实现,确实是个好方法。


 nkliyong 回复于:2002-04-02 12:28:40
可现在我却实现不了?

 valentine 回复于:2002-04-02 16:09:02
不会吧,你说的俺都明白了,你自己还不懂?

date命令的显示是与环境变量TZ有关的
看以下的命令操作,你应该便明白了,

$#看当前时区
$echo $TZ
CST-8
$#显示当前时间
$date
Mon Apr  2 15:48:36 CST 2002
$#改变当前时区,
TZ=CST+16;export TZ
$#显示当前时间(中间未改变系统时间,但date命令的显示已为昨天)
Mon Apr  1 15:48:33 CST 2002


 nkliyong 回复于:2002-04-03 08:57:23
是啊,我已经明白了,忘了告诉斑竹一声

 wolfer 回复于:2002-04-03 09:52:40
太谢谢楼主了,我正想问这个问题呢,谢谢!

 solarwind 回复于:2002-06-20 14:24:32
#!/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

 bluespace 回复于:2002-06-21 11:27:03
时区转换实在是太精妙了!:-)

 山地獾 回复于:2002-06-24 15:42:46
在sco unix版下有本人的贴子可完美的解决楼主的问题

 nortell 回复于:2002-07-17 12:05:05
如果在shell中改了时区,执行完后,系统真正的时区还是正确的吗?

 laowu99 回复于:2002-07-17 12:33:44
回楼上:最好你要把TZ的设置该回去了。
不过我在实践中用的方法是:
如果你的主机能够连接到数据库的话,比如可以连接到SYBASE数据库,那就可以利用数据库里面计算时间的丰富的函数了,比如
dateadd(day,getdate(),-1)
就能得到最天的日期了


 山地獾 回复于:2002-10-11 11:30:14
因为这个贴子被版主盖过章,所以在此跟一下。
最近经常看到有网友关于相对日期问题的贴子,这在shell下进行解决时比较头疼。现将我作的几个程序贴出来与大家分享。虽然是用c写的,把它们贴在这里,我想大家也不会太反对的。其中一个程序以前发表在sco版下,现在早已淹没在汪洋大海中了,无从查找。
因为是早先刚学c时的作品,且英文又不行,故写出的程序比较难看,请大家别见笑。
相关链接:
http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=11&topic=457&show=0
http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=11&topic=91&show=30


 山地獾 回复于:2002-10-11 11:31:02
int  date8_add(char *date8,char ymd,int value,char *date8added);
int  checkdate8(char *date8);
long int days_from_8zeros(char *date8);
int  get_data8_from_days(long int days,char *date8);


//功能:计算某年月日前后一定年数(或月数、天数)的年月日
//输入:
//     1. date8 计算基准日期
//     2. ymd   表示下一变量的单位  'y'-年  'm'-月  'd'-日
//     3. value 偏移量:年数、月数、天数
//输出:
//     1. date8added 计算后结果
//返回:
//      0 成功
//     -1 date8非法
//     -2 ymd非法
//     -3 value非法
//     -4 转换后date8added的年份小于公元1年
//     -5 转换后date8added的年份大于公元9999年
//     -6 转换后date8added非法,例如得到结果为2002/02/30
int  date8_add(char *date8,char ymd,int value,char *date8added)
{
    char strtmp[10];
    long int days;
    int c,vyear,vmonth,vday;
    int errbz;

    // 检查参数date8的合法性
    errbz=checkdate8(date8);
    if (errbz!=0) return(-1);

    // 检查参数ymd的合法性
    if ( ymd!='y' && ymd!='m' && ymd!='d') return(-2);

    // 检查参数value的合法性(简单检查)
    //if ( value < -9999 || value > 9999 ) return(-3);

    // 当增加量为年数时,计算结果并返回
    if (ymd=='y')
    {
       memset(strtmp,0,sizeof(strtmp));
       memcpy(strtmp,date8+0,4);
       sscanf(strtmp,"%d",&vyear);
       vyear+=value;
       if ( vyear<1 )    return(-4); //小于公元1年
       if ( vyear>9999 ) return(-5); //大于公元9999年

       strcpy(date8added,date8);
       sprintf(strtmp,"%04d",vyear);
       memcpy(date8added,strtmp,4);
       errbz=checkdate8(date8added);
       if (errbz!=0)     return(-6); //计算所得结果非法
       return(0);
    }

    // 当增加量为月数时,计算结果并返回
    if (ymd=='m')
    {
       vyear=0;
       vmonth=0;
       vday=0;
       
       memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+0,4); sscanf(strtmp,"%d",&vyear);
       memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+4,2); sscanf(strtmp,"%d",&vmonth);
       memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+6,2); sscanf(strtmp,"%d",&vday);

       vmonth=vyear*12+vmonth+value;
       vmonth--;
       vyear=vmonth/12;
       vmonth=vmonth%12;
       vmonth++;

       if (vyear<1) return(-4);
       if (vyear>9999) return(-5);
       sprintf(date8added,"%04d%02d%02d",vyear,vmonth,vday);
       errbz=checkdate8(date8added);
       if (errbz!=0) return(-6);
       return(0);
    }

    // 当增加量为天数时,计算结果并返回
    if (ymd=='d')
    {
       days=days_from_8zeros(date8);
       days+=value;
       if (days<=366) return(-4);    //年号为0000
       if (days>3652425) return(-5); //年号超出9999
       errbz=get_data8_from_days(days,date8added);
       if (errbz!=0) return(-1);
       return(0);
    }

}


//检查日期YyyyMmdd
//输入:date8 日期字符串
//返回:0-正确  -1-错误
int  checkdate8(char *date8)
{
    int c;
    int errdate=0;
    char str_year[5]="";
    char str_mon[3]="";
    char str_day[3]="";
    int int_year,int_mon,int_day;
    int leap_year;          // 1-闰年  0-不是闰年

    errdate=0;
    if ( strlen(date8) != 8 ) errdate=1;
    if (errdate!=1)
    {
       for (c=0;c<10;c++)
       {
         if (date8[c]==' ') errdate=1;
       }
       if ( date8[0] < '0'  || date8[0] >  '9' ) errdate=1;
       if ( date8[1] < '0'  || date8[1] >  '9' ) errdate=1;
       if ( date8[2] < '0'  || date8[2] >  '9' ) errdate=1;
       if ( date8[3] < '0'  || date8[3] >  '9' ) errdate=1;
       if ( date8[4] < '0'  || date8[4] >  '9' ) errdate=1;
       if ( date8[5] < '0'  || date8[5] >  '9' ) errdate=1;
       if ( date8[6] < '0'  || date8[6] >  '9' ) errdate=1;
       if ( date8[7] < '0'  || date8[7] >  '9' ) errdate=1;
    }

    if (errdate!=1)
    {
       str_year[0]=date8[0]; str_year[1]=date8[1];
          str_year[2]=date8[2]; str_year[3]=date8[3];
          str_year[4]='\0';
       str_mon[0]=date8[4]; str_mon[1]=date8[5]; str_mon[2]='\0';
       str_day[0]=date8[6]; str_day[1]=date8[7]; str_day[2]='\0';
       int_year=atoi(str_year);
       int_mon=atoi(str_mon);
       int_day=atoi(str_day);

       if ( ((int_year%4)==0 && (int_year%100)!=0) || (int_year%400)==0 )
             leap_year=1;
       else  leap_year=0;

       if ( leap_year==0 && int_mon==2 && int_day>28 ) errdate=1;
       if ( leap_year==1 && int_mon==2 && int_day>29 ) errdate=1;
       if ( int_mon==1 && int_day>31 ) errdate=1;
       if ( int_mon==3 && int_day>31 ) errdate=1;
       if ( int_mon==5 && int_day>31 ) errdate=1;
       if ( int_mon==7 && int_day>31 ) errdate=1;
       if ( int_mon==8 && int_day>31 ) errdate=1;
       if ( int_mon==10 && int_day>31 ) errdate=1;
       if ( int_mon==12 && int_day>31 ) errdate=1;
       if ( int_mon==4 && int_day>30 ) errdate=1;
       if ( int_mon==6 && int_day>30 ) errdate=1;
       if ( int_mon==9 && int_day>30 ) errdate=1;
       if ( int_mon==11 && int_day>30 ) errdate=1;
    }

    if ( int_mon<1 || int_mon>12 ) errdate=1;
    if ( int_day<1 ) errdate=1;

    if (errdate==0) return(0);
    return(-1);

}


//功能:计算日期YyyyMmDd距离虚拟的公元00000000的天数
//输入:date8
//返回:所求天数
long int days_from_8zeros(char *date8)
{
   int  leap;       //0-平年 1-闰年
   long int days;
   int  vyear,vmonth,vday;
   int  c;
   char strtmp[10];

   vyear=vmonth=vday=0;
   memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+0,4); sscanf(strtmp,"%d",&vyear);
   memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+4,2); sscanf(strtmp,"%d",&vmonth);
   memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+6,2); sscanf(strtmp,"%d",&vday);


   days=0;
   for (c=0;c<vyear;c++)
   {
       leap=0;
       if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1;
       if (leap==0) days+=365;
       if (leap==1) days+=366;
   }

   c=vyear;
   leap=0;
   if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1;

   for (c=1;c<vmonth;c++)
   {
      if (c==1) days+=31;
      if (c==2 && leap==0) days+=28;
      if (c==2 && leap==1) days+=29;
      if (c==3) days+=31;
      if (c==4) days+=30;
      if (c==5) days+=31;
      if (c==6) days+=30;
      if (c==7) days+=31;
      if (c==8) days+=31;
      if (c==9) days+=30;
      if (c==10) days+=31;
      if (c==11) days+=30;
      if (c==12) days+=31;
   }

   days+=vday;
   return(days);

}


//功能:根据到虚拟的公元00000000的天数计算日期
//输入:days
//输出:date8
//返回:0 成功   -1 失败
int  get_data8_from_days(long int days,char *date8)
{
    long int daystmp;
    int  leap; // 0-平年 1-闰年
    int  c;
    int  vyear,vmonth,vday;

    if (days<=0) return(-1);
    daystmp=0;
    for (c=0;c<=9999;c++)
    {
       leap=0;
       if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1;
       if (leap==0) daystmp+=365;
       if (leap==1) daystmp+=366;
       if (c==9999 && days>daystmp) return(-1);
       if (days<=daystmp)
       {
          vyear=c;
          if (leap==0) daystmp-=365;
          if (leap==1) daystmp-=366;
          break;
       }
    }

    c=vyear;
    leap=0;
    if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1;
    for (c=1;c<=12;c++)
    {
        // 以下这段程序借用vday
        if (c==1) vday=31;
        if (c==2 && leap==0) vday=28;
        if (c==2 && leap==1) vday=29;
        if (c==3) vday=31;
        if (c==4) vday=30;
        if (c==5) vday=31;
        if (c==6) vday=30;
        if (c==7) vday=31;
        if (c==8) vday=31;
        if (c==9) vday=30;
        if (c==10) vday=31;
        if (c==11) vday=30;
        if (c==12) vday=31;

        daystmp+=vday;
        if (days<=daystmp)
        {
           vmonth=c;
           daystmp-=vday;
           break;
        }
    }

    vday=days-daystmp;

    sprintf(date8,"%04d%02d%02d",vyear,vmonth,vday);
    return(0);

}




//功能:返回指定的年月日
//输入:
//     1. YyyyMmDd y [-+]val 返回YyyyMmDd前/后val年对应日的年月日
//     2. YyyyMmDd m [-+]val 返回YyyyMmDd前/后val月对应日的年月日
//     3. YyyyMmDd d [-+]val 返回YyyyMmDd前/后val日对应日的年月日
main(int argc,char *argv[])
{
    char date8[9];
    char ymd[2];
    long int val;
    char date8added[9];

    char strtmp[10];
    int c;
    int errbz;

    //printf("%d\n",days_from_8zeros("00000131"));
    //printf("%d\n",days_from_8zeros("00010131"));
    //printf("%d\n",days_from_8zeros("00020401"));
    //printf("%d\n",days_from_8zeros("20020510"));
    //printf("%d\n",days_from_8zeros("20020531"));
    //printf("%d\n",days_from_8zeros("99991231"));
    //printf("ret:%4d ",get_data8_from_days(31,strtmp));printf("%s\n",strtmp);
    //printf("ret:%4d ",get_data8_from_days(397,strtmp));printf("%s\n",strtmp);
    //printf("ret:%4d ",get_data8_from_days(822,strtmp));printf("%s\n",strtmp);
    //printf("ret:%4d ",get_data8_from_days(731346,strtmp));printf("%s\n",strtmp);
    //printf("ret:%4d ",get_data8_from_days(731367,strtmp));printf("%s\n",strtmp);
    //printf("ret:%4d ",get_data8_from_days(3652425,strtmp));printf("%s\n",strtmp);
    //printf("ret:%4d ",get_data8_from_days(3652426,strtmp));printf("%s\n",strtmp);

    errbz=0;

    //初步检查输入合法性
    if(errbz==0 && argc!=4) errbz=-999;          //参数数量错误
    if(errbz==0 && strlen(argv[1])!=8) errbz=-1; //参数YyyyMmDd非法--长度错
    if(errbz==0 && strlen(argv[2])!=1) errbz=-2; //参数ymd非法--长度错

    //将参数赋值到变量
    if (errbz==0)
    {
       memset(date8,0,sizeof(date8));
       memset(ymd,0,sizeof(ymd));
       val=0;
       strncpy(date8,argv[1],8);
       strncpy(ymd,argv[2],1);
       sscanf(argv[3],"%d",&val);
    }

    //调用函数计算新的日期值
    if (errbz==0)
    {
       memset(date8added,0,sizeof(date8added));
       errbz=date8_add(date8,ymd[0],val,date8added);
    }

    // 将结算结果或错误信息用printf输出
    if (errbz==0) printf("%s\n",date8added);

    if (errbz==-999) printf("%d Usage: date8add YyyyMmDd {ymd} [+|-]value\n",errbz);
    if (errbz==-1) printf("%d Usage: date8add YyyyMmDd {ymd} [+|-]value\n",errbz);
    if (errbz==-2) printf("%d Usage: date8add YyyyMmDd {ymd} [+|-]value\n",errbz);
    if (errbz==-3) printf("%d Usage: date8add YyyyMmDd {ymd} [+|-]value\n",errbz);
    if (errbz==-4) printf("%d result is valid\n",errbz);
    if (errbz==-5) printf("%d result is valid\n",errbz);
    if (errbz==-6) printf("%d result is valid\n",errbz);
}



 山地獾 回复于:2002-10-11 11:31:43
#include <time.h>

//功能:返回指定的年月日
//输入:
//     1. YyyyMmDd [-+]val 返回YyyyMmDd前/后val年对应日的年月日
//     2. YyyyMmDd [-+]val 返回YyyyMmDd前/后val月对应日的年月日
//     3. YyyyMmDd [-+]val 返回YyyyMmDd前/后val日对应日的年月日
main(int argc,char *argv[])
{
    time_t current;
    time_t current0;
    struct tm tm_struct,*ptm;

    char date8[9];
    char ymd[2];
    long int val;
    char strtmp[10];
    int c;
    int errbz;

    errbz=0;
    if(errbz==0 && argc!=3) errbz=1;
    if(errbz==0 && strlen(argv[1])!=8) errbz=1;

    if (errbz==0)
    {
       memset(date8,0,sizeof(date8));
       memset(date8,0,sizeof(ymd));
       val=0;
       strncpy(date8,argv[1],8);
       sscanf(argv[2],"%d",&val);
    }

    if (errbz==0)
    {
       for(c=0;c<8;c++)
         if(date8[c]<'0' || date8[c]>'9') { errbz=1;break; }
    }
    
    if (errbz==1)
    {
       printf("输入错误! 使用方法: 命令  日期YyyyMmDd  [+|-]value\n");
       return;
    }


    memset(&tm_struct,0,sizeof(tm_struct));
    memset(strtmp,0,sizeof(strtmp));strncpy(strtmp,date8+0,4);sscanf(strtmp,"%d",&tm_struct.tm_year);
    memset(strtmp,0,sizeof(strtmp));strncpy(strtmp,date8+4,2);sscanf(strtmp,"%d",&tm_struct.tm_mon);
    memset(strtmp,0,sizeof(strtmp));strncpy(strtmp,date8+6,2);sscanf(strtmp,"%d",&tm_struct.tm_mday);
    tm_struct.tm_year-=1900;
    tm_struct.tm_mon-=1;

    current0=mktime(&tm_struct);
    current = current0;
    current+=val*24*60*60;
    ptm = localtime(¤t);     /* 获取计算结果 */
    printf("%04d%02d%02d\n",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday);

}



 山地獾 回复于:2002-10-11 11:32:18
#include <stdio.h>

int  date8_add(char *date8,char ymd,int value,char *date8added);
int  checkdate8(char *date8);
long int days_from_8zeros(char *date8);
int  get_data8_from_days(long int days,char *date8);


//功能:计算某年月日前后一定年数(或月数、天数)的年月日
//输入:
//     1. date8 计算基准日期
//     2. ymd   表示下一变量的单位  'y'-年  'm'-月  'd'-日
//     3. value 偏移量:年数、月数、天数
//输出:
//     1. date8added 计算后结果
//返回:
//      0 成功
//     -1 date8非法
//     -2 ymd非法
//     -3 value非法
//     -4 转换后date8added的年份小于公元1年
//     -5 转换后date8added的年份大于公元9999年
//     -6 转换后date8added非法,例如得到结果为2002/02/30
int  date8_add(char *date8,char ymd,int value,char *date8added)
{
    char strtmp[10];
    long int days;
    int c,vyear,vmonth,vday;
    int errbz;

    // 检查参数date8的合法性
    errbz=checkdate8(date8);
    if (errbz!=0) return(-1);

    // 检查参数ymd的合法性
    if ( ymd!='y' && ymd!='m' && ymd!='d') return(-2);

    // 检查参数value的合法性(简单检查)
    //if ( value < -9999 || value > 9999 ) return(-3);

    // 当增加量为年数时,计算结果并返回
    if (ymd=='y')
    {
       memset(strtmp,0,sizeof(strtmp));
       memcpy(strtmp,date8+0,4);
       sscanf(strtmp,"%d",&vyear);
       vyear+=value;
       if ( vyear<1 )    return(-4); //小于公元1年
       if ( vyear>9999 ) return(-5); //大于公元9999年

       strcpy(date8added,date8);
       sprintf(strtmp,"%04d",vyear);
       memcpy(date8added,strtmp,4);
       errbz=checkdate8(date8added);
       if (errbz!=0)     return(-6); //计算所得结果非法
       return(0);
    }

    // 当增加量为月数时,计算结果并返回
    if (ymd=='m')
    {
       vyear=0;
       vmonth=0;
       vday=0;
       
       memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+0,4); sscanf(strtmp,"%d",&vyear);
       memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+4,2); sscanf(strtmp,"%d",&vmonth);
       memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+6,2); sscanf(strtmp,"%d",&vday);

       vmonth=vyear*12+vmonth+value;
       vmonth--;
       vyear=vmonth/12;
       vmonth=vmonth%12;
       vmonth++;

       if (vyear<1) return(-4);
       if (vyear>9999) return(-5);
       sprintf(date8added,"%04d%02d%02d",vyear,vmonth,vday);
       errbz=checkdate8(date8added);
       if (errbz!=0) return(-6);
       return(0);
    }

    // 当增加量为天数时,计算结果并返回
    if (ymd=='d')
    {
       days=days_from_8zeros(date8);
       days+=value;
       if (days<=366) return(-4);    //年号为0000
       if (days>3652425) return(-5); //年号超出9999
       errbz=get_data8_from_days(days,date8added);
       if (errbz!=0) return(-1);
       return(0);
    }

}


//检查日期YyyyMmdd
//输入:date8 日期字符串
//返回:0-正确  -1-错误
int  checkdate8(char *date8)
{
    int c;
    int errdate=0;
    char str_year[5]="";
    char str_mon[3]="";
    char str_day[3]="";
    int int_year,int_mon,int_day;
    int leap_year;          // 1-闰年  0-不是闰年

    errdate=0;
    if ( strlen(date8) != 8 ) errdate=1;
    if (errdate!=1)
    {
       for (c=0;c<10;c++)
       {
         if (date8[c]==' ') errdate=1;
       }
       if ( date8[0] < '0'  || date8[0] >  '9' ) errdate=1;
       if ( date8[1] < '0'  || date8[1] >  '9' ) errdate=1;
       if ( date8[2] < '0'  || date8[2] >  '9' ) errdate=1;
       if ( date8[3] < '0'  || date8[3] >  '9' ) errdate=1;
       if ( date8[4] < '0'  || date8[4] >  '9' ) errdate=1;
       if ( date8[5] < '0'  || date8[5] >  '9' ) errdate=1;
       if ( date8[6] < '0'  || date8[6] >  '9' ) errdate=1;
       if ( date8[7] < '0'  || date8[7] >  '9' ) errdate=1;
    }

    if (errdate!=1)
    {
       str_year[0]=date8[0]; str_year[1]=date8[1];
          str_year[2]=date8[2]; str_year[3]=date8[3];
          str_year[4]='\0';
       str_mon[0]=date8[4]; str_mon[1]=date8[5]; str_mon[2]='\0';
       str_day[0]=date8[6]; str_day[1]=date8[7]; str_day[2]='\0';
       int_year=atoi(str_year);
       int_mon=atoi(str_mon);
       int_day=atoi(str_day);

       if ( ((int_year%4)==0 && (int_year%100)!=0) || (int_year%400)==0 )
             leap_year=1;
       else  leap_year=0;

       if ( leap_year==0 && int_mon==2 && int_day>28 ) errdate=1;
       if ( leap_year==1 && int_mon==2 && int_day>29 ) errdate=1;
       if ( int_mon==1 && int_day>31 ) errdate=1;
       if ( int_mon==3 && int_day>31 ) errdate=1;
       if ( int_mon==5 && int_day>31 ) errdate=1;
       if ( int_mon==7 && int_day>31 ) errdate=1;
       if ( int_mon==8 && int_day>31 ) errdate=1;
       if ( int_mon==10 && int_day>31 ) errdate=1;
       if ( int_mon==12 && int_day>31 ) errdate=1;
       if ( int_mon==4 && int_day>30 ) errdate=1;
       if ( int_mon==6 && int_day>30 ) errdate=1;
       if ( int_mon==9 && int_day>30 ) errdate=1;
       if ( int_mon==11 && int_day>30 ) errdate=1;
    }

    if ( int_mon<1 || int_mon>12 ) errdate=1;
    if ( int_day<1 ) errdate=1;

    if (errdate==0) return(0);
    return(-1);

}


//功能:计算日期YyyyMmDd距离虚拟的公元00000000的天数
//输入:date8
//返回:所求天数
long int days_from_8zeros(char *date8)
{
   int  leap;       //0-平年 1-闰年
   long int days;
   int  vyear,vmonth,vday;
   int  c;
   char strtmp[10];

   vyear=vmonth=vday=0;
   memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+0,4); sscanf(strtmp,"%d",&vyear);
   memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+4,2); sscanf(strtmp,"%d",&vmonth);
   memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+6,2); sscanf(strtmp,"%d",&vday);


   days=0;
   for (c=0;c<vyear;c++)
   {
       leap=0;
       if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1;
       if (leap==0) days+=365;
       if (leap==1) days+=366;
   }

   c=vyear;
   leap=0;
   if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1;

   for (c=1;c<vmonth;c++)
   {
      if (c==1) days+=31;
      if (c==2 && leap==0) days+=28;
      if (c==2 && leap==1) days+=29;
      if (c==3) days+=31;
      if (c==4) days+=30;
      if (c==5) days+=31;
      if (c==6) days+=30;
      if (c==7) days+=31;
      if (c==8) days+=31;
      if (c==9) days+=30;
      if (c==10) days+=31;
      if (c==11) days+=30;
      if (c==12) days+=31;
   }

   days+=vday;
   return(days);

}


//功能:根据到虚拟的公元00000000的天数计算日期
//输入:days
//输出:date8
//返回:0 成功   -1 失败
int  get_data8_from_days(long int days,char *date8)
{
    long int daystmp;
    int  leap; // 0-平年 1-闰年
    int  c;
    int  vyear,vmonth,vday;

    if (days<=0) return(-1);
    daystmp=0;
    for (c=0;c<=9999;c++)
    {
       leap=0;
       if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1;
       if (leap==0) daystmp+=365;
       if (leap==1) daystmp+=366;
       if (c==9999 && days>daystmp) return(-1);
       if (days<=daystmp)
       {
          vyear=c;
          if (leap==0) daystmp-=365;
          if (leap==1) daystmp-=366;
          break;
       }
    }

    c=vyear;
    leap=0;
    if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1;
    for (c=1;c<=12;c++)
    {
        // 以下这段程序借用vday
        if (c==1) vday=31;
        if (c==2 && leap==0) vday=28;
        if (c==2 && leap==1) vday=29;
        if (c==3) vday=31;
        if (c==4) vday=30;
        if (c==5) vday=31;
        if (c==6) vday=30;
        if (c==7) vday=31;
        if (c==8) vday=31;
        if (c==9) vday=30;
        if (c==10) vday=31;
        if (c==11) vday=30;
        if (c==12) vday=31;

        daystmp+=vday;
        if (days<=daystmp)
        {
           vmonth=c;
           daystmp-=vday;
           break;
        }
    }

    vday=days-daystmp;

    sprintf(date8,"%04d%02d%02d",vyear,vmonth,vday);
    return(0);

}



//功能:返回两个日期相差的天数
//输入:
main(int argc,char *argv[])
{
    char date1[9];
    char date2[9];

    long int day1;
    long int day2;

    int errbz;

    errbz=0;

    //检查输入合法性
    if(errbz==0 && argc!=3) errbz=-999;          //参数数量错误
    if(errbz==0 && strlen(argv[1])!=8) errbz=-1; //第一个日期长度错
    if(errbz==0 && strlen(argv[2])!=8) errbz=-2; //第二个日期长度错
    if (errbz==0)
    {
       strcpy(date1,argv[1]);
       strcpy(date2,argv[2]);
    }
    if (errbz==0)
    {
       errbz=checkdate8(date1);
       if(errbz!=0) errbz=-1;
    }
    if (errbz==0)
    {
       errbz=checkdate8(date2);
       if(errbz!=0) errbz=-2;
    }
    
    if (errbz!=0)
    {
      fprintf(stderr,"%d Usage: date8sub YyyyMmDd YyyyMmDd\n",errbz);
      return(errbz);
    }

    day1=days_from_8zeros(date1);
    day2=days_from_8zeros(date2);
    printf("%d\n",day1-day2);
    return(0);
}



 suney 回复于:2002-10-11 12:09:22
我在工作时也会遇到需得到昨天的时间,但我手上有一个不知道是什么高人写的,而且是编译过或是加密的的小程序。把它加到SHELL中可直接得到昨天的日期。

还有,好象DATE有yesterday的参数吧。

 unixkiller 回复于:2002-10-11 13:06:27
编译后试了一下,好像可以

 huhuegg 回复于:2005-05-17 15:17:56
[b:a04b4d13ae]date --date "3 days ago" +%Y/%m/%d[/b:a04b4d13ae]

 云飞舞 回复于:2005-05-17 15:34:31
# date +%Y%m%d
20050517

# date +%Y%m%d -d '-100 day'
20050206

 fangjy2008 回复于:2005-05-17 16:16:47
LINUX上可以按这种方法来做
假如今天是2005-05-17
取2004-09-25
#date -d"-1 year +4 month +8 day" +%Y-%m-%d
取2008-02-12
#date -d"+3 year -3 month -5 day" +%Y-%m-%d

 w123456 回复于:2005-05-18 16:26:51
假如现在是2005-05-18 16:34:20
取        2005-05-18 08:20:00

 该咋个取?

 云飞舞 回复于:2005-05-18 16:31:02
没懂w123456的需求……

 w123456 回复于:2005-05-18 16:38:21
将文件中的时间项  2005-05-18     16:34:20 
调整为            2005-05-18     08:20:00 

即" -8 hour  -14min  -20 second "

 mauricewoo 回复于:2005-06-11 21:03:33
date -date=yesterday

 BigMonkey 回复于:2005-07-29 17:23:04
我也有次疑问
用c语言没那么复杂
用mktime函数和struct tm *
结构体就ok
代码估计5行都不到

 林子 回复于:2005-08-02 15:19:31
给一段经典的,不仅可以到昨天,只要改变24,如48,72 还可以得到前天、前前天。

yesterday()
{
        oset=`echo $TZ|tr -d '[A-Z+]`
        new_offset=`expr $oset + 24`
        TZ=`echo $TZ|sed "s/[+-]\{0,1\}[0-9][0-9]\{0,1\}/$new_oset/`\
        date +%m\/%d\/20%y
}
clear
lastday=`yesterday`
echo "\n\n\n\n\n\n\n\t\t请输入日期(缺省为昨日mm/dd/yyyy):\c"
read days
days=${days:="$lastday"}

 林子 回复于:2005-08-02 15:29:01
new_offset=`expr $oset + 24` 
应改为:new_oset=`expr $oset + 24`

 edwardcj 回复于:2005-08-03 08:48:50
[quote:88d23f3686="BigMonkey"]我也有次疑问
用c语言没那么复杂
用mktime函数和struct tm *
结构体就ok
代码估计5行都不到[/quote:88d23f3686]

下面是一个实现:
真正实现部分也就5-6行
[code:1:88d23f3686]
#include "stdio.h" 
#include "time.h" 

main(int argc, char *argv[]) 

   struct tm *tm; 
   time_t now; 
   int    yyyy=1, n=0; 

   if (argc>1){ 
      if (strcmp(argv[1], "-?")==0){ 
         printf("Usage: %s [+|-ndays] [Y4|Y2]\n", argv[0]); 
         printf("default +0 Y4\n", argv[0]); 
         printf("output is [YY]YYMMDD\n"); 
         exit(1); 
      } 
      else n = atoi(argv[1]); 
   } 
   if (argc>2) 
      yyyy = strcmp(argv[2], "Y2"); 
   now = time(NULL); 
   if (n) now += n*24*60*60; 
   tm = localtime(&now); 
   n = tm->tm_year + 1900; 
   if (yyyy) printf("%02d", n/100); 
   printf("%02d%02d%02d", n % 100, tm->tm_mon+1, tm->tm_mday); 
   return 0; 
} [/code:1:88d23f3686]

 别墅 回复于:2005-08-03 14:31:20
ddd

 水若寒 回复于:2005-08-26 12:02:13
[quote:76b16703fd="solarwind"]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 $mo..........[/quote:76b16703fd]

[color=red:76b16703fd]这有段怎样得到0826这样的格式?[/color:76b16703fd]