藍森林首頁 | 返回主頁 | 本站地圖 | 站內搜索 | 聯繫信箱 |
 您目前的位置:首頁 > 自由軟件 > 技術交流 > 應用編程


    

藍森林 http://www.lslnet.com 2006年6月6日 10:18


[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

// 我保證超級的準確, 哈哈

#include <iostream>;
using namespace std;

bool isleap(int y)
{ return y%4==0&&y%100!=0 || y%400==0;
}

bool is_correct_date(int d, int m, int y)
{
   if(
      (y<1||m<1||m>;12||d<1||d>;31) ||
      ((m==4||m==6||m==9||m==11)&&d>;30) ||
      (m==2 && isleap(y) && d>;29) ||
      (m==2 && !isleap(y) && d>;28 )
     )
   return false;
   return true;
}

void swap(int& a,int& b)
{
   int temp;
   temp = a;
   a = b;
   b = temp;
}

//input a date and increase by one day
void increase_one_day(int& d, int& m, int& y)
{
   
       d++;
       if(
             (((m==1||m==3||m==5||m==7||m==8||m==10)&&d==32))
             || ((m==4||m==6||m==9||m==11)&&d==31)
             || (m==2 && isleap(y) && d==30)
             || (m==2 && !isleap(y) && d==29)
         )
       {
             m++;                                            
             d=1;                                            
       }
       else if(m==12&&d==32)                             
       {
         y++;                                            
         m=1;                                            
         d=1;                                            
       }
}  

//input : day, month, year and the days increased
void after_n_days(int& d, int& m, int& y, int n_days)      
{
   while(n_days>;0)
   {
        increase_one_day(d, m, y);
        n_days--;
   }
}

//return the days between two date
int days_between_two_date(int d1, int m1, int y1,
                          int d2, int m2, int y2)
{
    int days = 0;
    if(y1<y2 || (y1==y2&&m1<m2) || (y1==y2&&m1==m2&&d1<d2))
    {     
        swap(y1, y2);
        swap(m1, m2);
        swap(d1, d2);
    }        
    while(y2!=y1 || m2!=m1 || d2!=d1)
    {
       increase_one_day(d2, m2, y2);
       days++;
    }   
    return days;
}   

int main()
{
  
  int d1, m1, y1, d2, m2, y2;
  cout<<"Enter date_1(day month year): ";
  cin>;>;d1>;>;m1>;>;y1;
  cout<<"Enter date_2(day month year): ";
  cin>;>;d2>;>;m2>;>;y2;
  cout<<endl;
  
  if(!is_correct_date(d2,m2,y2)||!is_correct_date(d1,m1,y1))
     cout<<"Error Date Exist!"<<endl;                                      
  else
  {
  
      cout<<"There are "<<days_between_two_date(d1, m1, y1, d2, m2, y2)
      <<" days between this two date."<<endl;   cout<<endl;
      
      int days;
      cout<<"Enter the days you need to increase:";
      cin>;>;days;
      after_n_days(d1, m1, y1, days);
      cout<<"date_1 after "<<days<<" days is "<<d1<<" "<<m1<<" "<<y1<<" "<<endl;
  }
}

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

藍色鍵盤, 無雙, gadfly, JohnBull ,   給個精華把,轉精華 :)

給個精華把, 什麼都考慮了, 什麼閏年啊, 31, 28啊, 什麼的啊, 我保證沒有一電點錯。

那位大俠能找了一個錯例嗎???????

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

關鍵是。。。。
沒有必要啊
練習一下思維的縝密倒還是有幫助。

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

! 代碼沒對齊
2 沒有註釋 別人要先看懂你的代碼才知道你要實現什麼功能 從軟件工程角度來看重寫一遍都可以了

3 有必要那麼麻煩嗎 使用localtime 得到的時間加上 N天對應的秒數 再使用tm 得到日期就OK了

4 能把自己想法寫出來還是不錯的
希望大家能這樣寫出自己想法
鼓勵一個
下次寫得很好的話再加精華
同樣各位代碼寫得很好的話也會加精華的

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

-->


不用localtime, tm , 你寫的出來嗎, 3小時之內?

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

可以

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

但是使用localtime
tm是最簡單的方法

因為你的是一天一天推進的
所以性能並不高
如果是負數就是要後退幾天的話
那麼能不能實現

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

[code]

struct day_info{
        unsigned int year;        //年份
        unsigned int month;           //1-12
        unsigned int day;        //1-31
};

//修正年
//兩上參數都是輸入舊值 返回新值
void advance_year(day_info &newdayinfo,int& advance_num)
{       
        newdayinfo.year        +=4*(advance_num/(365*4+1));        //看看要前進多少年
        advance_num        %=365*4+1;                //整理一年內的天數

        if(new_day<0){
                newdayinfo.year        -=4;
                advance_num        +=365*4+1;
        }

        while(advance_num<366){
                if((newdayinfo.year%4==0&& ewdayinfo.year%100!=0)
                                ||(newdayinfo.year%400==0)){
                        if(advance_num<367)
                                return ;
                        advance_num-=366;
                }else{
                        advance_num-=365;
                }
        }
}

//修正月
//兩個參數都是輸入舊值返回新值
void advance_month(day_info &newdayinfo,int& advance_num)
{
   newdayinfo.day+=advance_num;
   while(newdayinfo.day>;28){
      switch(newdayinfo.month){
         case 1:
         case 3:
         case 5:
         case 7:
         case 8:
         case 10:
         case 12:
            if(newdayinfo.day<=31)
               return ;
            newdayinfo.day-=31;
            break;

         case 2:
            if((newdayinfo.year%4==0&& ewdayinfo.year%100!=0)
                  ||(newdayinfo.year%400==0)){
               if(newdayinfo.day==29)
                  return ;
               newdayinfo.day--;
            }
            newdayinfo.day-=28;
            break;
            
         default:
            newdayinfo.day-=30;
            break;
      }
      newdayinfo.month++;
      if(newdayinfo.month>;12){
        newdayinfo.month-=12;
        newdayinfo.year++;
      }
   }
}

//可以前進或是後退
//        day[inout]        輸入今天 返回advance_num後的天數
//        advance_num        要推進的天數,如果<0那麼表示要後退的天數
//        返回                today的值
day_info & day_advance(day_info &today,int advance_num)
{
        advance_num         +=today.day-1;
        today.day        =1;
       
        advance_year(&newdayinfo, advance_num);
        advance_month(day_info &newdayinfo,int& advance_num);
}

[/code]

先寫完
等會測試

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

[code]#include <stdio.h>;
struct day_info{
    unsigned int year;        //年份
    unsigned int month;           //1-12
    unsigned int day;        //1-31
};

//修正年 ,根據advance_num日期修改年份
//兩上參數都是輸入舊值 返回新值
static void advance_year(day_info &newdayinfo,int& advance_num)
{
    day_info olddayinfo = newdayinfo;
    newdayinfo.year        +=4*(advance_num/(365*4+1));        //看看要前進多少年
    advance_num        %=365*4+1;                //整理一年內的天數

    if(advance_num<0){
        newdayinfo.year        -=4;
        advance_num        +=365*4+1;
    }

    while(advance_num>;365){
        if((newdayinfo.year%4==0&& newdayinfo.year%100!=0)
                ||(newdayinfo.year%400==0)){
            if(advance_num<367)
                break ;

            advance_num--;
        }

        advance_num-=365;
        newdayinfo.year+=1;
    }
}

//修正月 ,根據advance_num日期修改月份,可能會進一年
//兩個參數都是輸入舊值返回新值
static void advance_month(day_info &newdayinfo,int& advance_num)
{
    newdayinfo.day+=advance_num;
    while(newdayinfo.day>;28){
        switch(newdayinfo.month){
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                if(newdayinfo.day<=31)
                    return ;
                newdayinfo.day-=31;
                break;

            case 2:
                if((newdayinfo.year%4==0&& newdayinfo.year%100!=0)
                        ||(newdayinfo.year%400==0)){
                    if(newdayinfo.day==29)
                        return ;
                    newdayinfo.day--;
                }
                newdayinfo.day-=28;
                break;

            default:
                newdayinfo.day-=30;
                break;
        }
        newdayinfo.month++;
        if(newdayinfo.month>;12){
            newdayinfo.month-=12;
            newdayinfo.year++;
        }
    }
}

static convert2firstday(day_info &today,int &advance_num)
{
    advance_num         +=today.day-1;
    today.day        =1;

    while(today.month>;1){
        today.month--;
        switch(today.month){
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                advance_num+=31;
                break;

            case 2:
                if((today.year%4==0&& today.year%100!=0)
                        ||(today.year%400==0)){
                    advance_num++;
                }
                advance_num+=28;
                break;

            default:
                advance_num+=30;
                break;
        }
    }
}

//可以前進或是後退
//        day[inout]        輸入今天 返回advance_num後的天數
//        advance_num        要推進的天數,如果<0那麼表示要後退的天數
//        返回                today的值
day_info & day_advance(day_info &today,int advance_num)
{
    convert2firstday (today, advance_num);
    advance_year(today, advance_num);
    advance_month(today,advance_num);
}


main()
{
    day_info newday;
    day_info today={2000,3,13};

    int advance_num;
    newday=today;
    while(1){
        printf("new day is :%4d\%2d\%2d\n",
                newday.year,newday.month,newday.day);
        printf("please input advancenum:\n");
        scanf("%d",&advance_num);

        day_advance(newday,advance_num);
    }
}
[/code]

安裝了個BCB
然後調試了一下

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

好, 已經不錯了

10000 天, 沒什麼誤差
100000 天, 誤差2天
1000000 天, 誤差二十幾天

效率比我高點, 算法比我差點, 就算不相上下把 :)

我忘了用 CODE 功能了, 對的不齊, 我從帖在下面把 

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

//主要是寫了兩個函數, 
//一個是計算日期加減的,
//另一個是算,給定一個日期,過了N天後的天數的   

[code]
#include <iostream>;
using namespace std;

bool isleap(int y)
{ return y%4==0&&y%100!=0 || y%400==0;
}

bool is_correct_date(int d, int m, int y)
{
   if(
      (y<1||m<1||m>;12||d<1||d>;31) ||
      ((m==4||m==6||m==9||m==11)&&d>;30) ||
      (m==2 && isleap(y) && d>;29) ||
      (m==2 && !isleap(y) && d>;28)
     )
   return false;
   return true;
}

void swap(int& a,int& b)
{
   int temp;
   temp = a;
   a = b;
   b = temp;
}

//input a date and increase by one day
void increase_one_day(int& d, int& m, int& y)
{
   
       d++;
       if(
             (((m==1||m==3||m==5||m==7||m==8||m==10)&&d==32))
             || ((m==4||m==6||m==9||m==11)&&d==31)
             || (m==2 && isleap(y) && d==30)
             || (m==2 && !isleap(y) && d==29)
         )
       {
             m++;                                            
             d=1;                                            
       }
       else if(m==12&&d==32)                             
       {
         y++;                                            
         m=1;                                            
         d=1;                                            
       }
}  

//input : day, month, year and the days increased
void after_n_days(int& d, int& m, int& y, int n_days)      
{
   while(n_days>;0)
   {
        increase_one_day(d, m, y);
        n_days--;
   }
}

//return the days between two date
int days_between_two_date(int d1, int m1, int y1,
                          int d2, int m2, int y2)
{
    int days = 0;
    if(y1<y2 || (y1==y2&&m1<m2) || (y1==y2&&m1==m2&&d1<d2))
    {     
        swap(y1, y2);
        swap(m1, m2);
        swap(d1, d2);
    }        
    while(y2!=y1 || m2!=m1 || d2!=d1)
    {
       increase_one_day(d2, m2, y2);
       days++;
    }   
    return days;
}   

int main()
{
  
  int d1, m1, y1, d2, m2, y2;
  cout<<"Enter date_1(day month year): ";
  cin>;>;d1>;>;m1>;>;y1;
  cout<<"Enter date_2(day month year): ";
  cin>;>;d2>;>;m2>;>;y2;
  cout<<endl;
  
  if(!is_correct_date(d2,m2,y2)||!is_correct_date(d1,m1,y1))
     cout<<"Error Date Exist!"<<endl;                                      
  else
  {
  
      cout<<"There are "<<days_between_two_date(d1, m1, y1, d2, m2, y2)
      <<" days between this two date."<<endl;   cout<<endl;
      
      int days;
      cout<<"Enter the days you need to increase:";
      cin>;>;days;
      after_n_days(d1, m1, y1, days);
      cout<<"date_1 after "<<days<<" days is "<<d1<<" "<<m1<<" "<<y1<<" "<<endl;
  }
}                        
[/code]

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

OK
我再試試

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

樓主zephyr82兄弟精神可嘉,也夠熱情。

給個精華吧,鼓勵一下!

:P  :P  :P

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

高人啊!

[轉] 關於日期夾剪啊, 過了幾天是幾號啊啊。。。。

mktime()
這麼好的函數放著不用真是可惜。
為當初寫mktime()函數的前輩感到惋惜啊。



Copyright © 1999-2000 LSLNET.COM. All rights reserved. 藍森林網站 版權所有。 E-mail : webmaster@lslnet.com