How to compute custom timestamp in COBOL85 Tandem? - tandem

I want to calculate timestamp for custom date and time.
E.g 23/09/2022 4:30:45

To calculate Julian Timestamp of current date and time you can use JULIANTIMESTAMP using ENTER TAL but for Custom timestamp we have COMPUTETIMESTAMP GPC .
Syntax from GPC Reference manual
jval := COMPUTETIMESTAMP ( date-n-time,
[error-mask] );
Data types
jval is 64-bit Fixed Julian timestamp .
date-n-time is an integer array of date and time [YYYY,MM,DD,HH,,MM,SS,MIL,MIC] all elements of array are compulsory.
error-mask is integer array of bits 1 or 0 of length 8.
So let's Jump to the main Question how to Calculate Custom timestamp in COBOL85 . I have small example .
?ANSI
?save param
?symbols
?inspect
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 USER-FLD-CUST PIC X(50).
01 ARR.
03 DT PIC S9(4) COMP OCCURS 8 TIMES.
01 VAL PIC 9(16).
01 JTIME PIC S9(18) VALUE 0.
01 CER.
03 ERR PIC S9(1) COMP OCCURS 8 TIMES.
PROCEDURE DIVISION.
PROGRAM-BEGIN.
MOVE 2022 TO DT(1).
MOVE 99 TO DT(2).
MOVE 30 TO DT(3).
MOVE 10 TO DT(4).
MOVE 00 TO DT(5).
MOVE 00 TO DT(6).
MOVE 000 TO DT(7).
MOVE 000 TO DT(8).
ENTER TAL "COMPUTETIMESTAMP" USING ARR , CER
GIVING JTIME.
IF JTIME = -1
DISPLAY "INVALID DATE"
ELSE
DISPLAY JTIME.
STOP RUN.

Related

COBOL: File status 39 error

here is my cobol code. i have the testinput.txt in my cobol folder. I compiled it and it has no errors but when i try to run it,
there's a message that says
RCL0002: File status 39 on < unopened-file >
Error detected at offset 0046 in segment 00 of program TEST
IDENTIFICATION DIVISION.
PROGRAM-ID. transactionIN.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-PC.
OBJECT-COMPUTER. IBM-PC.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFILE ASSIGN TO 'testinput.txt'.
SELECT OUTFILE ASSIGN TO 'testoutput'.
DATA DIVISION.
FILE SECTION.
FD INFILE
LABEL RECORD IS STANDARD
DATA RECORD IS INREC.
01 INREC.
02 AC PIC X(99).
FD OUTFILE
LABEL RECORD IS OMITTED
DATA RECORD IS OUTREC.
01 OUTREC.
02 FILLER PIC X(80).
WORKING-STORAGE SECTION.
01 HEAD-1.
02 FILLER PIC X(32) VALUE SPACES.
02 FILLER PIC X(16) VALUE 'China Trust Bank'.
02 FILLER PIC X(32) VALUE SPACES.
01 HEAD-2.
02 FILLER PIC X(34) VALUE SPACES.
02 FILLER PIC X(13) VALUE 'Makati Avenue'.
02 FILLER PIC X(33) VALUE SPACES.
01 HEAD-3.
02 FILLER PIC X(35) VALUE SPACES.
02 FILLER PIC X(12) VALUE 'Makati City'.
02 FILLER PIC X(34) VALUE SPACES.
01 HEAD-4.
02 FILLER PIC X(33) VALUE SPACES.
02 FILLER PIC X(14) VALUE 'Account Report'.
02 FILLER PIC X(33) VALUE SPACES.
01 SUB-1.
02 FILLER PIC X(20) VALUE SPACES.
02 FILLER PIC X(7) VALUE 'Account'.
02 FILLER PIC X(10) VALUE SPACES.
02 FILLER PIC X(7) VALUE 'Account'.
02 FILLER PIC X(9) VALUE SPACES.
02 FILLER PIC X(7) VALUE 'Balance'.
02 FILLER PIC X(20) VALUE SPACES.
01 SUB-2.
02 FILLER PIC X(20) VALUE SPACES.
02 FILLER PIC X(6) VALUE 'Number'.
02 FILLER PIC X(12) VALUE SPACES.
02 FILLER PIC X(4) VALUE 'Name'.
02 FILLER PIC X(10) VALUE SPACES.
02 FILLER PIC X(18) VALUE SPACES.
SCREEN SECTION.
01 SCRE.
02 BLANK SCREEN.
PROCEDURE DIVISION.
MAIN-RTN.
PERFORM INIT-RTN THRU INIT-RTN-END.
PERFORM FINISH-RTN.
STOP RUN.
INIT-RTN.
OPEN INPUT INFILE, OUTPUT OUTFILE.
READ INFILE AT END PERFORM END-RTN
GO TO INIT-RTN-END.
PERFORM HEADING-RTN.
INIT-RTN-END.
END-RTN.
DISPLAY 'EMPTY FILE' LINE 3 COLUMN 20.
HEADING-RTN.
WRITE OUTREC FROM HEAD-1 AFTER PAGE.
WRITE OUTREC FROM HEAD-2 AFTER 1.
WRITE OUTREC FROM HEAD-3 AFTER 1.
WRITE OUTREC FROM HEAD-4 AFTER 3.
WRITE OUTREC FROM SUB-1 AFTER 2.
WRITE OUTREC FROM SUB-2 AFTER 1.
PROCESS-RTN.
DISPLAY SCRE.
FINISH-RTN.
CLOSE INFILE, OUTFILE.
DISPLAY 'TAPOS NA' LINE 6 COLUMN 20.
The FILE STATUS 39 means that there is a difference between what you have told COBOL about the file and what COBOL has discovered whilst attempting to OPEN it.
For the file you have defined in COBOL, the data must be exactly 99 bytes long. If you have 99 bytes per record, followed by one (or more) delimiters, then you'd need to extend the length of INREC to 100 or 101 bytes.
You may want to see if your compiler (from the error message it seems to be CA-Realia) supports LINE SEQUENTIAL files. This particular file-type understands delimited records, and the delimiters will be stripped before being presented to your program.
The simplest file-processing program in COBOL follows this outline:
OPEN files
READ input until end
process input, WRITE output
CLOSE files
That read-loop will typically be one of two forms:
PERFORM until some-flag-shows-end-of-file
READ input-file
AT END
make end-of-file-flag show "end of file"
NOT AT END
do some processing
END-READ
END-PERFORM
READ input-file ("priming read")
PERFORM until FILE STATUS field shows end-of-file
do some processing
READ input-file
END-PERFORM
The second is, to my mind, much simpler and less error-prone. It requires that the FILE STATUS is used on the SELECT for the file. This really should always be done for all files so that you can check after each IO that the IO didn't behave unexpectedly. Separate FILE STATUS field for each file.
Here's your program re-arranged. At the moment, it only reads one record (or none if end-of-file is returned immediately) but that is what you coded.
PROCEDURE DIVISION.
PERFORM INIT-RTN
PERFORM PROCESS-FILE
PERFORM END-RTN
PERFORM FINISH-RTN
STOP RUN
.
INIT-RTN.
OPEN INPUT INFILE
check file status
OPEN OUTPUT OUTFILE
check file status
PERFORM HEADING-RTN
.
PROCESS-FILE.
READ INFILE
check file status
.
END-RTN.
DISPLAY 'EMPTY FILE' LINE 3 COLUMN 20
.
HEADING-RTN.
WRITE OUTREC FROM HEAD-1 AFTER PAGE
check file status
WRITE OUTREC FROM HEAD-2 AFTER 1
check file status
WRITE OUTREC FROM HEAD-3 AFTER 1
check file status
WRITE OUTREC FROM HEAD-4 AFTER 3
check file status
WRITE OUTREC FROM SUB-1 AFTER 2
check file status
WRITE OUTREC FROM SUB-2 AFTER 1
check file status
.
PROCESS-RTN.
DISPLAY SCRE
.
FINISH-RTN.
CLOSE INFILE
check file status
CLOSE OUTFILE
check file status
DISPLAY 'TAPOS NA' LINE 6 COLUMN 20
.
So, check on FILE STATUS, LINE SEQUENTIAL, change your file (or program definition of it). Build from there.
You may think the FILE STATUS checking of the report lines will look large and ugly. You can do them like this, instead:
MOVE HEAD-1 TO OUTREC
PERFORM WRITE-OUTREC-AFTER-PAGE (other neater ways to do it later)
Where WRITE-OUTREC has the WRITE and the test of the FILE STATUS field.

How to read Date from VB binary-file in another language?

I get a binary file from a VB-application which consists of about 1400 records of a Timestamp in Date format followed by 19 Long values.
I am able to read the data in VBA with this function:
Dim myDate As Date
Dim myLong As Long
iFileNum = FreeFile
Open "C:\test.bin" For Binary Access Read As #iFileNum
Do While Not EOF(iFileNum)
Get iFileNum, , myDate
MsgBox(myDate)
For i = 1 To 19
Get iFileNum, , myLong
Next i
Loop
Now i want to read the Date-timestamps from the file (I am already able to read the Long-values) within java, but i cannot find any information on how to interpret the 8 bytes of the Date-type.
As an example, the first timestamp in binary form is c5 b3 a2 11 80 7b e4 40.
VB output for this is 2014-11-05 0:03:06 AM.
To clarify, I am not looking for a java implementation, but for information of the binary representation of data type 'Date' from VB.
(for which i wasn't able to find any more information as than this http://msdn.microsoft.com/en-us/library/3eaydw6e.aspx , which doesn't help much)
As #RBarryYoung mentions in his comment to the question, VBA stores Date/Time values internally as floating-point Double values. The integer part is the number of days since 1899-12-30 and the fractional part is the time (e.g., 0.25 = 6 AM, 0.5 = Noon, 0.75 = 6 PM).
In the example you gave, the Date/Time (Double) value is stored in bytes as c5 b3 a2 11 80 7b e4 40. Windows has always been a little-endian environment, so by reversing the order of the bytes we know that it corresponds to the 64-bit binary value 0x40e47b8011a2b3c5.
A Binary-to-IEEE_Double convertor like this one tells us that the decimal Double value is 4.19480021527777789742685854435E4, and if we ask VBA what the corresponding Date/Time value is we get
?CDate(41948.0021527777789742685854435)
2014-11-05 00:03:06

COBOL data buffering without moving character by character

I am reading a variable length input file and wanting to create an output buffer (indexed table) that will not utilize a character by character move.
For example: my first input record is 79 characters, I can then move this to my group level of the table. My second input record is 101 characters -- how can I take these 101 characters and place them in my table beginning at position 80 for a length of 101 ? And the next input record beginning at position 180.....etc. We currently Perform Varying 1 by 1 but this is incredibly CPU intensive compared to a block move to a beginning address.
We do this millions of times a day and a solution would be quite useful.
Use reference modification with the length from your record. Consider:
01 Record
05 Rec-LL Pic S9(4) Binary.
05 Rec-Data Pic X(32767).
01 Tgt-Area Pic X(10000000).
01 Curr-Ptr Pic S9(8) Binary.
Once you read your record, you can move based on the length like so:
Move 1 to Curr-Ptr
Perform Get-Next-Record
Perform until no-more-data
Move Rec-Data (1:Rec-LL) to Tgt-Area (curr-ptr:rec-LL)
Compute Curr-Ptr = Curr-Ptr + Rec-LL
Perform Get-Next-Record
End-Perform
Or the old fashioned ( we are talking COBOL here so old fashioned = Jurassic) way:-
01 Record.
05 REC-LL PIC S9(4) Binary.
05 REC-DATA.
10 REC-BYTES PIC X OCCURS 32767 times depending on REC-LL.
01 TARGET-AREA.
05 TARGET-HEADER PIC X(79).
05 TARGET-REC PIC X(101) OCCURS 50 TIMES.
01 TGT-INDEX PIC S9(8) BINARY VALUE 1.
* Length calculation happens by magic!
Perform Read-Record.
move REC-DATA TO TARGET-HEADER.
perform until no-more-data
Perform Read-Record
move REC-DATA to TARGET-RED(TGT-INDEX)
add +1 to TGT-INDEX
end-perform
Or if records really vary between 1 and 101 bytes:
01 Record.
05 REC-LL PIC S9(4) Binary.
05 REC-DATA.
10 REC-BYTES PIC X OCCURS 32767 times depending on REC-LL.
01 TARGET-AREA.
05 TGT-LL PIC s9(8) BINARY.
05 TGT-REC.
10 TGX-BYTE OCCURS 3175 depending on TGT-LL.
05 TGT-EXTRA PIC X(101).
Perform Read-Record.
Move +0 to tgt-LL.
perform until no-more-data
MOVE REC-DATE to TGT-EXTRA
ADD REC-LL TO TGT-LL
Perform Read-Record
add +1 to TGT-INDEX
end-perform
Take a look at the STRING INTO verb, in particular the WITH POINTER clause. Don't forget the ON OVERFLOW imperative when stringing things together like this.
For details, grab a copy of Gary Cutler's OpenCOBOL Programmer's Guide.
http://opencobol.add1tocobol.com/OpenCOBOL%20Programmers%20Guide.pdf
This is a world class COBOL manual, and it's an open and free document (GNU FDL).

Need help with a syntax error (COBOL)

I am working on my last homework assignment for COBOL this semester and I am being hit with a syntax error that is stopping my progress cold. Here is what I got:
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT USED-CAR-FILE-OUT
ASSIGN TO 'USED-CAR.RPT'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD USED-CAR-FILE-OUT.
01 USED-CAR-RECORD-OUT PIC X(80).
WORKING-STORAGE SECTION.
01 ID-CODE PIC X(3).
01 TOTAL-CASH-PAYMENT PIC 9(5).
01 MONTHLY-PAYMENT PIC 9(4).
01 NUMBER-OF-MONTHS PIC 9(3).
01 BALANCE-TOTAL PIC S9(6)V99 VALUE ZEROS.
01 INTEREST-EARNED PIC S99V99 VALUE ZEROS.
01 COMPARE-MONTH PIC 99 VALUE ZEROS.
01 YEAR-NUMBER PIC 99 VALUE ZEROS.
01 MONTH-NUMBER PIC 99 VALUE ZEROS.
01 DETAIL-LINE.
05 ID-CODE-DL PIC X(3).
05 PIC X(3) VALUE SPACES.
05 PIC X(4) VALUE 'Yr='.
05 YEAR-NUMBER-DL PIC Z9 VALUE ZEROS.
05 PIC X(4) VALUE SPACES.
05 PIC X(4) VALUE 'Mo='.
05 MONTH-NUMBER-DL PIC Z9.
05 PIC X(4) VALUE SPACES.
05 PIC X(5) VALUE 'Pmt='.
05 PAYMENT-DL PIC $$$,$$$.
05 PIC X(4) VALUE SPACES.
05 PIC X(5) VALUE 'Int='.
05 INTEREST-EARNED-DL PIC $$$$.99.
05 PIC X(3) VALUE SPACES.
05 PIC X(5) VALUE 'Bal='.
05 BALANCE-DL PIC $$$,$$$.99.
PROCEDURE DIVISION.
100-MAIN.
OPEN OUTPUT USED-CAR-FILE-OUT
PERFORM 200-INPUT THRU 299-EXIT
CLOSE USED-CAR-FILE-OUT
STOP RUN.
200-INPUT.
DISPLAY 'Used Car Sales Report'
DISPLAY 'Enter the ID Code (or END) - maximum three char.'
ACCEPT ID-CODE
IF ID-CODE = 'END'
GO TO 299-EXIT
END-IF
DISPLAY 'Enter the Total Cash Payment - maximum five digits'
ACCEPT TOTAL-CASH-PAYMENT
DISPLAY 'Enter the Monthly Payment - maximum four digits'
ACCEPT MONTHLY-PAYMENT
DISPLAY 'Enter the Number of Months - maximum three digits'
ACCEPT NUMBER-OF-MONTHS
PERFORM 300-PROCESS.
299-EXIT.
EXIT.
300-PROCESS.
IF TOTAL-CASH-PAYMENT > 0
MOVE TOTAL-CASH-PAYMENT TO PAYMENT-DL
END-IF
IF MONTHLY-PAYMENT > 0
MOVE MONTHLY-PAYMENT TO PAYMENT-DL
END-IF
ADD PAYMENT-DL TO BALANCE-TOTAL
COMPUTE INTEREST-EARNED ROUNDED = .0175 / BALANCE-TOTAL
ADD INTEREST-EARNED TO BALANCE-TOTAL
MOVE BALANCE-TOTAL TO BALANCE-DL
ADD 1 TO COMPARE-MONTH
IF MONTH-NUMBER-DL > 13
ADD 1 TO MONTH-NUMBER
MOVE MONTH-NUMBER TO MONTH-NUMBER-DL
END-IF
IF MONTH-NUMBER-DL = 13
MOVE 1 TO MONTH-NUMBER
MOVE MONTH-NUMBER TO MONTH-NUMBER-DL
END-IF
IF MONTH-NUMBER = 1
ADD 1 TO YEAR-NUMBER
MOVE YEAR-NUMBER TO YEAR-NUMBER-DL
END-IF
MOVE DETAIL-LINE TO USED-CAR-RECORD-OUT
WRITE USED-CAR-RECORD-OUT
AFTER ADVANCING 1 LINE
IF TOTAL-CASH-PAYMENT > 0
MOVE 0 TO TOTAL-CASH-PAYMENT
MOVE 0 TO PAYMENT-DL
END-IF
IF COMPARE-MONTH > NUMBER-OF-MONTHS
PERFORM 300-PROCESS
END-IF
The problem is with PAYMENT-DL, INTEREST-EARNED-DL and BALANCE-DL. It says that an illegal character, but I know that it should work as it shows those pic clauses in my book and the teacher handed out an incomplete version of the program that I have to write. What do I have to do to get rid of those errors?
The invalid character is the "$" sign.
This should be OK, but your compiler may have been customized to use a local currency symbol as the default.
You could switch to your local currency sign (if you know it!) or change it back to "$". Changing it back to "$" depends on which compiler you are using and how the defaults are set -- you really need to read the manual for your particular compiler to find out how this is done.

VB.NET declaration

I have to declare n = 01. But whenever I try it's getting changed to 1.
What should I try?
If this is just for display purposes then I would use the .ToString("0#"), unless you really need to do calculations based on two significant figures.
For index As Integer = 1 To 100
Console.WriteLine(index.ToString("0#"))
Next
Gives you
01
02
.
.
100