home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume6 / pcal < prev    next >
Text File  |  1989-03-21  |  16KB  |  517 lines

  1. Newsgroups: comp.sources.misc
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Message-Id: <8903150107.AA24489@vax1.acs.udel.edu>
  4. Subject: v06i074: calendar program, 1 month per page
  5. Reply-To: THE MASTER <evh@vax1.acs.udel.edu>
  6.  
  7. Posting-number: Volume 6, Issue 74
  8. Submitted-by: THE MASTER <evh@vax1.acs.udel.edu>
  9. Archive-name: pcal
  10.  
  11. #! /bin/sh
  12. # To extract, remove mail header lines and type "sh filename"
  13. echo x - README
  14. sed -e 's/^X//' > README << '!FaR!OuT!'
  15. XTo compile:
  16. X-----------
  17. X
  18. X  cc -o pcal pcal.c
  19. X
  20. X
  21. X
  22. X
  23. X
  24. XInfo on usage etc:
  25. X------------------
  26. X
  27. XI wrote this because I was interested in writing a routine to figure
  28. Xout the day of the week for a specific date(as it ended up, I couldn't
  29. Xget my hands on any algorithm so I got ripped some code from some one's
  30. Xprogram in the archives). Any how I ended up writing this calendar program.
  31. X
  32. X
  33. XI call this program 'pcal' because it it prints out one month per page.
  34. XEach month is separated by control-L type form feed character.
  35. XFor testing, I picked random years and verified them.
  36. XEach month is made up of a grid of 7(width) by 5(height) squares. Any
  37. Xmonth that requires over 5 squares high wil have the the appropriate
  38. Xdays split in half.
  39. X
  40. X
  41. XA typical month looks like.
  42. X
  43. X
  44. X                                      1989
  45. X
  46. X                                     April
  47. X
  48. X    |   SUN   |   MON   |   TUE   |   WED   |   THU   |   FRI   |   SAT   |
  49. X    -----------------------------------------------------------------------
  50. X    |         |         |         |         |         |         | 1|      |
  51. X    |         |         |         |         |         |         |---      |
  52. X    |         |         |         |         |         |         |         |
  53. X    |         |         |         |         |         |         |         |
  54. X    |         |         |         |         |         |         |         |
  55. X    -----------------------------------------------------------------------
  56. X    | 2|      | 3|      | 4|      | 5|      | 6|      | 7|      | 8|      |
  57. X    |---      |---      |---      |---      |---      |---      |---      |
  58. X    |         |         |         |         |         |         |         |
  59. X    |         |         |         |         |         |         |         |
  60. X    |         |         |         |         |         |         |         |
  61. X    -----------------------------------------------------------------------
  62. X    | 9|      |10|      |11|      |12|      |13|      |14|      |15|      |
  63. X    |---      |---      |---      |---      |---      |---      |---      |
  64. X    |         |         |         |         |         |         |         |
  65. X    |         |         |         |         |         |         |         |
  66. X    |         |         |         |         |         |         |         |
  67. X    -----------------------------------------------------------------------
  68. X    |16|      |17|      |18|      |19|      |20|      |21|      |22|      |
  69. X    |---      |---      |---      |---      |---      |---      |---      |
  70. X    |         |         |         |         |         |         |         |
  71. X    |         |         |         |         |         |         |         |
  72. X    |         |         |         |         |         |         |         |
  73. X    -----------------------------------------------------------------------
  74. X    |23|    _/|24|      |25|      |26|      |27|      |28|      |29|      |
  75. X    |---  _/  |---      |---      |---      |---      |---      |---      |
  76. X    |   _/    |         |         |         |         |         |         |
  77. X    | _/   ---|         |         |         |         |         |         |
  78. X    |/     |30|         |         |         |         |         |         |
  79. X    -----------------------------------------------------------------------
  80. X       
  81. X
  82. X
  83. X
  84. XUsage: pcal [-l] [-m startmonth]
  85. X            [-n nummonths] [-u] [-y startyear]
  86. X       startmonth:day of month to start on(1=jan...12=dec)
  87. X       startyear :year to start on(1989=1989, 89=0089)
  88. X                  default startday=1, startmonth=1,
  89. X                  startyear=current year
  90. X       nummonths :#of months to print out(default is 12)
  91. X       -l        :suppress printing of ^L's after each month
  92. X                  default is to print them
  93. X       -u        :print this synopsis
  94. X
  95. X
  96. X
  97. XExamples:
  98. X   Say todays date is March 17, 1989.
  99. X
  100. X
  101. X   pcal   -> print out a 12 month calendar for the year 1989.
  102. X             Each month is printed on a separate page.
  103. X
  104. X   pcal -n 3     ->print out Jan,Feb,March of 1989, each on a separate
  105. X                   page.
  106. X
  107. X   pcal -n 3 -l  ->print out Jan,Feb,March of 1989. Each month is printed
  108. X                   one after another.
  109. X
  110. X   pcal -m 4 -n 1 -> prints out the month of April, 1989 and a form feed.
  111. X
  112. X   pcal -m 4 -y 1992 -n 24 ->prints out months from April, 1992 to 
  113. X                             April, 1994. Each month separated by a control-L.
  114. X
  115. X
  116. XFeel free to make any changes to the code, but leave my name at the top
  117. Xof the code file(s).
  118. X
  119. !FaR!OuT!
  120. echo x - pcal.c
  121. sed -e 's/^X//' > pcal.c << '!FaR!OuT!'
  122. X/*pcal.c                                    Sun Feb 26 23:08:25 EST 1989*/
  123. X
  124. X
  125. X
  126. X/*
  127. X *Contents: One page per month calendar program.
  128. X *
  129. X *Author  : Troy Saville(evh@vax1.acs.udel.edu)
  130. X *
  131. X *Compiling: cc -o pcal pcal.c
  132. X *
  133. X *byebye     - make a clean exit from the program
  134. X *getmmddyy  - get month,day,year of todays date(from the system)
  135. X *isleapyear - determine if year is a leap year
  136. X *jan1       - get day of week for 1st day of a year
  137. X *dayofweek  - get day of week for any day of any year
  138. X *genweek    - driver to print out one week of a month
  139. X *genmonth   - driver to print out a complete month
  140. X *main       - the pcal program
  141. X *
  142. X */
  143. X
  144. X
  145. X
  146. X
  147. X
  148. X
  149. X/*generate a calender, 1 month per page*/
  150. X
  151. X
  152. X#include <stdio.h>
  153. X#include <strings.h>
  154. X#include <time.h>
  155. X
  156. X
  157. X
  158. X/*width of calendar, not including margin*/
  159. X#define NUMWIDTH 71
  160. X/*#of spaces to indent calendar*/
  161. X#define NUMINDENT 4
  162. X
  163. X#define INDENT() printf("%-*.*s",NUMINDENT,NUMINDENT,spaces)
  164. X
  165. X/*check for split sqaure on calendar*/
  166. X#define THESPLIT (weeknum == 5) && (endday < numdays) && (week[i]+7 <= numdays)
  167. X
  168. X
  169. Xstatic char *spaces = "                                                   ";
  170. Xstatic char *dashes = "-------------------------------------------------------------------------------";
  171. X
  172. Xstatic int daysinmonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
  173. X
  174. Xchar *monthnames[] = {"January", "February", "March", "April", "May", "June",
  175. X                      "July", "August", "September", "October", "November",
  176. X                      "December"};
  177. X
  178. Xchar *daynames[] = {"Sun" ,"Mon" ,"Tue" ,"Wed" ,"Thu" ,"Fri" ,"Sat" };
  179. X
  180. X
  181. X/*day of week that first day starts on*/
  182. X#define DAYSTART 0
  183. X
  184. X/*first month to print out*/
  185. X#define MONSTART 0
  186. X
  187. X
  188. X/*exit the program cleanly - display error message*/
  189. Xvoid byebye(fmt,a1,a2,a3,a4,a5,a6,a7)
  190. X   char *fmt;
  191. X   int a1,a2,a3,a4,a5,a6,a7;
  192. X   {
  193. X   if (fmt != NULL)
  194. X      {
  195. X      char tmp[80];
  196. X      sprintf(tmp,fmt,a1,a2,a3,a4,a5,a6,a7);
  197. X      printf(tmp);
  198. X      }
  199. X  
  200. X   printf("\n");
  201. X   printf("Usage: pcal [-l] [-m startmonth]\n");
  202. X   printf("            [-n nummonths] [-u] [-y startyear]\n");
  203. X   printf("       startmonth:day of month to start on(1=jan...12=dec)\n");
  204. X   printf("       startyear :year to start on(1989=1989, 89=0089)\n");
  205. X   printf("                  default startday=1, startmonth=1,\n");
  206. X   printf("                  startyear=current year\n");
  207. X   printf("       nummonths :#of months to print out(default is 12)\n");
  208. X   printf("       -l        :suppress printing of ^L's after each month\n");
  209. X   printf("                  default is to print them\n");
  210. X   printf("       -u        :print this synopsis\n");
  211. X
  212. X   exit(0);
  213. X   }
  214. X
  215. X
  216. X
  217. X/*get month,day,year of today date, year=89(mean actual year is 1989*/
  218. Xvoid getmmddyy(month,day,year)
  219. X   int *month, *day, *year;
  220. X   {
  221. X   long clockval,time();
  222. X   struct tm *dateinfo,*localtime();
  223. X
  224. X   clockval = time((long *) 0);
  225. X
  226. X   dateinfo = localtime(&clockval);
  227. X   if (month)
  228. X     *month = dateinfo->tm_mon+1;
  229. X   if (day)
  230. X      *day = dateinfo->tm_mday;
  231. X   if (year)
  232. X      *year = dateinfo->tm_year;
  233. X   }
  234. X
  235. X
  236. X
  237. X
  238. X/******************************************************************************
  239. X *isleapyear                                     Tue Oct 25, 1988 -> 21:42:56
  240. X *
  241. X *returns 1 if 'year' is a leap year else returns 0.
  242. X *1988 should be passed as 1988 and not 88.
  243. X */
  244. Xint isleapyear(year)
  245. X   int year;
  246. X   {
  247. X   return((!(year % 4)) && (year % 100) ? 1 : 0);
  248. X   }
  249. X
  250. X
  251. X/*Return day of the week for Jan 1 of the specified year.*/
  252. X/*0=sunday....6=saturday*/
  253. X/*I ripped this out of someone elses program*/
  254. X/*author unknown*/
  255. Xint jan1(year)
  256. X   int year;
  257. X   {
  258. X   int day;
  259. X
  260. X   day = year + 4 + ((year + 3) / 4);     /* Julian Calendar      */
  261. X   if (year > 1800)                       /* If it's recent, do   */
  262. X      {
  263. X      day -= ((year - 1701) / 100);       /* Clavian correction   */
  264. X      day += ((year - 1601) / 400);       /* Gregorian correction */
  265. X      }
  266. X    if (year > 1752)                      /* Adjust for Gregorian */
  267. X      day += 3;                           /* calendar             */
  268. X
  269. X   return (day % 7);
  270. X   }
  271. X
  272. X
  273. X
  274. X
  275. X/*return day of the week for the date passed in*/
  276. X/*month = 0-11, day is 1 based, year is assumed to be 4 digits*/
  277. X/*RETURN:0= sunday.....6=saturday*/
  278. Xint dayofweek(month,day,year)
  279. X   int month,day,year;
  280. X   {
  281. X   int i;
  282. X   int dow = (-1);
  283. X
  284. X   dow += day + jan1(year);
  285. X
  286. X   for(i=0;i < month;i++)
  287. X      dow += daysinmonth[i] + ((i == 1) * isleapyear(year));
  288. X
  289. X   return(dow % 7);
  290. X   }
  291. X
  292. X
  293. X/************************************************************************
  294. X *genweek                                    Mon Feb 27 00:46:16 EST 1989
  295. X * - generate calander for 1 week
  296. X */
  297. Xvoid genweek(week,weeknum,startday,daysinweek,numdays)
  298. X   int week[];     /*#of each day of week to be generated*/
  299. X   int weeknum;    /*week # for current month*/
  300. X   int startday;   /*starting day 
  301. X   int daysinweek; /*last day to be generated*/
  302. X   int numdays;    /*#days in month*/
  303. X   {
  304. X   int i;
  305. X   int row;
  306. X   int endday;
  307. X
  308. X   if (weeknum > 5)
  309. X      return;
  310. X
  311. X   endday = startday + daysinweek - 1;
  312. X
  313. X
  314. X   for(row=0;row < 5;row++)
  315. X      {
  316. X      INDENT();
  317. X      printf("|");
  318. X
  319. X      for(i=0;i< 7;i++)
  320. X         {
  321. X         /*see if day of the week contains a day for this month*/
  322. X         if (week[i])
  323. X            switch(row)
  324. X               {
  325. X               case 0:
  326. X                  printf("%2d|    %s",week[i],
  327. X                         (THESPLIT) ? "_/" : "  ");
  328. X                  break;
  329. X
  330. X               case 1:
  331. X                  printf("---  %s  ",(THESPLIT) ? "_/" : "  ");
  332. X                  break;
  333. X
  334. X               case 2:
  335. X                  printf("   %s    ",(THESPLIT) ? "_/" : "  ");
  336. X                  break;
  337. X
  338. X               case 3:
  339. X                  printf(" %s",(THESPLIT) ? "_/   ---" : "        ");
  340. X                  break;
  341. X
  342. X               case 4:
  343. X                  if (THESPLIT)
  344. X                     printf("/     |%2d",week[i]+7);
  345. X                  else
  346. X                     printf("         ");
  347. X                  break;
  348. X               }
  349. X         else /*this day of the week is in last month or next month*/
  350. X            printf("%-9.9s",spaces);
  351. X         printf("|");
  352. X         }
  353. X
  354. X      printf("\n");
  355. X      }
  356. X
  357. X   INDENT();
  358. X   printf("%-*.*s\n", NUMWIDTH, NUMWIDTH,dashes);
  359. X   }
  360. X
  361. X
  362. X
  363. X/************************************************************************
  364. X *genmonth                                   Sun Feb 26 23:21:30 EST 1989
  365. X * - generate calander for 1 month
  366. X */
  367. Xvoid genmonth(month,year)
  368. X   int month;
  369. X   int year;
  370. X   {
  371. X   int i,j,k;
  372. X   int startday; /*day of week 1st day starts on*/
  373. X   int numdays;  /*#days in month*/
  374. X   int dow;      /*dat of week*/
  375. X   int weeknum = 1; /*# of the current week to print*/
  376. X   int week[7];
  377. X
  378. X   i = (80 - strlen(monthnames[month])) / 2;
  379. X
  380. X   printf("%-*.*s%-s\n\n",i,i,spaces,monthnames[month]);
  381. X
  382. X   numdays = daysinmonth[month] + ((month==1) * isleapyear(year));
  383. X
  384. X   startday = dayofweek(month,1,year);
  385. X
  386. X   INDENT();
  387. X   printf("|   SUN   |   MON   |   TUE   |   WED   |   THU   |   FRI   |   SAT   |\n");
  388. X   INDENT();
  389. X   printf("%-*.*s\n", NUMWIDTH, NUMWIDTH,dashes);
  390. X
  391. X   /*figure out first row*/
  392. X   /*first row of calander*/
  393. X   for(i=0,j=0;i < 7;i++)
  394. X      if (i >= startday)
  395. X         week[i] = ++j;
  396. X      else
  397. X         week[i] = 0;
  398. X
  399. X   /*generate row for one week of calendar*/
  400. X   i = 7 - startday;
  401. X   genweek(week,weeknum,1,i,numdays);
  402. X
  403. X   /*rest of calendar*/
  404. X   for(k=0; i < numdays;i += k,k=0)
  405. X      {
  406. X      for(j=0;j < 7;j++)
  407. X         if ((i+k) < numdays)
  408. X            week[j] = ++k + i;
  409. X         else
  410. X            week[j] = 0;
  411. X      if (k)
  412. X         genweek(week,++weeknum,i+1,k,numdays);
  413. X      }
  414. X   }
  415. X
  416. X
  417. X
  418. X/**************************************************************************
  419. X *main 
  420. X * - main program
  421. X *
  422. X */
  423. Xmain(argc,argv)
  424. X   int argc;
  425. X   char *argv[];
  426. X   {
  427. X   int i,j;
  428. X   int curmonth = 1;   /*current month of year*/
  429. X   int curyear;        /*current year*/
  430. X   int numday;         /*#of the day of the week*/
  431. X   int nummonths = 12; /*#of months to print out*/
  432. X   int controll = 0;   /*suppress printing of control L's 0=no, 1=yes*/
  433. X
  434. X
  435. X   /*set defaults*/
  436. X   getmmddyy(0,0,&curyear);
  437. X   curyear += 1900;
  438. X
  439. X   /*parse command line args*/
  440. X   for(i=1;i<argc;i++)
  441. X      {
  442. X      if (argv[i][0] == '-')
  443. X         switch(argv[i][1])
  444. X            {
  445. X            case 'm': /*day # of the week to start calander on*/
  446. X               if (++i == argc)
  447. X                  byebye("-m requires integer arguement");
  448. X               else if ( (sscanf(argv[i],"%d", &curmonth) != 1) ||
  449. X                         (curmonth < 1) || (curmonth > 12) )
  450. X                  byebye("Bad arg '%s' for -m flag\n", argv[i]);
  451. X               break;
  452. X
  453. X            case 'n': /*#of months to print*/
  454. X               if (++i == argc)
  455. X                  byebye("-n requires integer arguement");
  456. X               else if ( (sscanf(argv[i],"%d", &nummonths) != 1) ||
  457. X                         (nummonths < 1) )
  458. X                  byebye("Bad arg '%s' for -n flag\n", argv[i]);
  459. X               break;
  460. X
  461. X            case 'y': /*day # of the week to start calander on*/
  462. X               if (++i == argc)
  463. X                  byebye("-y requires integer arguement");
  464. X               else if (sscanf(argv[i],"%d", &curyear) != 1)
  465. X                  byebye("Bad arg '%s' for -y flag\n", argv[i]);
  466. X               break;
  467. X
  468. X            case 'l': /*suppress ^L's*/
  469. X               controll = 1;
  470. X               break;
  471. X
  472. X            case 'u': /*usage*/
  473. X               byebye(0);
  474. X               break;
  475. X
  476. X            default: 
  477. X               byebye("Bad command line arguement: %s",argv[i]);
  478. X               break;
  479. X            }
  480. X      else
  481. X         byebye("Bad command line arguement: %s",argv[i]);
  482. X      }
  483. X
  484. X   curmonth--;
  485. X
  486. X
  487. X   /*loop through months*/
  488. X   for(;nummonths > 0;nummonths--, curmonth++)
  489. X      {
  490. X      if (curmonth == 12)
  491. X         {
  492. X         curmonth = 0;
  493. X         curyear++;
  494. X         }
  495. X
  496. X      printf("\n\n\n%-*.*s%-4d\n\n",38,38,spaces,curyear);
  497. X
  498. X      genmonth(curmonth,curyear);
  499. X
  500. X      if (!controll)
  501. X         printf("        \n"); /*form feed to next page*/
  502. X      }
  503. X
  504. X
  505. X   }
  506. X
  507. X
  508. X
  509. X
  510. X
  511. X
  512. X
  513. !FaR!OuT!
  514. exit
  515.  
  516.  
  517.