Hi,
I think this new version of the code, will give you what you are looking for,
DATA have;
Length
state $2
city $10
fmtname $7
start 8
label $5
hour 4
minute 4;
INPUT state city fmtname start :date9. label hour minute;
FORMAT start date9. label $5.;
DATALINES;
MD Baltimore sunrise 17Jan2017 07:24 7 24
MD Baltimore sunset 17Jan2017 17:10 17 10
DE Dover sunrise 13JUL2017 04:47 4 47
DE Dover sunset 13JUL2017 19:28 19 28
;
RUN;
/* Sort the Data in preparation for consalidation into single line per state/city/date */
PROC SORT data=have out=have_srtd;
BY state city start label hour;
RUN;
/* --------------------------------------------------------- */
/* The step below will: */
/* - Consolidate data into single record per state/city/date */
/* - Collect numbers & calculate factor for sunrise & sunset */
/* - Output a record for sunrise and record for sunset. */
/* --------------------------------------------------------- */
DATA want(KEEP=state city fmtname start label hour_:);
ARRAY init_hrs [24] _temporary_ (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1);
LENGTH state $2
city $10
fmtname $7
start 8
label $5
hour 4
minute 4;
LENGTH sunrise $5
sunset $5
rise_hr 4
set_hr 4
rise_min 4
set_min 4
rise_factor 8
set_factor 8;
ARRAY hours {24} 4 hour_0-hour_23;
FORMAT hour_: BEST8.4;
RETAIN init_rb8_str hr1_addr sunrise rise_hr set_hr rise_min rise_factor;
IF (_n_ = 1) THEN
DO;
/* Get the String representation of the array elements */
init_rb8_str = put (peekclong (addrlong(init_hrs[1]), 192), $192.);
/* Get the memory address of the first element of the hours array */
hr1_addr = addrlong(hours[1]);
END;
/* - Consolidate data into single record per state/city/date */
/* - Collect numbers & calculate factor for sunrise & sunset */
DO UNTIL (last.start);
SET have_srtd;
BY state city start label hour;
if (lowcase(fmtname)='sunrise') then
do;
/* Process SunRise Time */
sunrise = label;
rise_hr = hour;
rise_min = minute;
rise_factor = rise_min/60;
end;
else
do;
/* Process SunSet Time */
sunset = label;
set_hr = hour;
set_min = minute;
set_factor = set_min/60;
end;
END;
/* ---------------------------------------------------- */
/* - Output a record for sunrise and record for sunset. */
/* ---------------------------------------------------- */
* --- Output the SunRise Record --- ;
fmtname = 'sunrise';
label = sunrise;
/* Set all Hours to 1 in a single command */
CALL POKELONG (init_rb8_str, hr1_addr, 192);
/* Assign the SunRise factor hours */
do i=(rise_hr+2) to (set_hr+1);
hours[i]=rise_factor;
end;
OUTPUT;
* --- Output the SunSet Record --- ;
fmtname = 'sunset';
label = sunset;
/* Reset all Hours to 1 in a single command */
CALL POKELONG (init_rb8_str, hr1_addr, 192);
/* Deals with the hours prior to sunRise */
do i=1 to (rise_hr+1);
hours[i]=set_factor;
end;
/* Deals with the hours after sunSet */
do i=(set_hr+2) to dim(hours);
hours[i]=set_factor;
end;
OUTPUT;
RUN;
DE |
Dover |
sunrise |
13JUL2017 |
04:47 |
1 |
1 |
1 |
1 |
1 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
0.783333 |
1 |
1 |
1 |
1 |
DE |
Dover |
sunset |
13JUL2017 |
19:28 |
0.466666 |
0.466666 |
0.466666 |
0.466666 |
0.466666 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0.466666 |
0.466666 |
0.466666 |
0.466666 |
MD |
Baltimore |
sunrise |
17JAN2017 |
07:24 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0.4 |
0.4 |
0.4 |
0.4 |
0.4 |
0.4 |
0.4 |
0.4 |
0.4 |
0.4 |
1 |
1 |
1 |
1 |
1 |
1 |
MD |
Baltimore |
sunset |
17JAN2017 |
17:10 |
0.166667 |
0.166667 |
0.166667 |
0.166667 |
0.166667 |
0.166667 |
0.166667 |
0.166667 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0.166667 |
0.166667 |
0.166667 |
0.166667 |
0.166667 |
0.166667 |