get next working day

i want to get next working day from give date, that is other than Saturday or Sunday.
suppose given date is 26-DEC-2008 (i.e Friday) then i should get 29-DEC-2008 as next working day(i.e Monday). how code this in C. do we have any calendar API in C. please help me out.
thanks and regards

man 2 time
man 3 localtime

Include <time.h>, get the current time (time(2)), increase once by 86400 (next day), feed it to localtime(3) and check if 0<struct tm.tm_wday<6 (Mon-Fri is 1-5). If it's not in that range, increase by 86400 until it is.

thanks for help.
but i want in other way. i have function
computeBsnsDate(start date, no_of_days,next_bsns_date);

i want to pass startdate say "26-DEC-2008 and no_of_days as 1
so i have to get return date as "29-DEC-2008"

do i have to use getdate();

can ny1 tell how? please
thanks

Feed you character array to strptime(3), the resulting struct tm to mktime, the resulting time_t to localtime, and test that result until struct tm.tm_wday indicates a workday. Then convert it to a character array and return that.

Here is some code which does what you are looking to do

/*
**
**      USAGE: nextworkday [-d] date
**
**                       -d turn on debugging
**
**       INPUT:  Date as DD-MMM-YYYY
**
**    OUTPUT:  Prints next working day as DD-MMM-YYYY
**
**   EXAMPLE: nextworkday 30-DEC-2008
**
*/

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

#define IFORMAT "%d-%b-%Y %H:%M:%S"
#define OFORMAT "%d-%b-%Y"

int
main(int argc, char* argv[])
{
   int c, debug = 0, errflg= 0;
   char buf[50];
   char date[80];
   char format[50];
   struct tm tm1;
   time_t t1;

   extern char *optarg;
   extern int optind, optopt;

   while ((c = getopt(argc, argv, "dh")) != -1) {
        switch(c) {
        case 'd':
            debug = 1;
            break;
        case 'h':
            errflg++;
            break;
        case '?':
            fprintf(stderr, "Unknown option: -%c\n", optopt);
            errflg++;
        }
   }
   if (errflg || (argc - optind != 1)) {
       fprintf(stderr, "Usage: nextworkday [-d] date\n");
       exit(2);
   }

   strcpy(date, argv[optind]);
    /* to ensure tm is populated with something decent */
   strcat(date, " 08:00:00");
   strcpy(format, IFORMAT);

   if (debug) {
       fprintf(stderr, "  DATE STR: %s\n", date);
   }

   if (!strptime(date, format, &tm1)) {
       fprintf(stderr, "strptime() error\n");
       exit(1);
   }

   if (debug) {
       fprintf(stderr, "BEFORE DoM: %d\n", tm1.tm_mday);
       fprintf(stderr, "     Month: %d\n", tm1.tm_mon);
       fprintf(stderr, "      Year: %d\n", tm1.tm_year);
       fprintf(stderr, "       DoW: %d\n", tm1.tm_wday);
   }

   if (tm1.tm_wday < 5)
      tm1.tm_mday = tm1.tm_mday + 1;
   else
      tm1.tm_mday = tm1.tm_mday + (8 - tm1.tm_wday);

   if (debug)
       fprintf(stderr, "   NEW DoM: %d\n", tm1.tm_mday);

   /* hack to fix up the time structure - see man page */
   if ((t1 = mktime(&tm1)) == -1) {
      fprintf(stderr, "mktime() error\n");
      exit(1);
   }

   if (debug) {
       fprintf(stderr, "AFTER  DoM: %d\n", tm1.tm_mday);
       fprintf(stderr, "     Month: %d\n", tm1.tm_mon);
       fprintf(stderr, "      Year: %d\n", tm1.tm_year);
       fprintf(stderr, "       DoW: %d\n", tm1.tm_wday);
   }

   if (strftime(buf,sizeof(buf), OFORMAT, &tm1) == 0) {
      fprintf(stderr, "strftime() error\n");
      exit(1);
   }

   printf("%s\n", buf);

   exit(0);

}

thanks a lot :slight_smile:
it solved my problem.

fpmurphy gave you a very reasonable response based on your requirements.

I work in calendrics a lot, and the requirements you stated for the
definition of a "business day" were either very naive, or for a country
I have never done work for. In most places there are a lot of other
considerations as to what the definition of a "business day" is.

One reason is because the requirment doesn't take holidays and religious
observances into account. Holidays are never trivial, they are often
very local and often based on a distinctly non-Gregorian lunar
calculation. So there is no general method presented very often.

The other issue is that programmers think they "know" calendars
because they grew up with them, but may not know what calendars really do..
Even for the Gregorian calendar. Read the langinfo man page. Look at
the output of

 cal 9 1752

Do you know why September seems wrong?
And if you live in France that output of cal is wrong.

Holidays --
One way is parse a tztab-like file, then write code: maybe a "isholiday(struct
tm *)" function to parse the table the against a given date:

The E-2 entry is a paschal lunar easter algorithm for western Easter
(as opposed to Orthodox Easter) - the entry above returns two days
before Easter. Lunar holidays and very important religious observances
usually require special algorithms.

The table also deals with moving holidays onto work days, like observing
July 4th (a US holiday) on July 5 or on July 3 because July 4 is on a weekend.

i done some modifications for considering holidays also(i.e local holiday).
also you can get nth working day from given day.
if holiday list is stored in table, you can build hash table on it instead of array of holiday. hash table will give lots of performance gain also


#include <stdio.h>
#include <stdlib.h>
#include<time.h>


#define OFORMAT "%Y-%m-%d"

//char holidy_list[][12]={"01-Jan-2004","03-Jan-2004","04-Jan-2004","10-Jan-2004","11-Jan-2004","17-Jan-2004","18-Jan-2004"};

char holidy_list[][12]={"2004-01-01","2004-01-03","2004-01-04","2004-01-10","2004-01-11","2004-01-17","2004-01-18"};

int main(void)
{
   struct tm xmas, *tm1;
   time_t tt;

   int flg=0,i,found=0;

   char date[] = "2003-12-31";
   char buf[12];



  int no_of_days =1;  // nth working day 
  int  count =0;

   if (strptime(date, "%Y-%m-%d", &xmas) == NULL)
   {
      printf("strptime() failed.\n");
      exit(1);
   }


    tt = mktime(&xmas);
    tm1 = localtime(&tt);
    strftime(buf,sizeof(buf), OFORMAT, tm1);
    printf("\nOld Date is <%s>\n",buf);

 for(;;)
 {
    tt= tt-86400;
    tm1 = localtime(&tt);
    strftime(buf,sizeof(buf), OFORMAT, tm1);

    //printf("\nbuf<%s>  count<%d>",buf,count);
    found=0;
    if (tm1->tm_wday==0 || tm1->tm_wday ==6)
    {
         continue;
    }

    if(HashGet(buf))
     { found = 1;}

    if(found ==0)
     {
        count ++;
        if (count >= no_of_days)  break;

     }

     //printf("\nbuf<%s> hldlst<%s> count<%d>",buf,holidy_list,count);

  }

  for( i = 0; buf[ i ]; i++)
    buf[ i ] = toupper( buf[ i ] );
  printf( "\nNew Date is <%s>\n",buf);
}


int HashGet(char buf[])
{
    int i;
    for(i=0;i< (sizeof(holidy_list)/sizeof("30-DEC-2008"));i++)
    {
      if (strncasecmp(holidy_list,buf,sizeof(buf))==0)
        { return 1; break;}
    }
    return 0;
}

Anup13, I would follow the approach suggested by jim mcnamara and use an external holiday file. Otherwise you are going to have to modify your source code every year instead of just updating the holiday file.

I agree, something like SourceForge.net: xml-holidays home would work great for this.

ya, i know using file is much more good thing. i kept array in my program just for testing purpose. actually in our case we have holiday table stored in database. before this code we build holiday has table based on some parameter for that year and next year. in in code instead of searching in arry of holiday, i do search in HASH table. its very fast search.
so i don't need to change code every year.