Advertisement
jalih

Calculate calendar week number in PL/I

Jun 3rd, 2012
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.11 KB | None | 0 0
  1. *PROCESS MARGINS(1, 140);
  2.  
  3. test: proc options (main);
  4. dcl 1 date_type based,
  5. 2 day pic'99',
  6. 2 month pic'99',
  7. 2 year pic'9999';
  8.  
  9. dcl d like date_type;
  10.  
  11. /* fill date structure */
  12. d.day = '01';
  13. d.month = '01';
  14. d.year = '2012';
  15.  
  16. /* test our proggy */
  17. put skip list (trim(week(d)));
  18.  
  19. /**************************************************************************************************************************************/
  20. (STRINGRANGE, SUBSCRIPTRANGE):
  21. week: proc (day) returns (fixed bin (31));
  22. dcl day like date_type;
  23.  
  24. dcl (from, to) like date_type;
  25. dcl (days_from, days_to) fixed bin (31);
  26. dcl total_days fixed bin (31);
  27. dcl week_index fixed bin (31);
  28. dcl weeknro fixed bin (31);
  29. dcl result bit (*) aligned controlled;
  30. dcl weeks (7) bit (7) aligned nonasgn init ('0100000'b, '0010000'b, '0001000'b, '0000100'b, '0000100'b, '0000010'b, '0000001'b);
  31. dcl masks (7) bit (7) aligned nonasgn init ('0111100'b, '1111000'b, '1110001'b, '1100011'b, '1000111'b, '0001111'b, '0011110'b);
  32. dcl bool bit (1);
  33.  
  34. dcl (days, weekday, tally, substr, lbound, hbound, copy, omitted) builtin;
  35.  
  36. /* we start from first of january, naturally */
  37. from.day = '01';
  38. from.month = '01';
  39. from.year = day.year;
  40.  
  41. to = day;
  42.  
  43. days_from = days(string(from), 'DDMMYYYY');
  44. days_to = days(string(to), 'DDMMYYYY');
  45.  
  46. /* calculate required length for the bit string */
  47. total_days = days_to - days_from + 1;
  48. if total_days <= 0 then return (0);
  49.  
  50. /* allocate bit string, holding date range */
  51. allocate result bit (total_days);
  52.  
  53. /* fill bit string with correct rotation of the week pattern */
  54. week_index = weekday(days_from);
  55. result = copy(weeks(week_index), total_days / 7) || substr(weeks(week_index), 1, mod(total_days, 7));
  56.  
  57. /* find the number of weeks starting on monday */
  58. weeknro = tally(result, '1'b);
  59.  
  60. /* free allocated storage */
  61. free result;
  62.  
  63. /* first week can be partial and if it includes thursday, then add it to the result */
  64. bool = substr(masks(week_index), 1, 1);
  65. If bool then weeknro += 1;
  66.  
  67. /* maybe first days of the year belong to week numbering of the previous year? */
  68. if weeknro <= 0 then
  69. do;
  70. from.year -= 1;
  71. to = from;
  72. to.day = '31';
  73. to.month = '12';
  74.  
  75. days_from = days(string(from), 'DDMMYYYY');
  76. days_to = days(string(to), 'DDMMYYYY');
  77.  
  78. total_days = days_to - days_from + 1;
  79. if total_days <= 0 then return (0);
  80.  
  81. allocate result bit (total_days);
  82.  
  83. week_index = weekday(days_from);
  84. result = copy(weeks(week_index), total_days / 7) || substr(weeks(week_index), 1, mod(total_days, 7));
  85.  
  86. weeknro = tally(result, '1'b);
  87. free result;
  88. end;
  89. return (weeknro);
  90. end week;
  91. /**************************************************************************************************************************************/
  92. end test;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement