Skip to content

Instantly share code, notes, and snippets.

@luelista
Last active August 29, 2015 14:01
Show Gist options
  • Save luelista/4bda8c0c5e08c11d3311 to your computer and use it in GitHub Desktop.
Save luelista/4bda8c0c5e08c11d3311 to your computer and use it in GitHub Desktop.
Workingdays - Calculate the number of business days in a given year
// Workingdays - Calculate the number of business days in a given year
// Copyright (c) 2014 Max Weller
// COMPILE AND RUN:
// $ gcc -o workingdays workingdays.c
// $ ./workingdays -h
// Tested with Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) (x86_64-apple-darwin13.1.0)
// and gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) (x86_64-linux-gnu)
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
// definition of months
#define JAN 0x0
#define FEB 0x1
#define MAR 0x2
#define APR 0x3
#define MAY 0x4
#define JUN 0x5
#define JUL 0x6
#define AUG 0x7
#define SEP 0x8
#define OCT 0x9
#define NOV 0xa
#define DEC 0xb
#define TMOBJ struct tm*
#define DAYSOFYEAR 365
#define IFDAY(myday,d,m) if ((myday->tm_mon == m) && (myday->tm_mday == d))
#define HOLYDAY(d,m,f,n) IFDAY(myday,d,m) MAKEHOLY(d,m,f,n)
#define EASTERDAY(since,f,n) if (march == since) MAKEHOLY(myday->tm_mday,myday->tm_mon,f,n)
#define MAKEHOLY(d,m,f,n) { work[day] = f; if(debug)printf("%02d.%02d.\t%s\n", d, 1+m, n); }
int debug = 0;
float sumdays();
void checkdays(int year);
TMOBJ makemyday(int year, int month, int day);
void nextday(TMOBJ day);
int easter(int X);
int urlaubdays(int year, int start, int jahres);
float work[DAYSOFYEAR];
// format a day of year
char* prnday(int y, int dayofj) {
return asctime(makemyday(y-1900, 0, dayofj));
}
// main entry point
int main(int argc, char** argv) {
time_t t = time(NULL);
TMOBJ now = localtime(&t);
int year = 0;
int ju = -1;
// parse opts
if (argc == 1) year = now->tm_year + 1900;
else if (argc == 2 && strcmp(argv[1], "-c") == 0) { year = now->tm_year + 1900; debug = 1; }
else if (argc == 2) year = atoi(argv[1]);
else if (argc == 3 && strcmp(argv[1], "-c") == 0) { year = atoi(argv[2]); debug = 1; }
else if (argc == 4 && strcmp(argv[1], "-j") == 0) { year = atoi(argv[2]); ju = atoi(argv[3]); }
// show usage
if (year == 0) {
printf("Usage: %1$s [-c] [year]\n\
or %1$s -j year annualVacationDays\n\n\
-c display holiday dates and names\n\
-j calculate maximum free time\n", argv[0]);
return 1;
}
// run calculation
checkdays(year);
printf("%f\n", sumdays());
if (ju > -1) {
int maxu = 0, maxi = 0, i, u;
for(i = 0; i <= DAYSOFYEAR - ju; i++) {
u = urlaubdays(year, i, ju);
if (u > maxu) { maxu = u; maxi = i; }
}
printf("You get the maximum free time of %d days if you start your vacation on %s", maxu, prnday(year, maxi+1));
}
return 0;
}
// count the holidays
float sumdays() {
float sum = 0.0; int i;
for(i = 0; i <= DAYSOFYEAR; i++) sum += work[i];
return sum;
}
// go through year and check holidays
void checkdays(int year) {
int e = easter(year);
year -= 1900;
TMOBJ myday = makemyday(year, 0, 1);
int day = 0, march = 0;
while(myday->tm_year == year) {
if (myday->tm_mon >= MAR) march++;
work[day] = 1.0;
if (myday->tm_wday < 2) work[day] = 0.0;
// definition of fixed holidays
// day month work holiday name
HOLYDAY( 1, JAN, 0.0, "Neujahr");
HOLYDAY( 1, MAY, 0.0, "Maifeiertag");
HOLYDAY( 3, OCT, 0.0, "Tag der Deutschen Einheit");
HOLYDAY( 24, DEC, 0.5, "Heiligabend");
HOLYDAY( 25, DEC, 0.0, "1. Weihnachtsfeiertag");
HOLYDAY( 26, DEC, 0.0, "2. Weihnachtsfeiertag");
// definition of movable holidays dependent on easter sunday
// delta work holiday name
EASTERDAY( e - 2, 0.5, "Karfreitag");
EASTERDAY( e + 1, 0.0, "Ostermontag");
EASTERDAY( e + 39, 0.0, "Christi Himmerfahrt");
EASTERDAY( e + 50, 0.0, "Pfingstmontag");
nextday(myday); day++;
}
}
// return a pointer to a time structure with the given date
TMOBJ makemyday(int year, int month, int day) {
time_t t = time(NULL);
TMOBJ now = localtime(&t);
now->tm_mon = month; now->tm_mday = day; now->tm_year = year;
now->tm_hour = 1; now->tm_min = 0; now->tm_sec = 0;
t = mktime(now);
TMOBJ first = localtime(&t);
return first;
}
// increment a time structure by one day
void nextday(TMOBJ day) {
day->tm_mday++;
time_t mytime = mktime(day);
day = localtime(&mytime);
}
// calculate easter day according to the Gaussian formula
int easter(int X) {
int K = X / 100;
int M = 15 + (3 * K + 3) / 4 - (8 * K + 13) / 25;
int S = 2 - (3 * K + 3) / 4;
int A = X % 19;
int D = (19 * A + M) % 30;
int R = (D + A / 11) / 29;
int OG = 21 + D - R;
int SZ = 7 - (X + X / 4 + S) % 7;
int OE = 7 - (OG - SZ) % 7;
int OS = OG + OE;
return OS;
}
int urlaubdays(int year, int start, int jahres) {
int i; float j = jahres;
for(i = start; i <= DAYSOFYEAR && j > 0; i++) {
j -= work[i];
}
return i - start;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment