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

  1. From decwrl!ogicse!uwm.edu!cs.utexas.edu!uunet!allbery Sat Mar  3 18:29:02 PST 1990
  2. Article 1356 of comp.sources.misc:
  3. Path: decwrl!ogicse!uwm.edu!cs.utexas.edu!uunet!allbery
  4. From: marcel@duteca.tudelft.nl (Marcel Mol)
  5. Newsgroups: comp.sources.misc
  6. Subject: v10i084: new version of weekday
  7. Message-ID: <79986@uunet.UU.NET>
  8. Date: 27 Feb 90 02:54:57 GMT
  9. Sender: allbery@uunet.UU.NET
  10. Organization: Delft University of Technology, Dep. of Electrotechnical engineering.
  11. Lines: 755
  12. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  13. Posted: Mon Feb 26 18:54:57 1990
  14.  
  15. Posting-number: Volume 10, Issue 84
  16. Submitted-by: marcel@duteca.tudelft.nl (Marcel Mol)
  17. Archive-name: weekday
  18.  
  19. [Shar, please!!!  ++bsa]
  20.  
  21. This version of weekday repairs some bugs and adds the ISO date standard as
  22. date input format. (The diffs were almost as large as the source so I send out
  23. the soure).
  24.  
  25. -Marcel
  26.  
  27. ------------------------- Cut here ---------------------------------------
  28. #! /bin/sh
  29. # This file was wrapped with "dummyshar".  "sh" this file to extract.
  30. # Contents:  weekday.c
  31. echo extracting 'weekday.c'
  32. if test -f 'weekday.c' -a -z "$1"; then echo Not overwriting 'weekday.c'; else
  33. sed 's/^X//' << \EOF > 'weekday.c'
  34. X/* @(#) weekday.c       3.40 02/06/90  */
  35. X/*************************************************************************
  36. X **                                                                     **
  37. X **  Name    :  weekday                                                 **
  38. X **  Author  :  Marcel J.E. Mol                                         **
  39. X **  Date    :  12/28/89              (first release)                   **
  40. X **  Version :  3.40                                                    **
  41. X **  Files   :  weekday.c       Main source file                        **
  42. X **                                                                     **
  43. X **  ------------------------- Revision List -------------------------  **
  44. X **  Ver   Date       Name                   Remarks                    **
  45. X **  3.40  02/06/90   Marcel Mol    Added ISO date standard YYYY-MM-DD  **
  46. X **                              Suggested by mathew smm12@cl.cam.ac.uk **
  47. X **  3.33  02/04/90   Marcel Mol    Fixed bug when entering years in    **
  48. X **                                 0 <= year <= 99 with leading '0'    **
  49. X **  3.32  02/01/90   Marcel Mol    Fixed typos in January February     **
  50. X **                                 October                             **
  51. X **  3.31  01/09/90   Marcel Mol    Removed unnecessary code.           **
  52. X **                                 Added comments.                     **
  53. X **  3.30  01/08/90   Marcel Mol    Improved option handling.           **
  54. X **                                 verbose works on more options.      **
  55. X **                                 use printf field length option to   **
  56. X **                                 get short day and month names.      **
  57. X **  3.26  01/07/90   Marcel Mol    Filled in usage function.           **
  58. X **  3.25  01/04/90   Marcel Mol    Use 'today' when no date is given.  **
  59. X **  3.20  01/03/90   Marcel Mol    Allow bsd `date` as input.          **
  60. X **  3.11  01/03/90   Marcel Mol    Documentation, typos, checkdate().  **
  61. X **                                 Removed redundant checks.           **
  62. X **  3.10  01/02/90   Marcel Mol    Added -s and -v options.            **
  63. X **                                 allow yy.ddd input and implement    **
  64. X **                                 julian date conversion.             **
  65. X **  3.00  12/30/89   Marcel Mol    Set up user interface.              **
  66. X **                                 Allow mm/dd/yy and dd-mm-yy input.  **
  67. X **                                 Options to print different parts.   **
  68. X **  2.10  12/28/89   Marcel Mol    Added Julianday.                    **
  69. X **  2.00  12/27/89   Marcel Mol    Made weekday and weeknr everlasting.**
  70. X **  1.00  12/26/89   Marcel Mol    First release.                      **
  71. X **                                 Set up algorithms weekday weeknr.   **
  72. X **  =================================================================  **
  73. X **                                                                     **
  74. X **  Compile as follows: cc weekday.c -Oso weekday                      **
  75. X **                                                                     **
  76. X **  Usage: weekday [-svdDmMywjnah] [<date>]                            **
  77. X **                                                                     **
  78. X **         Weekday outputs line on which it informs you about several  **
  79. X **         thing of the given <date>.                                  **
  80. X **         The <date> input may be in several formats:                 **
  81. X **                                                                     **
  82. X **             mm/dd/yy      e.g.   10/30/89    or 1/2/510             **
  83. X **             dd-mm-yy      e.g.   30-10-89    or 2-1-510             **
  84. X **             yyyy-mm-dd    e.g. 1989-10-30    or 0510-1-2            **
  85. X **             yy.ddd        e.g.   89.303      or 510.2               **
  86. X **             `date` output e.g.   Mon Oct 30 99:99:99 1989           **
  87. X **                                                                     **
  88. X **         If no date argument is given, weekday uses the system date. **
  89. X **         The yyyy-mm-dd date format must have 4 digits for the yyyy  **
  90. X **         part, 2 for the mm part and 2 for the dd part; it's just    **
  91. X **         the ISO date standard. (undocumented feature: it also works **
  92. X **         if the mm and/or dd part is only one digit long.)           **
  93. X **         So the following trick does not apply to this date format:  **
  94. X **         When the year number is less than 100 and the string        **
  95. X **         forming the year does not start with a 0, the year is       **
  96. X **         converted to be in the current century. So 10/30/89 is      **
  97. X **         actually 10/30/1989. If the real year 89 is wanted specify  **
  98. X **         it as 10/30/089. (the current century is a constant in the  **
  99. X **         source code. If this programs survives 1999 this constant   **
  100. X **         must be changed, and the program recompiled.)               **
  101. X **         Note: make sure that `date` output is passed as one         **
  102. X **         argument, so enclose it with "s.                            **
  103. X **                                                                     **
  104. X **         The output, when no options are given, is something like    **
  105. X **         this:                                                       **
  106. X **                                                                     **
  107. X **         30 October 1989 is on a Monday on julian day 303 in week 44 **
  108. X **                                                                     **
  109. X **         or:                                                         **
  110. X **                                                                     **
  111. X **         2 January 510 is on a Friday on julian day 2 in week 1      **
  112. X **                                                                     **
  113. X **         Depending on the options the output changes:                **
  114. X **                                                                     **
  115. X **           -s toggle short form output: Monday -> Mon, June -> Jun   **
  116. X **              and vice versa.                                        **
  117. X **           -v toggle verbose output; removes 'is on a' etc.          **
  118. X **              and vice versa.                                        **
  119. X **           -d prints day of week number: 1 is Monday, 7 is Sunday    **
  120. X **           -D gives day of week name, i.e Monday or Mon              **
  121. X **           -m prints the month number                                **
  122. X **           -M outputs the month name, i.e. January or Jan            **
  123. X **           -y outputs the year number                                **
  124. X **           -w gives the week number                                  **
  125. X **           -j outputs the julian day number                          **
  126. X **           -n gives day of month                                     **
  127. X **           -a gives everything it knows. Without the -s and -v       **
  128. X **              options this outputs the same as the default case.     **
  129. X **              In fact -a is just short for -nmyDjw.                  ** 
  130. X **           -h give a usage message                                   **
  131. X **                                                                     **
  132. X **         With the verbose option on, each printing option speaks to  **
  133. X **         you in a more or less english way.                          **
  134. X **         All options that print something also print a space         **
  135. X **         character (except -a).                                      **
  136. X **         The options may come in any order and as many times as      **
  137. X **         you like. The -s and -v options only have an effect on the  **
  138. X **         options that follow them.                                   **
  139. X **         When now option is given (except for the -v and -s option)  **
  140. X **         the -a option is default.                                   **
  141. X **         The output is ended with a newline                          **
  142. X **         Examples:                                                   **
  143. X **                                                                     **
  144. X **           % weekday  -yjMdD 12/31/89                                **
  145. X **           89 365 December 7 Sunday                                  **
  146. X **                                                                     **
  147. X **           % weekday  -yjMsdD 12/31/89                               **
  148. X **           89 365 December 7 Sun                                     **
  149. X **                                                                     **
  150. X **           % weekday  -yjsMsdD 12/31/89                              **
  151. X **           89 365 Dec 7 Sunday                                       **
  152. X **                                                                     **
  153. X **           % weekday  -v 30/30/89                                    **
  154. X **           30 Oct 1989 is on a Mon on julian day 303 in week 44      **
  155. X **                                                                     **
  156. X **   BUGS: the program assumes there have always been leap years       **
  157. X **         so year 4 is a leap year as far as the program can tell...  **
  158. X **                                                                     **
  159. X **   This software is copyrighted (c) 1989 1990 by M.J.E. Mol.         **
  160. X **   This code or part of this code may be used by freeware,           **
  161. X **   public domain or any other non-commercial product. I only ask     **
  162. X **   you to give me credit for the used code in the documentation      **
  163. X **   and in your source code.                                          **
  164. X **                                                                     **
  165. X **   If you want to use this code or part of this code in your         **
  166. X **   shareware or any other commercial product, I ask you to contact   **
  167. X **   me so we can setup an arrangement for the use of the code or part **
  168. X **   of the code.                                                      **
  169. X **                                                                     **
  170. X **   In any case, I can not be held responsible for any damage this    **
  171. X **   code or part of this code may cause you or anyone or anything     **
  172. X **   else.                                                             **
  173. X **                                                                     **
  174. X **   Mail bugs to: email: marcel@duteca.tudelft.nl                     **
  175. X **                 pmail: Marcel J.E. Mol                              **
  176. X **                        Karel Doormanlaan 58                         **
  177. X **                        2283AT Rijswijk                              **
  178. X **                        The Netherlands (Holland)                    **
  179. X **                 Phone: (+31) 070-3932390                            **
  180. X **                 Bankaccount: 36.89.35.922 (In the Netherlands)      **
  181. X **                                                                     **
  182. X ************************************************************************/
  183. X
  184. Xchar * copyright = "@(#) weekday.c  3.40 02/06/90  (c) M.J.E. Mol";
  185. X
  186. X#include <stdio.h>
  187. X#include <string.h>
  188. X#include <time.h>
  189. X
  190. X
  191. X#define CENTURY     1900                             /* prefix for years */
  192. X#define LEAP(year)  ((year%4 == 0) && (year%100 != 0) || (year%400 == 0)) 
  193. X
  194. X/*
  195. X * Global variables
  196. X */
  197. X
  198. Xchar *weekdays[8]   = {"", "Monday", "Tuesday", "Wednesday", "Thursday",
  199. X                           "Friday", "Saterday", "Sunday"};
  200. Xchar  days[13]      = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  201. Xint   juldays[13]   = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
  202. Xchar *monthname[13] = {"", "January", "February", "March", "April",
  203. X                           "May", "June", "July", "August",
  204. X                           "September", "October", "November", "December"};
  205. X
  206. Xint shortflag = 0;                  /* short output of day and month name */
  207. Xint verbose   = 1;                  /* output in a 'sentence' */
  208. Xchar * progname;
  209. X
  210. X
  211. X/*
  212. X * function declarations
  213. X */
  214. Xvoid main();
  215. Xvoid scanmmddyy();
  216. Xvoid scanyyyymmdd();
  217. Xvoid scanddmmyy();
  218. Xint  scanjul();
  219. Xint  scandate();
  220. Xint  julianday();
  221. Xvoid julian2day();
  222. Xint  weekday();
  223. Xint  weeknr();
  224. Xvoid checkdate();
  225. Xvoid usage();
  226. X
  227. X
  228. Xvoid main(argc, argv)
  229. Xint argc;
  230. Xchar **argv;
  231. X{
  232. X    int year, month, day, week;
  233. X    int wday = -1;
  234. X    int jday = -1;
  235. X    int opt, haveopt;
  236. X    char *date;
  237. X    extern int optind;                  /* For getopt */
  238. X    extern char * optarg;               /* For getopt */
  239. X
  240. X    progname = *argv;
  241. X    date = argv[argc-1];
  242. X
  243. X    /*
  244. X     * pick up the date argument and scan it
  245. X     */
  246. X    if (*date == '-' || argc == 1)                   /* no date, take current */
  247. X        wday = scandate(NULL, &year, &month, &day);
  248. X    else if (strchr(date, '/') != NULL)              /* mm/dd/yy format date */
  249. X        scanmmddyy(date, &year, &month, &day);
  250. X    else if (strchr(date, '-') == date+4)            /* yyyy-mm-dd format    */
  251. X        scanyyyymmdd(date, &year, &month, &day);
  252. X    else if (strchr(date, '-') != NULL)              /* dd-mm-yy format date */
  253. X        scanddmmyy(date, &year, &month, &day);
  254. X    else if (strchr(date, '.') != NULL)              /* yyyy.ddd format date */
  255. X        jday = scanjulian(date, &year, &month, &day);
  256. X    else                                           /* unix date output format */
  257. X        wday = scandate(date, &year, &month, &day);
  258. X
  259. X    /*
  260. X     * get missing data
  261. X     */
  262. X    if (jday == -1)
  263. X        jday = julianday(year, month, day);
  264. X    if (wday == -1)
  265. X        wday = weekday(year, month, day);
  266. X    week = weeknr(year, month, day);
  267. X
  268. X
  269. X    /*
  270. X     * print the wanted stuff ...
  271. X     */
  272. X    while ((opt = getopt(argc, argv, "svdDmMywjnah")) != EOF) {
  273. X        switch (opt) {
  274. X            case 's' : shortflag ^=  1;
  275. X                       break;
  276. X            case 'v' : verbose ^= 1;
  277. X                       break;
  278. X            case 'D' : printf("%s%.*s ",
  279. X                                   verbose ? "is on a " : "",
  280. X                                   shortflag ? 3 : 9 , weekdays[wday]);
  281. X                       haveopt = 1;
  282. X                       break;
  283. X            case 'd' : printf("%s%d ", verbose ? "is weekday " : "", wday);
  284. X                       haveopt = 1;
  285. X                       break;
  286. X            case 'm' : printf("%d ", month);
  287. X                       haveopt = 1;
  288. X                       break;
  289. X            case 'M' : printf("%.*s ", shortflag ? 3 : 9, monthname[month]);
  290. X                       haveopt = 1;
  291. X                       break;
  292. X            case 'y' : printf("%d ", year);
  293. X                       haveopt = 1;
  294. X                       break;
  295. X            case 'w' : printf("%s%d ", verbose ? "in week " : "", week);
  296. X                       haveopt = 1;
  297. X                       break;
  298. X            case 'j' : printf("%s%d ", verbose ? "on julian day " : "", jday);
  299. X                       haveopt = 1;
  300. X                       break;
  301. X            case 'n' : printf("%d ", day);
  302. X                       haveopt = 1;
  303. X                       break;
  304. X            case 'a' : if (verbose) {
  305. X                           printf("%d %.*s %d is on a %.*s ",
  306. X                                  day,  shortflag ? 3 : 9, monthname[month],
  307. X                                  year, shortflag ? 3 : 9, weekdays[wday]);
  308. X                           printf("on julian day %d in week %d", jday, week);
  309. X                       }
  310. X                       else
  311. X                           printf("%d %.*s %d %.*s %d %d",
  312. X                                  day,  shortflag ? 3 : 9, monthname[month],
  313. X                                  year, shortflag ? 3 : 9, weekdays[wday],
  314. X                                  jday, week);
  315. X                       haveopt = 1;
  316. X                       break;
  317. X            case 'h' : usage();
  318. X                       break;
  319. X            default  : fprintf(stderr,
  320. X                               "%s: use -h option for help\n", progname);
  321. X                       exit(1);
  322. X                       break;
  323. X        }
  324. X    }
  325. X
  326. X
  327. X    if (!haveopt) {
  328. X        if (verbose) {
  329. X            printf("%d %.*s %d is on a %.*s ",
  330. X                   day,  shortflag ? 3 : 9, monthname[month],
  331. X                   year, shortflag ? 3 : 9, weekdays[wday]);
  332. X            printf("on julian day %d in week %d", jday, week);
  333. X        }
  334. X        else
  335. X            printf("%d %.*s %d %.*s %d %d",
  336. X                   day,  shortflag ? 3 : 9, monthname[month],
  337. X                   year, shortflag ? 3 : 9, weekdays[wday],
  338. X                   jday, week);
  339. X    }
  340. X
  341. X    /*
  342. X     * finish with a newline
  343. X     */
  344. X    putchar('\n');
  345. X
  346. X    exit(0);
  347. X
  348. X} /* main */
  349. X /*************************************************************************
  350. X **                                                                     **
  351. X **                    DATE SCANNING ROUTINES                           **
  352. X **                                                                     **
  353. X *************************************************************************/
  354. X
  355. X/*
  356. X * scanmmddyy --- scan the date variable in the form MM/DD/YY.
  357. X *                MM, DD and YY may be variable sized numbers.
  358. X *                output is in output variables year, month and day.
  359. X */
  360. Xvoid scanmmddyy(date, year, month, day)
  361. Xchar *date;
  362. Xint *year, *month, *day;
  363. X{
  364. X    char *i;
  365. X
  366. X    if (sscanf(date, "%d/%d/%d", month, day, year) != 3 ||
  367. X        *month <= 0 || *day <= 0 || *year < 0) {
  368. X        fprintf(stderr, "%s: error in mm/dd/yy format date %s\n",
  369. X                        progname, date);
  370. X        exit(4);
  371. X    }
  372. X
  373. X    if (*year < 100) {
  374. X        i = strrchr(date, '/') + 1;
  375. X        if (*i != '0')
  376. X           *year += CENTURY;
  377. X    }
  378. X
  379. X    return;
  380. X
  381. X} /* scanmmddyy */
  382. X
  383. X
  384. X
  385. X/*
  386. X * scanyyyymmdd --- scan the date variable in the form YYYY-MM-DD.
  387. X *                YYYY, MM and DD must be 4, 2 and 2 digits wide.
  388. X *                output is in output variables year, month and day.
  389. X */
  390. Xvoid scanyyyymmdd(date, year, month, day)
  391. Xchar *date;
  392. Xint *year, *month, *day;
  393. X{
  394. X
  395. X    if (sscanf(date, "%4d-%2d-%2d", year, month, day) != 3 ||
  396. X        *month <= 0 || *day <= 0 || *year < 0) {
  397. X        fprintf(stderr, "%s: error in yyyy-mm-dd format date %s\n",
  398. X                        progname, date);
  399. X        exit(4);
  400. X    }
  401. X
  402. X    return;
  403. X
  404. X} /* scanyyyymmdd */
  405. X
  406. X
  407. X/*
  408. X * scanddmmyy --- scan the date variable in the form DD-MM-YY.
  409. X *                Also YYYY-MM-DD is recognized if YYYY > 31 and DD <= 31.
  410. X *                DD, MM and YY may be variable sized numbers.
  411. X *                output is in output variables year, month and day.
  412. X */
  413. Xvoid scanddmmyy(date, year, month, day)
  414. Xchar *date;
  415. Xint *year, *month, *day;
  416. X{
  417. X    char *i;
  418. X
  419. X    if (sscanf(date, "%d-%d-%d", day, month, year) != 3 ||
  420. X        *month <= 0 || *day <= 0 || *year < 0) {
  421. X        fprintf(stderr, "%s: error in dd-mm-yy format date %s\n",
  422. X                        progname, date);
  423. X        exit(4);
  424. X    }
  425. X
  426. X    if (*year < 100) {
  427. X        i = strrchr(date, '-') + 1;
  428. X        if (*i != '0')
  429. X           *year += CENTURY;
  430. X    }
  431. X
  432. X    return;
  433. X
  434. X} /* scanddmmyy */
  435. X
  436. X
  437. X
  438. X/*
  439. X * scanjulian --- scan the date variable in the form YY.DDD.
  440. X *                YY and DDD may be variable sized numbers.
  441. X *                output is in output variables year, month and day.
  442. X *                the return value is tha actual julian day DDD.
  443. X */
  444. Xint scanjulian(date, year, month, day)
  445. Xchar *date;
  446. Xint *year, *month, *day;
  447. X{
  448. X    int jday;
  449. X
  450. X    if (sscanf(date, "%d.%d", year, &jday) != 2 || *year < 0 || jday <= 0) {
  451. X        fprintf(stderr, "%s: error in julian date %s\n", progname, date);
  452. X        exit(4);
  453. X    }
  454. X
  455. X    if ((*year < 100) && (*date != '0'))
  456. X        *year += CENTURY;
  457. X    julian2day(*year, jday, month, day);
  458. X
  459. X    return jday;
  460. X
  461. X} /* scanjulian */
  462. X
  463. X
  464. X
  465. X/*
  466. X * scandate --- scan the date variable in the Unix `date` form.
  467. X *              This can look like: "Mon Jan 8 20:10:10 MET 1990"
  468. X *              or:                 "Mon Jan 8 20:10:10 1990"
  469. X *              the number of spaces between the fields is not fixed
  470. X *              (although date output is always in  the same with, see ctime(3).
  471. X *              output is in output variables year, month and day.
  472. X *              the return value is the day of the week number.
  473. X *              If the date input is the NULL pointer, the xurrent system date
  474. X *              is taken.
  475. X */
  476. Xint scandate(date, year, month, day)
  477. Xchar *date;
  478. Xint *year, *month, *day;
  479. X{
  480. X    char *i;
  481. X    char dayname[4];
  482. X    char monname[10];
  483. X    int j, k;
  484. X    long tim;
  485. X
  486. X    if (date == NULL) {
  487. X        tim = time((long *) 0);
  488. X        date= ctime(&tim);
  489. X    }
  490. X
  491. X    if (sscanf(date, "%3s %3s %d %*s %d",      /* date without time zone */
  492. X                     dayname, monname, day, year) != 4 &&
  493. X        sscanf(date, "%3s %3s %d %*s %*s %d", /* date with time zone */
  494. X                     dayname, monname, day, year) != 4) {
  495. X        fprintf(stderr, "%s: error in unix `date` format date %s\n",
  496. X                        progname, date);
  497. X        exit(4);
  498. X    }
  499. X
  500. X    for(j=1; j<12; j++) {
  501. X        if (strncmp(monname, monthname[j], 3) == NULL)
  502. X            break;
  503. X    }
  504. X    if (strncmp(monname, monthname[j], 3) != NULL) {
  505. X        fprintf(stderr, "%s: error in unix `date` format date %s\n",
  506. X                        progname, date);
  507. X        exit(4);
  508. X    }
  509. X    *month = j;
  510. X    for(j=1; j<7; j++) {
  511. X        if (strncmp(dayname, weekdays[j], 3) == NULL)
  512. X            break;
  513. X    }
  514. X    if (strncmp(dayname, weekdays[j], 3) != NULL) {
  515. X        fprintf(stderr, "%s: error in unix `date` format date %s\n",
  516. X                        progname, date);
  517. X        exit(4);
  518. X    }
  519. X
  520. X    return j;
  521. X
  522. X} /* scandate */
  523. X /*************************************************************************
  524. X **                                                                     **
  525. X **                    DATE CONVERSION ROUTINES                         **
  526. X **                                                                     **
  527. X *************************************************************************/
  528. X
  529. X
  530. X
  531. X/* 
  532. X * julian2day -- converts year and julian day value to the corresponding 
  533. X *               month and day of the month values for that year.
  534. X *               these values are returned in the ouput variables month and day.
  535. X */
  536. Xvoid julian2day(year, jday, month, day)
  537. Xint year, jday;
  538. Xint *month, *day;
  539. X{
  540. X    int leap;
  541. X
  542. X    leap = LEAP(year) ? 1 : 0;
  543. X    if (jday > 365+leap || jday <= 0) {
  544. X        fprintf(stderr, "%s: error in julian date %d.%d\n",
  545. X                        progname, year, jday);
  546. X       exit(8);
  547. X    }
  548. X
  549. X    if (jday <= 31) {
  550. X        *month = 1;
  551. X        *day = jday;
  552. X        return;
  553. X    }
  554. X
  555. X    jday -= leap;
  556. X    if (jday <= 59) {
  557. X        *month = 2;
  558. X        *day = jday - 31 + leap;
  559. X    }
  560. X    else if (jday <= 90) {
  561. X        *month = 3;
  562. X        *day = jday - 59;
  563. X    }
  564. X    else if (jday <= 120) {
  565. X        *month = 4;
  566. X        *day = jday - 90;
  567. X    }
  568. X    else if (jday <= 151) {
  569. X        *month = 5;
  570. X        *day = jday - 120;
  571. X    }
  572. X    else if (jday <= 181) {
  573. X        *month = 6;
  574. X        *day = jday - 151;
  575. X    }
  576. X    else if (jday <= 212) {
  577. X        *month = 7;
  578. X        *day = jday - 181;
  579. X    }
  580. X    else if (jday <= 243) {
  581. X        *month = 8;
  582. X        *day = jday - 212;
  583. X    }
  584. X    else if (jday <= 273) {
  585. X        *month = 9;
  586. X        *day = jday - 243;
  587. X    }
  588. X    else if (jday <= 304) {
  589. X        *month = 10;
  590. X        *day = jday - 273;
  591. X    }
  592. X    else if (jday <= 334) {
  593. X        *month = 11;
  594. X        *day = jday - 304;
  595. X    }
  596. X    else {
  597. X        *month = 12;
  598. X        *day = jday - 334;
  599. X    }
  600. X
  601. X    return;
  602. X
  603. X} /* julian2day */
  604. X
  605. X
  606. X
  607. X/* 
  608. X * julianday -- converts a year, mont and day value the corresponding julian
  609. X *              day number of that year.
  610. X *              the julian day is passed as a return value.
  611. X */
  612. Xjulianday(year, month, day)
  613. Xint year, month, day;
  614. X{
  615. X    register int doy;
  616. X
  617. X    checkdate(year, month, day);           /* exits if date in error */
  618. X    doy = juldays[month];
  619. X    if ((month > 2) && LEAP(year)) 
  620. X        doy++;
  621. X    doy += day;
  622. X
  623. X    return doy;
  624. X
  625. X} /* julianday */
  626. X
  627. X
  628. X
  629. X/*
  630. X * weekday -- returns the day of the week number based on the given
  631. X *            year, month and day of the month value.
  632. X */
  633. Xweekday(year, month, day)
  634. Xint year, month, day;
  635. X{
  636. X    register int dow;
  637. X
  638. X    checkdate(year, month, day);           /* exits if date in error */
  639. X    dow = 6 +                             /* the magic number */
  640. X          year +                          /* shift a day each year */
  641. X          year/4 - year/100 + year/400 +  /* shift a day each leap year */
  642. X          juldays[month] + day;           /* day of year */
  643. X
  644. X    if ((month < 3) && LEAP(year))        /* first two months of leap don't */
  645. X        dow--;                            /* have the extra leap shift      */
  646. X
  647. X    dow %= 7;
  648. X    return (dow == 0) ? 7 : dow;          /* convert 0 to 7 */
  649. X
  650. X} /* weekday */
  651. X
  652. X
  653. X/*
  654. X * weeknr -- returns the weeknumber of the given date (year, month and day of
  655. X *           the month) for that year.
  656. X */
  657. Xweeknr(year, month, day)
  658. Xint year, month, day;
  659. X{
  660. X    register int fday, jul, weeknum;
  661. X
  662. X    checkdate(year, month, day);           /* exits if date in error */
  663. X
  664. X    fday = weekday(year, 1, 1);
  665. X
  666. X    jul = julianday(year, month, day);
  667. X    weeknum = (jul + fday - 2)/7;
  668. X    if (fday <= 4)
  669. X        weeknum++;
  670. X
  671. X    if (weeknum == 0)                      /* go into previous year           */
  672. X        if ((fday == 5) ||                 /* week 1 has 4 or 5 days and week */
  673. X           ((fday == 6) && LEAP(year-1)) ) /*    53 has 4 or 5 days in year-1 */
  674. X            return 53;
  675. X        else
  676. X            return 52;
  677. X
  678. X    if (weeknum == 53) {                  /* only a week 53 if we have > 4   */
  679. X        fday = weekday(year, 12, 31);     /*     days in the week            */
  680. X        if (fday < 4)
  681. X           weeknum = 1;
  682. X    }
  683. X
  684. X    return weeknum;
  685. X
  686. X} /* weeknr */
  687. X /*************************************************************************
  688. X **                                                                     **
  689. X **                         OTHER  ROUTINES                             **
  690. X **                                                                     **
  691. X *************************************************************************/
  692. X
  693. X
  694. X
  695. X/*
  696. X * checkdate -- checks if the given date is a valid one.
  697. X *              if not, it just exits.
  698. X */
  699. Xvoid checkdate(year, month, day)
  700. Xint year, month, day;
  701. X{
  702. X    int dim;
  703. X
  704. X    if (year < 0) {
  705. X        fprintf(stderr, "%s: %d is an invalid year\n", progname, year);
  706. X        exit(2);
  707. X    }
  708. X    if ((month < 1) || (month > 12)) {
  709. X        fprintf(stderr, "%s: %d is an invalid month\n", progname, month);
  710. X        exit(2);
  711. X    }
  712. X    dim = days[month];
  713. X    if ((month == 2) && LEAP(year)) 
  714. X        dim++;
  715. X    if ((day > dim) || (day < 1)) {
  716. X        fprintf(stderr, "%s: %d is an invalid day in %s %d\n", progname,
  717. X                         day, monthname[month], year);
  718. X        exit(2);
  719. X    }
  720. X
  721. X   return;
  722. X
  723. X} /* checkdate */
  724. X
  725. X
  726. X
  727. X/*
  728. X * usage -- give usage message.
  729. X */
  730. Xvoid usage()
  731. X{
  732. X
  733. X    fprintf(stderr,"Usage: weekday [-svdDmMywjnah] [<date>]\n"); 
  734. X    fprintf(stderr,"   <date>: mm/dd/yy  |  dd-mm-yy  |  yyyy-mm-dd\n  |");
  735. X    fprintf(stderr,"           yy.ddd  |  Unix date\n");
  736. X    fprintf(stderr,"   default is today\n");
  737. X    fprintf(stderr,"   options: -s toggle short form output\n");
  738. X    fprintf(stderr,"            -v toggle verbose output\n");
  739. X    fprintf(stderr,"            -d prints day of week number\n");
  740. X    fprintf(stderr,"            -D gives day of week name\n");
  741. X    fprintf(stderr,"            -m prints the month number\n");
  742. X    fprintf(stderr,"            -M outputs the month name\n");
  743. X    fprintf(stderr,"            -y outputs the year number\n");
  744. X    fprintf(stderr,"            -w gives the week number\n");
  745. X    fprintf(stderr,"            -j outputs the julian day number\n");
  746. X    fprintf(stderr,"            -n gives day of month\n");
  747. X    fprintf(stderr,"            -a gives everything it knows (default)\n");
  748. X    fprintf(stderr,"            -h give a usage message\n");
  749. X
  750. X    return;
  751. X
  752. X} /* usage */
  753. EOF
  754. chars=`wc -c < 'weekday.c'`
  755. if test $chars !=    27998; then echo 'weekday.c' is $chars characters, should be    27998 characters!; fi
  756. fi
  757. exit 0
  758. -- 
  759. #########################################
  760. # Marcel J.E. Mol                       ######################################
  761. # Delft University of Technology          Pink Elephant Management Services  #
  762. # The Netherlands                         Voorburg                           #
  763. # UUCP: marcel@duteca.tudelft.nl          Tel: 070-694231                    #
  764. #                                          ######################################
  765. #########################################
  766.  
  767.  
  768.