home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume06 / pcal < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  15.3 KB

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