My client has seven iSeries systems and the time is set by hand on each. This causes a swing of several minutes from the slowest to the fastest. A number of good tools exist that use SMTP to get the correct time from the internet or perhaps even the more accurate GPS system for iSeries. Most are written in 'C' and/or use sockets programming. These methods and SMTP all want to use the standard TCP port of 123 for time services. My problem was that the clients network management group has this port blocked at the firewall. So with some investigation I found that FTPing into the U.S. Navy time server I would get a welcome message containing the UTC time. Now this method has more overhead than standard SMTP and the accuracy will suffer. On my oldest and slowest system I'm finding the time to be 8 - 10 seconds slow. This is still far better than manual setting the clock. The setup is quite simple. First create a dummy file for the compile requirement. CRTPF FILE(QTEMP/FTPLOG) RCDLEN(132) You will also need to create a source physical file named FTPTIME. Add to this file (using SEU) a TXT member named FTP. Edit the member adding these two lines: anonymous your@email.com quit Now compile this CLP interactively with enough authority to change the sysval QTIME. Note: The line "DCL VAR (&UPDATE) TYPE(*LGL) VALUE('0')" must be changed to ('1') for the system value to be changed. If you wish to automate the Daylight saving time adjustment of your sysval QUTCOFFSET use the 2nd small CLP. Note: the values are for the East coast U.S. only. This program can be setup in any basic job scheduler to run every Sunday at 2:00. Code: /********************************************************************+ | + | Program FTPTIME set the system time using FTP + | + | FTP to the US Navy time site and capture the login text + | which contains the current UTC time. Then set the system time. + | + | Note: Job must run with authority that can CHGSYSVAL QTIME + | This program requires you correctly set the SYSVAL + | QUTCOFFSET for your time zone. + | Tip: Using your browser go to www.time.gov for your time zone + | offset value. + | + | Doug Hart 1/31/2022 + | + +*********************************************************************/ PGM /*********************************************************************/ /* Local Variables */ /*********************************************************************/ /* Switch 0=no update, 1=update */ DCL VAR(&UPDATE) TYPE(*LGL) VALUE('0') DCL VAR(&TGTSYS) TYPE(*CHAR) LEN(30) + VALUE('TYCHO.USNO.NAVY.MIL') DCL VAR(&CMPSTR) TYPE(*CHAR) LEN(8) + VALUE('230-USNO') /* line compare string */ DCL VAR(&UTCSYSVAL) TYPE(*CHAR) LEN(5) DCL VAR(&UTC) TYPE(*DEC) LEN(2 0) DCL VAR(&UTCSIGN) TYPE(*CHAR) LEN(1) DCL VAR(&HH) TYPE(*CHAR) LEN(2) DCL VAR(&MM) TYPE(*CHAR) LEN(2) DCL VAR(&SS) TYPE(*CHAR) LEN(2) DCL VAR(&HHN) TYPE(*DEC) LEN(2 0) DCL VAR(&TIME) TYPE(*CHAR) LEN(6) DCL VAR(&QTIME) TYPE(*CHAR) LEN(6) /********************************************************************/ /* Setup variables for QCLSCAN program */ /********************************************************************/ DCL VAR(&STRING) TYPE(*CHAR) LEN(132) DCL VAR(&STRLEN) TYPE(*DEC) LEN(3 0) VALUE(132) DCL VAR(&STRPOS) TYPE(*DEC) LEN(3 0) VALUE(25) DCL VAR(&PATTERN) TYPE(*CHAR) LEN(1) + VALUE(':') DCL VAR(&PATLEN) TYPE(*DEC) LEN(3 0) VALUE(1) DCL VAR(&TRANSLATE) TYPE(*CHAR) LEN(1) VALUE('0') DCL VAR(&TRIM) TYPE(*CHAR) LEN(1) VALUE('0') DCL VAR(&WILD) TYPE(*CHAR) LEN(1) VALUE(' ') DCL VAR(&RESULT) TYPE(*DEC) LEN(3 0) VALUE(1) /********************************************************************/ /* File in QTEMP that will be parsed for time string */ /* To compile program, file must be created and in libl */ /********************************************************************/ DCLF FILE(FTPLOG) /********************************************************************/ /* Get UTC time offset hours and + or - sign from sysval */ /********************************************************************/ RTVSYSVAL SYSVAL(QUTCOFFSET) RTNVAR(&UTCSYSVAL) CHGVAR VAR(&UTCSIGN) VALUE(%SST(&UTCSYSVAL 1 1)) CHGVAR VAR(&UTC) VALUE(%SST(&UTCSYSVAL 2 2)) /********************************************************************/ /* Build the FTP login file. */ /* This file has only two record holding the password and email */ /* and the FTP command QUIT needed for the Navy FTP server. */ /* ex: ANONYMOUS */ /* QUIT */ /* Note: This can be setup once manually using SEU */ /********************************************************************/ /* CRTSRCPF FILE(*LIBL/FTPTIME) RCDLEN(92) MBR(FTP) */ /********************************************************************/ /* Delete/Create the FTP transfer log file */ /********************************************************************/ DLTF FILE(QTEMP/FTPLOG) MONMSG MSGID(CPF0000) CRTPF FILE(QTEMP/FTPLOG) RCDLEN(132) MBR(FTPLOG) /********************************************************************/ /* Execute FTP transfer */ /********************************************************************/ OVRDBF FILE(INPUT) TOFILE(*LIBL/FTPTIME) MBR(FTP) OVRDBF FILE(OUTPUT) TOFILE(QTEMP/FTPLOG) MBR(FTPLOG) STRTCPFTP RMTSYS(&TGTSYS) DLTOVR FILE(*ALL) /********************************************************************/ /* Parse FTPLOG file for time string */ /********************************************************************/ READ: RCVF MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(END)) /* End of file found and record not found = error */ IF COND(%SST(&FTPLOG 1 8) = &CMPSTR) THEN(DO) + /********************************************************************/ /* Found time string line in log starting with '230-USNO' */ /* Now parse the line for ':' to get time position */ /* Then convert the string to HH MM SS values */ /********************************************************************/ CHGVAR VAR(&STRING) VALUE(&FTPLOG) CALL PGM(QCLSCAN) PARM(&STRING &STRLEN &STRPOS + &PATTERN &PATLEN &TRANSLATE &TRIM &WILD + &RESULT) IF COND(&RESULT = 0) THEN(GOTO CMDLBL(END)) /* Time ':' not found in string = error */ CHGVAR VAR(&RESULT) VALUE(&RESULT - 2) CHGVAR VAR(&HH) VALUE(%SST(&FTPLOG &RESULT 2)) CHGVAR VAR(&RESULT) VALUE(&RESULT + 3) CHGVAR VAR(&MM) VALUE(%SST(&FTPLOG &RESULT 2)) CHGVAR VAR(&RESULT) VALUE(&RESULT + 3) CHGVAR VAR(&SS) VALUE(%SST(&FTPLOG &RESULT 2)) CHGVAR VAR(&HHN) VALUE(&HH) IF COND(&UTCSIGN = '-') THEN(DO) CHGVAR VAR(&HHN) VALUE(&HHN - &UTC) IF COND(&HHN < 0) THEN(CHGVAR VAR(&HHN) + VALUE(24 + &HHN)) ENDDO ELSE CMD(DO) /* &UTCSIGN = '+' */ CHGVAR VAR(&HHN) VALUE(&HHN + &UTC) IF COND(&HHN > 23) THEN(CHGVAR VAR(&HHN) + VALUE(&HHN - 24)) ENDDO CHGVAR VAR(&HH) VALUE(&HHN) /********************************************************************/ /* Set the system value QTIME */ /********************************************************************/ CHGVAR VAR(&TIME) VALUE(&HH || &MM || &SS) RTVSYSVAL SYSVAL(QTIME) RTNVAR(&QTIME) IF COND(&UPDATE) + THEN(CHGSYSVAL SYSVAL(QTIME) VALUE(&TIME)) SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('System + time changed from' |> %SST(&QTIME 1 2) || + ':' || %SST(&QTIME 3 2) || ':' || + %SST(&QTIME 5 2) |> 'to' |> &HH || ':' || + &MM || ':' || &SS |> 'by FTPTIME + program') MSGTYPE(*INFO) RETURN /* Good completion */ ENDDO GOTO CMDLBL(READ) /* get next record loop */ /********************************************************************/ /* On error send mesage */ /********************************************************************/ END: SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('FTP + time process ended in ERROR. Check + joblog for details, or review the QTEMP + files FTPCMD and FTPLOG.') MSGTYPE(*ESCAPE) ENDPGM /* ----------------------------------------------------------------- + | Program: ADJUTC Adjust UTC Sysval + | Date : 2/05/2022 + | Author : D. Hart + | + | Function: Adjust for Daylight Saving Time the system value + | QUTCOFFSET. This is only for the Eastern US time zone + | Run this job every Sunday at 02:00 in system job + | scheduler. + | + | Coordinated Universal Time -4 hours; Daylight Saving Time + | Coordinated Universal Time -5 hours; Not Daylight Saving Time + | + L ----------------------------------------------------------------- */ PGM DCL VAR(&MONTH) TYPE(*CHAR) LEN(2) DCL VAR(&DAY) TYPE(*CHAR) LEN(2) RTVSYSVAL SYSVAL(QMONTH) RTNVAR(&MONTH) RTVSYSVAL SYSVAL(QDAY) RTNVAR(&DAY) /* 1ST Sunday in April start Daylight Saving Time */ IF COND(&MONTH = '04' *AND &DAY *LE '07') THEN( + CHGSYSVAL SYSVAL(QUTCOFFSET) VALUE('-0400')) /* Last Sunday in October end Daylight Saving Time */ IF COND(&MONTH = '10' *AND &DAY *GE '25') THEN( + CHGSYSVAL SYSVAL(QUTCOFFSET) VALUE('-0500')) ENDPGM |