Category Archives: Technology

Happy Birthday, RPG IV notes that 21 years ago today, RPG IV (also known as RPG ILE) was released.

The first version of RPG IV came as part of OS400 V3R1, which was released on November 25 1994. Even though the code was still constrained by columns, the new Definition specifications (D-specs) was introduced, and I could now use variable names that were up to ten characters long. It also made it possible to use Date, Time, and Timestamp data types along with operations codes to be able to easily perform math with them. And I no longer had to use indicators for reads, chains, etc.

This makes me feel a bit old as I remember when RPG ILE was the next big thing. And, without much fanfare, it has continued to evolve — in many ways more rapidly than other, more popular languages. This is both RPG’s greatest strength and its greatest weakness.

IBM have, over the years, put a great deal of effort into ensuring that, for all the new features, backward compatibility has never been broken. This means that if you are running an i on Power, you can upgrade as and when you are ready without having to worry about all of your applications breaking. There are not many reasons for not staying on a supported release, and fewer valid valid ones.

The downside of this is that there is nothing to force developers to take advantage of any of these new features. You could, if you wanted to, write programs in exactly the way you did 30 years ago. They would still compile, still run and still work as expected. And people do.

RPG today is in the somewhat unfortunate position of being a very modern language that is often perceived as being old fashioned. This is because it lets programmers get into a rut and never learn anything new.

I doubt that there is any way of squaring this particular circle. Backward compatibility is important and business critical applications shouldn’t be put at risk. But remember this: If someone claims that RPG is old, obsolete, or worse, the issue to which they are referring is not a technical one.

Flattr this!

Better date conversion with timestamp_format

Some time ago, I discussed the never-ending problem of converting a six digit number into an ISO date. I have since found a better way of doing this and, in order to save myself a search through the IBM Knowledge Center every time I need to do this, I’m putting it up here.

So here’s the problem: I have a table in which the date is represented as a 7 digit number. The first digit is the century (0 indicates 20th century, 1 indicates 21st century) and the next six digits represent the date in YYMMDD format. So 1150831, for example, is 31st August 2015.

The request in hand is for a report, so I want to convert the number into a date so that it looks sensible once exported into Excel. Timestamp_format is your friend.

The TIMESTAMP_FORMAT function returns a timestamp that is based on the interpretation of the input string using the specified format.

It’s that “interpretation of the input string” that makes this so handy. Put simply: you tell the function how to interpret the string and it will do the rest.

Here’s an example. I have a contracts table (CONTRACTS) with three columns: Contract Number (CTNR), Start Date (STDT) and End Date (ENDT). The start and end date are both seven digit numbers as described previously. I need to list all of the currently active contracts (Start Date is before Today and End Date is after Today).

And the SQL looks like this:

select CTNR,
       date(timestamp_format(substr(digits(STDT), 2, 6), 'YYMMDD')),
       date(timestamp_format(substr(digits(ENDT), 2, 6), 'YYMMDD'))
where date(timestamp_format(substr(digits(STDT), 2, 6), 'YYMMDD')) <= current_date
and date(timestamp_format(substr(digits(ENDT), 2, 6), 'YYMMDD')) >= current_date

Current_date is a special register that returns the current date, but that’s not important right now.

The date conversion part involves several nested functions to get to a final date, so here’s the breakdown using a date of 1st September 2015 (1150901):

  • digits(STDT) converts the 7 digit number into a 7 character string. So 1150901 is converted to ‘1150901’.
  • The IBM i can figure out which century it’s in by looking at the year, so I don’t need the century flag and the substr(digits(STDT), 2, 6) strips it out to give me a value of ‘150901’
  • The timestamp_format function takes the date string and uses the format string of ‘YYMMDD’ to generate a timestamp of 2015-09-01- Since I only passed it a date, the hours, minutes and seconds are all zeroes.
  • And finally, I can use the date function to retrieve the date from the generated timestamp.

And here’s the result:

CTNR      DATE      DATE
C1000001  01/09/15  31/08/16

Pretty, and portable.

Flattr this!

Can you spot the drowning child?

Here’s a fun game you can play just before heading off on the family holiday. Spot the Drowning Child is a simple educational game written by Francisco Saldaña to help people recognise what is happening.

The Instinctive Drowning Response — so named by Francesco A. Pia, Ph.D., is what people do to avoid actual or perceived suffocation in the water. And it does not look like what most people expect. There is very little splashing, no waving, and no yelling or calls for help of any kind. To get an idea of just how quiet and undramatic from the surface drowning can be, consider this: It is the number two cause of accidental death in children, age 15 and under (just behind vehicle accidents) — of the approximately 750 children who will drown next year, about 375 of them will do so within 25 yards of a parent or other adult. In ten percent of those drownings, the adult will actually watch them do it, having no idea it is happening.

For the record, I did manage to spot the drowning child, but it took a lot longer than I expected, especially when you take into account that I was actively looking for the drowning child.

Via io9

Flattr this!

Managing network drives in Powershell

It used to be, in Windows, that the way to map network drives was with the net use command, but with Powershell this has become a bit easier. I haven’t, however, been able to find a simple overview of the commands and their usage so hopefully this will be of use to someone other than me.

There are three commands (cmdlets in Powershell speak) that you need to know about.


This lists the currently mapped drives and a bit of information about them, most usefully the network path that the drive is mapped to. You can also enter the drive letter as a parameter so that

Get-PSDrive C

Tells you that drive C is mapped to the Windows C: drive. Obvious, really, but more useful if you want to know about other mapped drives.


This is the cmdlet that maps drives to to shared folders. If I want, for example, to map my Y drive to folder \sharedfiles on server Server the command would look like this:

New-PSDrive –Name “Y” –PSProvider FileSystem –Root “\\Server\sharedfiles” –Persist

The PSProvider switch tells Powershell what sort of data this drive is accessing. Filesystem, obviously, is the filesystem but you can also map to environment variables and other oddities.

The Root switch is needed so that Powershell understands the path name.

The Persist switch tells Powershell that this mapping is persistent so the mapped drive is available every time you reboot. This switch also causes Powershell to create a mapped network drive in Windows which can be accessed via all the standard Windows tools such as Windows Explorer.


When you no longer need the mapped drive, you can remove the mapping with this command.

Remove-PSDrive Y

Does exactly what you would expect.

Flattr this!

Using QShell and CL to work with Stream files in the IFS

It turns out that there is no simple way of generating a list of files currently residing in a folder on the IBM i IFS. Simple, in this case, would be a command like DSPLNK OUTPUT(*FILE). An API does exist, but a combination of not enough time and too much lazy proved to be quite a disincentive for me going down that route.

The issue was that we recieve a number of very big files and, to save a bit of bandwidth, these files were being zipped before being sent to the IBM i. Dropping the file into the IFS and unzipping it was easy enough but then I found myself with an archive folder containing one of more files. While I can set the name of the folder into which the files should be extracted, I have no way of determining beforehand what the file names will be.

Here’s a solution:

/* -------------------------------------------------------------------------- */
/* Program     : EXTRACTZIP                                                   */
/* Description : Retrieve and unpack a zipped archive                         */
/* Written by  : Paul Pritchard                                               */
/* Date        : 27/05/2015                                                   */
/* -------------------------------------------------------------------------- */
dcl &library *char 10 value('MYLIB')
dcl &fromfile *char 50
dcl &tombr *char 50 value('/qsys.lib/qtemp.lib/IMPORTP.file/IMPORTP.mbr')
dcl &dltfile *char 50

/* Retrieve and the zipped file and unzip it.                                 */
/* I won't bore you with the details here, but the the production program is  */
/* retriving the ZIP file from an FTP server and using PKZIP to unzip it.     */
/* The extract directory is /home/EXPATPAUL/EXTRACTFLR which now contains one */
/* or more stream files                                                       */

/* Retrieve a list of extracted files                                         */
/* First, I use QShell to list the files in EXTRACTFLR. The output of this is */
/* redirected to ExtractedFiles.TXT.                                          */
/* In order to use this information, I copy the ExtractedFiles.TXT stream     */
/* to an ad-hoc physical file (QTEMP/EXTRACTP)                                */
qsh cmd('ls /home/EXPATPAUL/EXTRACTFLR/ > /home/EXPATPAUL/ExtractedFiles.TXT')
crtpf file(QTEMP/EXTRACTP) rcdlen(20)
cpyfrmstmf fromstmf('/home/EXPATPAUL/ExtractedFiles.TXT') +
           tombr('/qsys.lib/qtemp.lib/EXTRACTP.file/EXTRACTP.mbr') +

/* And now I can use QTEMP/EXTRACTP to drive my way through EXTRACTFLR and    */
/* copy each of the files in the archive into the IMPORTP physical file.      */
dowhile '1'
    monmsg msgid(CPF0864) exec(LEAVE)

    /* Copy the next sream file from the archive                              */
    chgvar &fromfile value('/home/EXPATPAUL/EXTRACTFLR/' *tcat &EXTRACTP)
    cpyfrmstmf fromstmf(&fromfile) tombr(&tombr) mbropt(*add) +

    /* and then delete the stream file                                        */
    chgvar &dltfile value('rm /home/EXPATPAUL/EXTRACTFLR/' *tcat &EXTRACTP)
    qsh cmd(&dltfile)


/* Clean up and exit                                                          */    
qsh cmd('rm /home/EXPATPAUL/ExtractedFiles.TXT')
dltf qtemp/EXTRACTP


It should go without saying that some of the names have been changed and that the above program should be treated as a sample only.

Being able to move information between the QShell/IFS and traditional i5/OS environments is both useful and (in my experience) increasingly important. Although it does take a bit of thinking about, it isn’t difficult which is why I find that the oft-seen solution of “buy this tool” is both disappointing and (often) overkill.

Flattr this!

Gnome 3.16: A First Impression

I ran a system update today and Gnome 3.16 turned up. Which was nice.

One thing that I always found mildly annoying in Gnome 3.14 (and I think that this was also true of Gnome 3.12) was that when I clicked the shutdown button it would give me a choice between shutting down or logging out. If I wanted to reboot, I had to log out first and then reboot from the login screen.

So, wondering if anything had been done about the shutdown options, I clicked on the shutdown button.

And my laptop shut itself down.

10/10 for simple behaviour. Minus about 30 for being totally unexpected.

Flattr this!

More consolidation: Squirt

After spending some time cleaning up the mess of repsoitories that I have generated over the past few years, I thought it might be a good time to take a look at Squirt, a slightly larger project. In this case, Squirt still has its own repository but I have removed some branches. Now, instead of creating a seperate branch for every point release (because this is going to become very silly very quickly), I have two branches: development and master.

Obviously, the intention is to use development for any code changes and once I am happy with them, they will be pushed to master. Hopefully this will encourage to be a little less tardy about keeping the master branch up to date.

Flattr this!

It is done

I mentioned last month that I was in the process of consolidating the mess of repositories that I have created over the past few years. This is now done and, hopefully, will be a bit more manageable going forward.

I now have three consolidated repositories: silliness, utilities and utils-on-power. The Configurate repository is already logically enough organised and Squirt is large enough to justify its own repo.

I have also removed the static pages referring to these repos on this site. They were creating overhead without adding any value.

And I now know a lot more about Git that I knew this time last month.

Flattr this!