For example, FOLLOWUP-DATE might need to be a week after SHIPPED-DATE.
With the new $Days function in Suprtool, you can easily generate a date that is N-days before or after any date. You only need to use two Suprtool tasks. The input date can be in any supported format, but the output date will be in yyyymmdd format.
The first task generates the desired date, but it will be in Julianday format. For simplicity, we assume that the file only contains the date, in yyyymmdd X8 format.
>input YOURFILE >def shipped-date,1,8 >item shipped-date,date,yyyymmdd >def jdate,1,4,int >item jdate,date,julianday >ext shipped-date >ext jdate = $days(shipped-date) + 7 >out tmpfile,link >xeqThe second task converts the Julian-format date to yyyymmdd format.
>in tmpfile >def followup-date,1,8,display >item followup-date,date,yyyymmdd >ext shipped-date >ext followup-date = $stddate(jdate) >out result,link >xeqNow you have a self-describing file with the following information
SHIPPED FOLLOWUP 19981231 19980107 19991230 19990106 19990228 19990307
Well, yes there is. The key to this is knowing that Julian Day 0 was a Monday. So if you convert any date to a Juliandays value (via Suprtool's "$days" function), and divide by 7, the modulus would tell you how many days that date is from the previous Monday. So the steps for achieving this are:
purge dtfile purge dtfile2 purge dtfile3 input catalog.pub.sys {input any file with at least 1 record} def lastdate,1,8,display item lastdate,date,yyyymmdd ext lastdate = $date(*/*-1/last) {output the date for last day of last month} num 1 {only need 1 output record} out dtfile,link xeq in dtfile def lastmonday,1,4,int extract lastdate ext lastmonday=($days(lastdate)-($days(lastdate) mod 7)) {calculate juliandays value for the previous Monday} out dtfile2,link xeq in dtfile2 extract 'setvar lastdayoflastmonth,', lastdate {create "setvar" for the last day of previous month} :file dtfile3;rec=-80 out dtfile3,ascii num 2 {leave space for a second record} set squeeze off xeq in dtfile2 {create a "setvar" command for the previous Monday} item lastmonday,date,julianday extract 'setvar previousmonday,' ext lastmonday = $stddate(lastmonday) out dtfile3,ascii,append xeq use dtfile3DTFILE3 now contains 2 setvar commands:
/l dtfile3 1 setvar lastdayoflastmonth,20001231 2 setvar previousmonday, 20001225 3... and the file has been "use"d in Suprtool, so the variables have been set. They can then be referenced further down in the jobstream, as follows:
>set varsub on >if mydate >= !previousmonday and mydate <= !lastdayoflastmonth >verify if IF mydate >= 20001225 and mydate <= 20001231 >Note that the variables will insert the actual numeric values into the IF command, so it will make for efficient data selection. We could reduce the number of passes in the above script to generate an IF command directly, as in:
if $days(mydate) <= {juliandays value of lastdayofmonth} & and $days(mydate) >= {juliandays value of previous monday}... but this would mean that Suprtool would have to calculate the juliandays value for every record read at runtime, so it would be less efficient.
With this conversion, it becomes possible to compare two dates that are not in the same format. And because $stddate puts century and year first, you can reliably do greater-than and less-than comparisons.
$Stddate can be used in two places in Suprtool. In the If command it is used for selecting records based on date criteria. In the Extract command it is used for converting dates to the standard ccyymmdd format.
get shipping-records item order-date, date, mmddyy item date-shipped, date, ddmmyyyy if $stddate(date-shipped) > $stddate(order-date) ...
get shipping-records item order-date, date, mmddyy define converted-date, 1, 8, display extract converted-date = $stddate(order-date) ...If you are creating a self-describing (link) output file, remember to tell Suprtool that the new field is in ccyymmdd format.
item converted-date, date, ccyymmdd output myfile,link xeq
if not $invalid(date-shipped) and & not $invalid(order-date) & and $stddate(date-shipped) > $stddate(order-date)
input db;prompt="Enter the start date yymmdd: " input de;prompt="Enter the end date yymmdd: " setvar dbyy str('!db', 1,2 ) setvar dbmm str('!db', 3,2 ) setvar dbdd str('!db', 5,2 ) setvar deyy str('!de', 7,2 ) setvar demm str('!de', 9,2 ) setvar dedd str('!de', 11,2 ) echo if $stddate(database-date) !>= $date(!dbyy/!dbmm/!dbdd) and & $stddate(database-date) !<= $date(!deyy/!demm/!dedd) >chkdate run suprtool base mybase get mydset use chkdate ext key-value, database-date out result xeq
Before Suprtool can use a date field, it has to know the format of a particular date field. Use the Item command to specify the date format. For example, to tell Suprtool that the item purch-date is a date field with a format of yyyymmdd (e.g., 20010319), you would use:
item purch-date, date, yyyymmdd {date format}The formats supported are wide and varying. Suprtool is able to process virtually all date formats that appear in IMAGE databases. For dates, the date format must be one of the following, combined with a field of a compatible data type:
ASK J1 and K1 Calendar J1 and K1 ddmmyy X6, Z6, J2, K2, and P8 or greater ddmmyyyy X8, Z8, J2, K2, and P10 or greater mmddyy X6, Z6, J2, K2, and P8 or greater mmddyyyy X8, Z8, J2, K2, and P10 or greater Oracle X7 PHdate J1, K1, J2, and K2 yymm X4, Z4, J1, and K1 yymmdd X6, Z6, J2, K2, and P8 or greater yyymmdd J2, P8 yyyymmdd X8, Z8, J2, K2, and P10 or greater ccyymmdd X8, Z8, J2, K2, and P10 or greater ccyymm X6, Z6, J2, K2, and P8 or greater yyyymm X6, Z6, J2, K2, and P8 or greater aammdd X6 aamm X4 mmddaa X6 ddmmaa X6 ccyy X4, Z4, J1, and K1 SRNChronos X6 mmyyyy X6, Z6, J2, K2, and P8 or greater yyddd X5, Z5, J2, K2, and P8 or greater ccyyddd X7, Z7, J2, K2, and P10 or greater HPCalendar J2, K2 EDSDate J2, P8 JulianDay J2 PHdate8 J1, K1, J2, and K2Some of these are quite odd formats used by a single specific application. Check the Suprtool manual for complete definitions of each type. Note: if you are dealing with raw data from a disk file, use the Define command first to tell Suprtool the names, sizes and data types of the fields you need to select, sort or extract. In the following date examples, we show the Item command in each example. In practice, however, you only need to use the Item command once per date field, not once per task.
>get d-sales >item purch-date,date,yyyymmdd >if purch-date = $today {select today's date} >output result >xeqOther tricks with $today
>if purch-date = $today(-1) {yesterday} >if purch-date = $today(+1) {tomorrow}
>get d-sales >item purch-date,date,yyyymmdd >if purch-date = $date(2000/08/12) >output result >xeq
>get d-sales >item purch-date,date,yyyymmdd >if purch-date >= $date(2004/01/01) and & purch-date <= $date(2004/12/31) >output result >xeq
> get invoice-detail > set date cutoff 30 > item invoice-date,date,yymmdd > item close-date,date,mmddyyyy > if $stddate(close-date) <= $stddate(invoice-date) > out badinvs,link > xeqCreate extracts with dates in a CCYYMMDD format from any internal format
> get invoice-detail > item invoice-date,date,hpcalendar > define new-date-8,1,8,display {temp num field} > extract new-date-8 = $stddate(invoice-date) > extract first-field / last-fieldIn this case we define a new numeric data field, new-date-8, to hold the converted invoice-date.
> get invoice-detail > item invoice-date,date,phdate > if $stddate(invoice-date) >= $date(*+2/*/*) {two years from now}
> get invoice-detail > item close-date,date,mmddyyyy > if $stddate(close-date) < $today
> get invoice-detail > item close-date,date,mmddyy > extract first-field / last-field > define new-field,1,8,integer > extract new-field = $stddate(close-date) > output foo,temp,link > xeq > > input foo > sort new-field > extract first-field / last-field > output myfile > xeq
>if field=$date(2000/01/01) {January 1, 2000} >if field=$date(2000-1/01/01) {January 1, 1999} >if field=$date(*-1/01/01) {January 1, last year} >if field=$date(*/*/01) {start of cur year and month} >if field=$date(*/*-18/*) {exactly eighteen months ago} >if field=$date(2001/01/first) {January 1, 2001} >if field=$date(*/*-1/last) {last day of previous month}Combining these features makes it possible to generate batch jobs that require no operator input. For example, to select all of the transactions for last month you would use:
>item trans-date,date,phdate >if trans-date >= $date(*/*-1/first) and & trans-date <= $date(*/*-1/last)
>if $days(SHIP-DATE) - $days(ORDER-DATE) >=30
> define timestamp,1,8 > echo extract timestamp = "!HPTIMEF" > foo > use fooThis will insert an X8 field called "timestamp" into each output record. The timestamp contains the time the data was extracted.
"I am having a field SYSTEM-DATE declared as X(8), which is holding the date in "YY/MM/DD" format (including the "/"s) . I need to code a script to extract data, based on date. Everyday my job has to run to extract data, from today to 7 days before based on the field SYSTEM-DATE. Below is my code. Please let me know, is there any optimized coding for this spec. "
GET LSILM002 DEF YY,SYSTEM-DATE[1],2 DEF MM,SYSTEM-DATE[4],2 DEF DD,SYSTEM-DATE[7],2 EXT DCCODE EXT PRODUCT EXT RECEIPTNO EXT SYSTEM-DATE EXT YY EXT MM EXT DD OUTPUT GRNSIP03,QUERY X INPUT GRNSIP03 DEF DCPRODRECPT,1,18 DEF YYMMDD,47,6 ITEM YYMMDD,DATE,YYMMDD IF ($STDDATE(YYMMDD) >= $TODAY(-7) & AND $STDDATE(YYMMDD) <= $TODAY) EXT DCPRODRECPT EXT SYSTEM-DATE SORT DCPRODRECPT OUTPUT GRNSIP04,QUERY X
input catalog.pub.sys define dt,1,6 item dt,date,YYMMDD extract dt = $today(-7) extract dt = $today output dtfile,temp numrecs 1 xeq input dtfile define fromdateyy,1,2 define fromdatemm,3,2 define fromdatedd,5,2 define todateyy,7,2 define todatemm,9,2 define todatedd,11,2 extract "if SYSTEM-DATE >= '" extract fromdateyy,"/",fromdatemm,"/",fromdatedd,"'" extract " and SYSTEM-DATE <= '" extract todateyy,"/",todatemm,"/",todatedd,"'" output ifcmd xeqThis creates a file called IFCMD that looks like this:
:print ifcmd if SYSTEM-DATE >= '01/06/12' and SYSTEM-DATE <= '01/06/19'You can reference this in your main Suprtool task, just "use ifcmd". This will mean 2 (small) "pre-passes" with 1 record each, rather than 1 "pre-pass" with all the data records, so should run much faster.