计算C中两个日期之间的工作日

时间:2016-11-27 17:20:44

标签: c

我在C中用两个函数编写代码。

第一个(WorkDay)会显示一个日期并说明是否是工作日(return 1)或不是return 0)。我认为第一个功能是可以的,虽然它可能会更好,但它确实有效。它包括我国的周末和公众假期。

问题在于第二个函数(CountWorkDays)。它应该花两个日期并说明它们是否正确(return 1),并且在这种情况下还要说明其中有多少个工作日,包括输入的日期(cnt=)。如果日期不正确(首先大于第二个等),则有return 0。我试图提供帮助功能next_day(),但我很确定这是错误的。你能帮我解决第二个问题吗? 我不能使用<time.h>并且我在那里放了一些断言,我正在测试函数。

#include <stdio.h>
#include <math.h>
#include <assert.h>

int WorkDay ( int y, int m, int d )
{
int h, day;
h= (d + floor(((m+1)*26)/10) + y + floor(y/4) + 6*floor(y/100) + floor(y/400));
day=h%7;

if ((y%4!=0) && m==2 && d==29)
    return 0;
else if (((y%4==0 || y%400==0) && (y%100!=0 || y%4000!=0)) && m==2 && d==29)
{

    if (day==2 || day==3 || day==4 || day==1 || day==0)
        return 1;
    else
        return 0;
}
else if ((d==1 && m==1) || (d==1 && m==5) || (d==8 && m==5) || (d==5 && m==7) || (d==6 && m==7) ||  (d==28 && m==9) || (d==28 && m==10) || (d==17 && m==11) || (d==24 && m==12) || (d==25 && m==12) || (d==26 && m==12) || day==0 || day==1 || (m==1 && (d>31 || d<1)) || (m==2 && (d>29 || d<1)) || (m==3 && (d>31 || d<1)) || (m==4 && (d>30 || d<1)) || (m==5 && (d>31 || d<1)) || (m==6 && (d>30 || d<1)) || (m==7 && (d>31 || d<1)) || (m==8 && (d>31 || d<1)) || (m==9 && (d>30 || d<1)) || (m==10 && (d>31 || d<1)) || (m==11 && (d>30 || d<1)) || (m==12 && (d>31 || d<1)) || y<2000 || m>12 || m<1)
    return 0;
else if (day==2 || day==3 || day==4 || day==5 || day==6)
    return 1;
else
    return 0;
}


int next_day()
{
int y1, m1, d1;
static int days_in_month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
unsigned short day_counter;

    d1 += 1; day_counter++;
    if (d1 > days_in_month[m1])
        {
        d1 = 1;
        m1 += 1;
            if (m1 > 12)
            {
            m1 = 1;
            y1 += 1;
            if (((y1%4==0 || y1%400==0) && (y1%100!=0 || y1%4000!=0)))
                {
                days_in_month[2] = 29;
                }
            else
                {
                days_in_month[2] = 28;
                }
            }
        }
return 0;
}

int CountWorkDays ( int y1, int m1, int d1,
                int y2, int m2, int d2,
                int * cnt )
{
int i,x;
if ( (m1==1 && (d1>31 || d1<1)) || (m1==2 && (d1>29 || d1<1)) || (m1==3 && (d1>31 || d1<1)) || (m1==4 && (d1>30 || d1<1)) || (m1==5 && (d1>31 || d1<1)) || (m1==6 && (d1>30 || d1<1)) || (m1==7 && (d1>31 || d1<1)) || (m1==8 && (d1>31 || d1<1)) || (m1==9 && (d1>30 || d1<1)) || (m1==10 && (d1>31 || d1<1)) || (m1==11 && (d1>30 || d1<1)) || (m1==12 && (d1>31 || d1<1)) || y1<2000 || m1>12 || m1<1 ||(m2==1 && (d2>31 || d2<1)) || (m2==2 && (d2>29 || d2<1)) || (m2==3 && (d2>31 || d2<1)) || (m2==4 && (d2>30 || d2<1)) || (m2==5 && (d2>31 || d2<1)) || (m2==6 && (d2>30 || d2<1)) || (m2==7 && (d2>31 || d2<1)) || (m2==8 && (d2>31 || d2<1)) || (m2==9 && (d2>30 || d2<1)) || (m2==10 && (d2>31 || d2<1)) || (m2==11 && (d2>30 || d2<1)) || (m2==12 && (d2>31 || d2<1)) || y2<2000 || m2>12 || m2<1 || y2>y1 || (y1==y2 && m2>m1) || (y1==y2 && m1==m2 && d2>d1) )
    return 0;
else
{
while (y1!=y2 && m1!=m2 && d1!=d2)
{
while (next_day())
    {
    if (WorkDay( y1, m1, d1 ) == 1)
        i=0;
        x=i++;
    }
}
*cnt=x;
return 1;
}
}

int main ( int argc, char * argv [] )
{
  int cnt;
  assert ( WorkDay ( 2016, 11, 11 ) );
  assert ( ! WorkDay ( 2016, 11, 12 ) );
  assert ( CountWorkDays ( 2016, 11,  1,
                       2016, 11, 30, &cnt ) == 1
       && cnt == 21 );
  assert ( CountWorkDays ( 2001,  1,  1,
                       2015,  2, 29, &cnt ) == 0 );
  return 0;
}

2 个答案:

答案 0 :(得分:0)

问题在于next_day()和CountWorkDays()。

  1. next_day()使用局部变量d1,m1和y1。它计算一些随机日的第二天。
  2. 在CountWorkDays()中,您没有递增d1,m1,y1。
  3. <强>解决方案:

    1. 修改next_day()以接收一天作为输入,并在第二天作为输出返回。

      int next_day(int *d, int *m, int *y)
      {
          /* Use current day to start. */
          int y1 = *y;
          int m1 = *m;
          int d1 = *d;
      
         /* Your code to find next day. Remove day_counter here as it is unnecessary.*/
      
         /* Return next day. */
         *y = y1;
         *m = m1;
         *d = d1;
         return 0;
      }
      
    2. 在CountWorkDays()中调用next_day,d1,m1,y1如下所示。

    3. else
      {
          while (1)
          {
              if (y1!=y2 && m1!=m2 && d1!=d2) //Check if end day is reached.
              {
                  if (WorkDay( y1, m1, d1 ) == 1)
                      x++; //At the beginning initialize x to 0.
              }
              else
              {
                  break;
              }
      
              next_day(&d1, &m1, &y1); //Get the next day.
          }
      }
      

答案 1 :(得分:0)

try {
    offers.acceptOffer({tradeOfferId: offer.tradeofferid}, function(err, log) {
        if (err) { 
            helper.log('Error accepting trade offer ' + offer.tradeofferid, 891, err);
            offers.declineOffer({tradeOfferId: offer.tradeofferid}, function() {
                currentGameOffers.splice(currentGameOffers.indexOf(offer.tradeofferid), 1);
            });     
            return;
        }

你的逻辑错误多余。如果日期小于1,您需要检查一次。您正在检查至少20次。然后在另一个功能中再次检查20次。你重复int CountWorkDays(int y1, int m1, int d1, int y2, int m2, int d2, int * cnt) { int i, x; if( (m1 == 1 && (d1>31 || d1<1)) || (m1 == 2 && (d1>29 || d1<1)) || (m1 == 3 && (d1>31 || d1<1)) || (m1 == 4 && (d1>30 || d1<1)) || (m1 == 5 && (d1>31 || d1<1)) || (m1 == 6 && (d1>30 || d1<1)) || (m1 == 7 && (d1>31 || d1<1)) || (m1 == 8 && (d1>31 || d1<1)) || (m1 == 9 && (d1>30 || d1<1)) || (m1 == 10 && (d1>31 || d1<1)) || (m1 == 11 && (d1>30 || d1<1)) || (m1 == 12 && (d1>31 || d1<1)) || y1<2000 || m1>12 || m1<1 || (m2 == 1 && (d2>31 || d2<1)) || (m2 == 2 && (d2>29 || d2<1)) || (m2 == 3 && (d2>31 || d2<1)) || (m2 == 4 && (d2>30 || d2<1)) || (m2 == 5 && (d2>31 || d2<1)) || (m2 == 6 && (d2>30 || d2<1)) || (m2 == 7 && (d2>31 || d2<1)) || (m2 == 8 && (d2>31 || d2<1)) || (m2 == 9 && (d2>30 || d2<1)) || (m2 == 10 && (d2>31 || d2<1)) || (m2 == 11 && (d2>30 || d2<1)) || (m2 == 12 && (d2>31 || d2<1)) || y2<2000 || m2>12 || m2<1 || y2>y1 || (y1 == y2 && m2>m1) || (y1 == y2 && m1 == m2 && d2>d1)) ... x++; 。这使您的代码不可读并容易出错。

您也没有初始化变量。 d2的起始值未定义。放xint x = 0;

稍后你有:

i = 0;

您可以将其重写为i=0; x=i++; 。但你可能想写x = 1

现在看来你正在检查假期:

x++

这种类型的编码没有错,但它也不实用。我会把假期放在一个结构中:

else if((
    d == 1 && m == 1) || 
    (d == 1 && m == 5) || 
    (d == 8 && m == 5) || 
    (d == 5 && m == 7) || 
    (d == 6 && m == 7) || 
    (d == 28 && m == 9) || 
    (d == 28 && m == 10) || 
    (d == 17 && m == 11) || 
    (d == 24 && m == 12) || 
    (d == 25 && m == 12) || 
    (d == 26 && m == 12) || 

然后遍历struct holidays_t { int day, month; }; struct holidays_t holidays[] = { { 1 , 1 }, { 1 , 5 }, ... }; 数组以查看日期是否匹配。如果您尚未学习结构,则将日期和月份放在两个不同的数组中。例如:

holidays

你的工作日公式错了。你需要解决这个问题。

int holiday_days[]={1,1,...};
int holiday_months[]={1,5,...};