Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ILE RPG/400: How do you get the timestamp from the system clock?

1,953 views
Skip to first unread message

Scott Klement

unread,
Mar 3, 1997, 3:00:00 AM3/3/97
to

This is the first time I've needed to do this... and I can't find any
information on how to do it. We are running ILE RPG/400 on V3R1

RPG IV provides a time stamp data-type, and this data type... something
like this: yyyy-mm-dd-hh.mm.ss.mmmmmm

But, I cant for the life of me find any way to retrieve this value from
the clock!

I have no problem finding info on how to set these fields using
literals, *HIVAL, *LOVAL or the INZ() keyword. I have no problem
finding information on how to add or subtract or test a timestamp
field.

The TIME Op-Code can give me the date & time to the nearest second.

but what good does any of this do if I can't retrieve the current
milliseconds from the system clock?! Why even have milliseconds if
they don't give me any way to check the what the current value is in
the system clock?

I *MUST* be missing something obvious here! :) Help!

Francis Lapeyre

unread,
Mar 3, 1997, 3:00:00 AM3/3/97
to klem...@orion.ods.net

Amazingly enough, V3R1 ILE RPG doesn't have the ability to use the TIME
opcode directly to a date, time, or timetamp field. You have to go
through a numeric field first. What I heard about (but have not tried
yet) is using data structures iverlaying the date field (not sure if you
need to have the separators there or not). I'd put the whole thing in a
subroutine, because when you go RISC, V3R7 and later (presumably) has
the ability for the TIME opcode to go directly to date/time/timestamp
fields. As far as the milliseconds are concerned, until V3R7, you're out
of luck as far as the TIME opcode goes, but read the DDS book: the only
way I can see right now is to do a call to QCMDEXC before you opn the
file and use the INZPFM command, as follows:

INZPFM FILE(lib/file) TOTRCDS(1)

Then, you OPEN the file in RPG again, and *HIVAL SETGT, and READP to get
the latest timestamp. Do an UPDATE instead of a WRITE.

Or, you can take the K.I.S.S. approach, which is to simply use the TIME
opcode to the nearest second, then, in a DOU loop, (on a logical of your
file sorted only by the timestamp field), SETLL to the file, with the
found indicator. If found, do an 1:microsecond ADDDUR (not sure of
format) to the timestamp field until you get a unique value, exit the
loop, and write your record. It may not give you the exact microsecond,
but at least you'll have a unique key.

Or, you could get V3R7 and a RISC (not sure if V3R2 will have this
capability.. anyone??


--
Francis Lapeyre flap...@communique.net
----------------------------------------------------------
Qui desiderat pacem præparet bellum (Who would desire
peace should be prepared for war).--Vegetius: Rei Militari
3, Prolog.

Opinions are my own. Otherwise, they are someone else's.

Njal Fisketjon (Njål Fisketjøn)

unread,
Mar 4, 1997, 3:00:00 AM3/4/97
to

Scott Klement <klem...@orion.ods.net> wrote:

>This is the first time I've needed to do this... and I can't find any
>information on how to do it. We are running ILE RPG/400 on V3R1
>
>RPG IV provides a time stamp data-type, and this data type... something
>like this: yyyy-mm-dd-hh.mm.ss.mmmmmm
>
>But, I cant for the life of me find any way to retrieve this value from
>the clock!
>
>I have no problem finding info on how to set these fields using
>literals, *HIVAL, *LOVAL or the INZ() keyword. I have no problem
>finding information on how to add or subtract or test a timestamp
>field.
>
>The TIME Op-Code can give me the date & time to the nearest second.
>
>but what good does any of this do if I can't retrieve the current
>milliseconds from the system clock?! Why even have milliseconds if
>they don't give me any way to check the what the current value is in
>the system clock?
>
>I *MUST* be missing something obvious here! :) Help!


There's at least one API to retrieve the time. You can use the
QWCCVTDT (listed under Misc. API's in the API guide), and specify
*CURRENT for 'From Date'.

There's also an ILE API to get a timestamp


Njål Fisketjøn
FIGU DATA AS
nfis...@figu.no
nfis...@hesgrp.com

Alex Nubla

unread,
Mar 4, 1997, 3:00:00 AM3/4/97
to

Here it is again!

If you are in V3R2 or V3R7, you can retrieve QCENTURY and replace my
centurty routine at the bottom. Make sure you change the dimension for
@OFFSYSVAL to 5 and add QCENTURY in the compile time array.

Refer to the System API manual for the API usaged. This routine is good
for Year 2K project if company decides to add TIMESTAMP in the database.

Alex Nubla

alex_...@msn.com

visit my site: www.geocities.com/SiliconValley/Pines/5581


****************************************************************
* D E F I N I T I O N S P E C I F I C A T I O N *
****************************************************************
*
* Retrieve System Value (QWCRSVAL) API
*
D@RtnSysVal DS
D @NbrRtnVal 9B 0 Inz( %Elem(@NamSysVal) )
D @OffSysVal 9B 0 Dim(4)
D @SysValTbl 100
*
* Timestamp Data Structure
*
D DS
D@TimeStamp Z Inz
D @Century 2A Overlay(@TimeStamp: 1)
D @Year 2A Overlay(@TimeStamp: 3)
D @Month 2A Overlay(@TimeStamp: 6)
D @Day 2A Overlay(@TimeStamp: 9)
D @Hour 2A Overlay(@TimeStamp: 12)
D @Minute 2A Overlay(@TimeStamp: 15)
D @Second 2A Overlay(@TimeStamp: 18)
D @Milli 3A Overlay(@TimeStamp: 21)
*
* Record structure for error code parameter
*
D@ErrData DS
D @BytesProv 9B 0 Inz(100)
D @BytesAval 9B 0
D @ExcpId 7
D @Reserved1 1
D @ExcpData 184
*
* Standalone fields
*
D @LenSysVal S 9B 0 Inz( %Size(@RtnsysVal) )
D @NamSysVal S 10 Dim(4) PerRcd(4)
D CtData
D @NbrSysVal S 9B 0 Inz( %Elem(@NamSysVal) )
D @Offset S 9B 0
C/EJECT
C
****************************************************************
*À C A L C U L A T I O N S P E C I F I C A T I O N Ä*
****************************************************************
*
C Exsr $GetTime
C Eval YourTS = @TimeStamp
*
/SPACE 4
*==============================================================*
* *
* Retrieve the time from the system values *
* *
C $GetTime BEGSR
*
*==============================================================*
*------------------------------------------*
* Retrieve using QWCRSVAL API *
*------------------------------------------*
C Call 'QWCRSVAL'
C Parm @RtnSysVal
C Parm @LenSysVal
C Parm @NbrSysVal
C Parm @NamSysVal
C Parm @ErrData
*
* Retrieve QMONTH (first offset)
*
C Eval @Offset = @OffSysVal(1) - 3
C Eval @Month = %subst(@SysValTbl: @Offset:
2)
*
* Retrieve QDAY (second offset)
*
C Eval @Offset = @OffSysVal(2) - 3
C Eval @Day = %subst(@SysValTbl: @Offset:
2)
*
* Retrieve QYEAR (third offset)
*
C Eval @Offset = @OffSysVal(3) - 3
C Eval @Year = %subst(@SysValTbl: @Offset:
2)
*
* Retrieve QTIME (fourth offset)
*
C Eval @Offset = @OffSysVal(4) - 3
C Eval @Hour = %subst(@SysValTbl: @Offset:
2)
C Eval @Offset = @Offset + 2
C Eval @Minute = %subst(@SysValTbl: @Offset:
2)
C Eval @Offset = @Offset + 2
C Eval @Second = %subst(@SysValTbl: @Offset:
2)
C Eval @Offset = @Offset + 2
C Eval @Milli = %subst(@SysValTbl: @Offset:
3)
*
* Determine Century
*
C If @Year < '40'
C Eval @Century = '20'
C Else
C Eval @Century = '19'
C EndIf
*
C #GetTime ENDSR
**CTDATA @NamSysVal
QMONTH QDAY QYEAR QTIME


Paul Nicolay

unread,
Mar 4, 1997, 3:00:00 AM3/4/97
to

Hi Scott,

Included is the routine that returns a timestamp with a 3 digit precision
(after a second) which is the maximum precision available on the AS/400.
Unfortunately, this isn't enough in some cases since I tried to write
records in a loop and got the same timestamps. At least it's a lot better
than just having seconds.

The routine should be called with a parameter of data type Z.

Kind regards,
Paul Nicolay
System Engineer
_________________

* Program : TimeStamp
*
* Description : Return timestamp
*
* Author : Paul Nicolay
*
* Modifications :
*
* Initials Date Description
* -------- ---------- ----------------------------------------------
* PN 30-10-1996 Creation
*
**********************************************************************
****************************
* Definitions *
****************************
DTimeStamp DS
D Stamp 26 Inz('0000-00-00-00.00.00.000000')
D Century 2 OverLay(Stamp:1)
D Year 2 OverLay(Stamp:3)
D Month 2 OverLay(Stamp:6)
D Day 2 OverLay(Stamp:9)
D Hour 2 OverLay(Stamp:12)
D Minute 2 OverLay(Stamp:15)
D Second 2 OverLay(Stamp:18)
D MSecond 6 OverLay(Stamp:21)

DOutputVar DS
D CurCentury 1
D CurYear 2
D CurMonth 2
D CurDay 2
D CurHour 2
D CurMinute 2
D CurSecond 2
D CurMSecond 3

DError DS
D ErrorLen 1 4B 0
D MessageID 9 15

C *Entry PList
C Parm #TimeStamp 26
****************************
* Main *
****************************
C Eval ErrorLen = %Size(Error)
C Call 'QWCCVTDT'
C Parm '*CURRENT' InputFmt 10
C Parm InputVar 1
C Parm '*YMD' OutputFmt 10
C Parm OutputVar 16
C Parm Error

C If CurCentury = '0'
C MoveL '19' Century
C Else
C MoveL '20' Century
C EndIf

C MoveL CurYear Year
C MoveL CurMonth Month
C MoveL CurDay Day
C MoveL CurHour Hour
C MoveL CurMinute Minute
C MoveL CurSecond Second
C MoveL CurMSecond MSecond

C MoveL TimeStamp #TimeStamp

C Return

___________
Scott Klement <klem...@orion.ods.net> wrote in article
<331B42...@orion.ods.net>...


> This is the first time I've needed to do this... and I can't find any
> information on how to do it. We are running ILE RPG/400 on V3R1
>
> RPG IV provides a time stamp data-type, and this data type... something
> like this: yyyy-mm-dd-hh.mm.ss.mmmmmm
>
> But, I cant for the life of me find any way to retrieve this value from
> the clock!
>
> I have no problem finding info on how to set these fields using
> literals, *HIVAL, *LOVAL or the INZ() keyword. I have no problem
> finding information on how to add or subtract or test a timestamp
> field.
>
> The TIME Op-Code can give me the date & time to the nearest second.
>
> but what good does any of this do if I can't retrieve the current
> milliseconds from the system clock?! Why even have milliseconds if
> they don't give me any way to check the what the current value is in
> the system clock?
>
> I *MUST* be missing something obvious here! :) Help!
>


The contents of this message express only the sender's opinion.
This message does not necessarily reflect the policy or views of
my employer, Merck & Co., Inc. All responsibility for the statements
made in this Usenet posting resides solely and completely with the
sender.

Scott P. Johnson

unread,
Mar 5, 1997, 3:00:00 AM3/5/97
to

You have to load the Timestamp in two parts, time & date.
I don't have the code available right now, but I have done it.
If I remember correctly you just move the Time into the
Timestamp field and then MOVEL the Date. The AS/400 is smart
enough to put it where it needs to.

Hope this Helps,
Scott P. Johnson
Veritec Computing

Njal Fisketjon (Njål Fisketjøn)

unread,
Mar 5, 1997, 3:00:00 AM3/5/97
to

"Alex Nubla" <alex_...@msn.com> wrote:

>Here it is again!
>
>If you are in V3R2 or V3R7, you can retrieve QCENTURY and replace my
>centurty routine at the bottom. Make sure you change the dimension for
>@OFFSYSVAL to 5 and add QCENTURY in the compile time array.
>
>Refer to the System API manual for the API usaged. This routine is good
>for Year 2K project if company decides to add TIMESTAMP in the database.
>
>Alex Nubla
>
>alex_...@msn.com
>

a LOT of code snipped


I would prefer to keep it simple: This works even on V3R6.

A small CLLE program bound with a couple of service programs (QLECWI
and QLEAWI). I don't remember the binding directory, but it's
specified in the API manual.

pgm
dcl &Lilian *char 4
dcl &seconds *char 8
dcl &Gregorian *char 23
dcl &fc *char 12

callprc CEELOCT (&Lilian &seconds &Gregorian &fc)

sndpgmmsg &Gregorian

endpgm


Of course in real life, you would add a parameter (i.e. &Gregorian)
and remove the sndpgmmsg command.

This returns for example 19970305235656127000000

Santiago Cardona

unread,
Apr 5, 1997, 3:00:00 AM4/5/97
to

I want to know if somebody can give me a solution to this problem. It
is very simple in other languages but in RPG IV I don,t know HOW .
Thanks.


PROGRAM 001 PROGRAM 002
:
var_a = 'initial'
call PROGRAM 002 with var_a
* change var_a to 'changed'
return from PROGRAM 002

I want to have the changed field in the Program 001 [first] HOW ¿?¿


Thanks in advanced for your help.


Jaume Cardona
Tanus Ubiest SR
SPAIN

Scott Klement

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Lets see if I understand you correctly... you want to define a
variable in one program, then call a second program which changes that
same variable??

This is very easy to do in RPG IV.. In the example below, PROGRAM1
will create a variable called "Var_A" and set its value to "initial"
it calls PROGRAM2 which changes the value to "changed" and end.

PROGRAM1 will resume execution when PROGRAM2 ends, and will display the
variable on your screen with its new value "changed"


RPG IV Source for "PROGRAM1"

D Var_A S 7A

C eval Var_A = 'initial'

C call 'PROGRAM2'
c parm Var_A

c Var_A DSPLY
c eval *INLR = *ON

RPG IV source for 'PROGRAM2'

D Var_A S 7A

c *ENTRY PLIST
c parm Var_A

c eval Var_A = 'changed'

c eval *INLR = *ON
c Return

Paul Nicolay

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Hi Santiago,

The basic statements you need look as follows;

Program A
----------------
DVarA S 10A
C Call 'PROGRAMB'
C Parm VarA

Program B
----------------
DVarB S 10A
C *Entry PList
C Parm VarB
C MoveL 'Changed' VarB
C Return

Kind regards,
Paul
_______________
Santiago Cardona <ta...@abaforum.es> wrote in article
<3346d056...@news.abaforum.es>...


>
> I want to know if somebody can give me a solution to this problem. It
> is very simple in other languages but in RPG IV I don,t know HOW .
> Thanks.
>
>
> PROGRAM 001 PROGRAM 002
> :
> var_a = 'initial'
> call PROGRAM 002 with var_a
> * change var_a to 'changed'
> return from PROGRAM 002
>
> I want to have the changed field in the Program 001 [first] HOW ¿?¿
>
>
> Thanks in advanced for your help.
>
>
> Jaume Cardona
> Tanus Ubiest SR
> SPAIN
>

MADWALTER

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

Caller:
EVAL Pass_var = *blanks
CALL 'Reciever'
PARM Pass_var

Reciever:
*entry PLIST
PARM Pass_var
|
|
EVAL *inlr = *on
RETURN

The variable Pass_var is initialized before the call is made. Pass the
variable to the reciever with the PARM Opcode. The *entry PLIST line tells
the RPG that there is a parameter comming. The reciever will modify the
variable and when the RETURN is encountered Pass_var will pass it value
back to the caller.
This is a simple example. The spacing is probably not correct also the
Names Caller: and Reciver: should not be included. They just signify The
calling programs code and the recieving programs code.

I hope this helps you

0 new messages