Вы находитесь на странице: 1из 12

MC Press Online

RPG IV Legacy Dates Cheat Sheet


Contributed by Sam Lennon Tuesday, 01 January 2008 Last Updated Friday, 04 January 2008

Still stuck with legacy date and time fields in your database and programs? Let RPG IV do the heavy lifting for you.

By Sam Lennon

In V5R3, date-handling is superb and calculations are straightforward. Fine, you say, but what about all those pesky character or numeric fields we still have to fight with from designs that originated before the date- and time-field data types were available? Those fields might have two- or four-digit years and might be in YMD order or MDY order or, outside the

U.S. , even DMY order. What about them?

Still stuck with legacy date and time fields in your database and programs? Let RPG IV do the heavy lifting for you.

In V5R3, date-handling is superb and calculations are straightforward. Fine, you say, but what about all those pesky character or numeric fields we still have to fight with from designs that originated before the date- and time-field data types were available? Those fields might have two- or four-digit years and might be in YMD order or MDY order or, outside the

U.S. , even DMY order. What about them?

No sweat. RPG handles these legacy fields easily and concisely, but based on code I've seen recently, not everyone knows how to do it.

http://www.mcpressonline.com

Powered by Joomla!

Generated: 29 August, 2008, 00:11

MC Press Online

I'm surprised that some developers still write code that uses data structures or sub-stringing or concatenation to manipulate dates—not only in converted RPG III code, but also in new RPG IV development. Much of this code deals with creating legacy date and time fields used to timestamp database records, though it isn't restricted to this, because you often want to add or subtract from one of these stored dates. In many cases, the developer has some reusable, tried-and-tested code snippets. While I applaud code reuse, it wouldn't hurt to upgrade the code, because RPG IV date-handling makes the code shorter and easier to understand. Some Bad Examples

Following are three examples of code that I came across recently. I found each as shown; all I've done is add standalone fields in place of database fields. See if you find any obvious errors.

This is example 1, from a developer who has been writing code for at least 10 years:

D t_audit_date

8p 0

D t_audit_time

6p 0

D #TimeDate

DS

D #Time

6 0

D #Date

14 0

D #CYMD

D DATFMT(*ISO)

time

TimeStamp

14 0

move

TimeStamp

#TimeDate
Powered by Joomla! Generated: 29 August, 2008, 00:11

http://www.mcpressonline.com

MC Press Online

USA

move

#Date

#CYMD

move

#cymd

wrkdate

80

move

wrkdate

t_audit_date

move

#time

t_audit_time

This is example 2. Similar code also turned up in several programs this developer wrote.

D Todays_Date_C DS

D Todays_Date

8 0 Overlay(Todays_Date_C)

D Curr_Date

D inz(*sys)

/free

Todays_Date_C = %subst(%Char(Curr_Date):1:4) +

%subst(%Char(Curr_Date):6:2) +

http://www.mcpressonline.com

Powered by Joomla!

Generated: 29 August, 2008, 00:11

MC Press Online

%subst(%Char(Curr_Date):9:2);

This is example 3. An experienced developer from a large contracting company wrote this about three years ago.

h DATEDIT(*YMD)

D HMDATE

8A

D HMTIME

6S 0

move

*Date

HMDATE

TIME

HMTIME

Now, what's your opinion of the above code? Do you see any problems? Better Examples

While I labeled them as bad examples, two of the routines work well, and the third works most of the time. But the code can be better.

Bad example 1 works. This is a snippet of debugged code that the developer uses routinely. The main problem is the
http://www.mcpressonline.com Powered by Joomla! Generated: 29 August, 2008, 00:11

MC Press Online

wordiness and the obfuscation caused by using the data structure. Data structures have their place, but when used like this, you have to look at two places in the program to see what's going on. Consider this shorter code, which produces the same result without using a data structure.

D t_audit_date

8p 0

D t_audit_time

6p 0

D TimeStamp

/FREE

TimeStamp = %timestamp();

t_audit_date = %dec(%date(Timestamp):*ISO);

t_audit_time = %dec(%time(Timestamp):*HMS);

Bad example 2 also works, and again, the only problem is the wordiness. This much shorter piece of code produces the same results.

D Todays_Date

8 0

D Curr_Date

D inz(*sys)

/free
http://www.mcpressonline.com Powered by Joomla! Generated: 29 August, 2008, 00:11

MC Press Online

Todays_Date = %dec(Curr_Date:*ISO);

Bad example 3 really is bad, though it works most of the time. (For reference, check if your boss thinks accuracy 99 percent of the time is acceptable.) I've seen this combination of a reserved word and the TIME opcode in way too many programs. In RPG IV, the reserved words UDATE, *DATE, UMONTH, *MONTH, UYEAR, *YEAR, UDAY, and *DAY all refer to the date the job started to run. This job date does not change. The TIME opcode, on the other hand, comes from the system clock that is constantly changing. If the job runs past midnight, such date and time combinations will be incorrect, and it will look like the later transactions occurred before the earlier ones.

It makes little sense to combine a static date and a variable time to timestamp a record unless you can guarantee that the job will never run past midnight. Why take the risk? This is the correct (and just as easy) way to timestamp a record with legacy fields:

D HMDATE

8A

D HMTIME

6S 0

D TS

*=======================================================

/free

TS = %timestamp();

http://www.mcpressonline.com

Powered by Joomla!

Generated: 29 August, 2008, 00:11

MC Press Online

HMDATE = %char(%date(TS):*ISO0);

HMTIME = %dec(%time(TS):*HMS); The Cheat Sheet

OK, here's the cheat sheet—short on theory, long on examples. It is in the form of an RPG IV program, with the variable names constructed to let you intuitively know what they contain. CC, for example, represents the century, the first two digits, of a year. YY is the last two digits of a year, MM is the month of a year, and DD is the day of a year. C by itself means 0 for 19 and 1 for 20. At the end of the variable name, _n means it is a numeric field and _c means it is a character field. So CCYYMMDD_n is a numeric field that might contain 20071231.

The first section is for creating legacy fields in a variety of formats. The second section is for converting legacy fields to native data types so that you can easily do calculations on them.

* Legacy Date and Time Handling Cheat Sheet

D TS

D Date

D CCYYMMDD_n

8 0

D YYMMDD_n

6 0

http://www.mcpressonline.com

Powered by Joomla!

Generated: 29 August, 2008, 00:11

MC Press Online

D CYYMMDD_n

7 0

D MMDDYY_n

6 0

D CCYYMMDD_c

D YYMMDD_c

D CYYMMDD_c

D MMDDYY_c

D HHMMSS_n

D HHMMSS_c

/free

//=== Legacy Date & Time Stamps - from System Clock ===

http://www.mcpressonline.com

Powered by Joomla!

Generated: 29 August, 2008, 00:11

MC Press Online

TS = %timestamp();

//--- Set Numeric Legacy Date Fields ---

CCYYMMDD_n = %dec(%date(TS): *ISO);

YYMMDD_n = %dec(%date(TS): *YMD);

CYYMMDD_n = %dec(%date(TS): *CYMD);

MMDDYY_n = %dec(%date(TS): *MDY);

//--- Set Character Legacy Date Fields ---

CCYYMMDD_c = %char(%date(TS): *ISO0);

YYMMDD_c = %char(%date(TS): *YMD0);

CYYMMDD_c = %char(%date(TS): *CYMD0);

MMDDYY_c = %char(%date(TS): *MDY0);

http://www.mcpressonline.com

Powered by Joomla!

Generated: 29 August, 2008, 00:11

MC Press Online

//--- Set Legacy Time Fields ---

HHMMSS_n = %dec(%time(TS): *HMS);

HHMMSS_c = %char(%time(TS): *HMS0);

//=== Legacy Date Stamp from Job Date ===

CCYYMMDD_n = %dec(%date(*DATE): *ISO);

CCYYMMDD_c = %char(%date(*DATE): *ISO0);

//=== Converting Legacy Dates to True Dates ===

//--- True date from numeric fields ---

Date = %date(122507: *MDY);

http://www.mcpressonline.com

Powered by Joomla!

Generated: 29 August, 2008, 00:11

MC Press Online

Date = %date(251207: *DMY);

Date = %date(071225: *YMD);

Date = %date(12252007: *

USA );

Date = %date(25122007: *EUR);

Date = %date(20071225: *ISO);

//--- True date from character fields, no separators ---

Date = %date('122507': *MDY0);

Date = %date('251207': *DMY0);

Date = %date('071225': *YMD0);

Date = %date('12252007': *USA0);

Date = %date('25122007': *EUR0);

Date = %date('20071225': *ISO0);


http://www.mcpressonline.com Powered by Joomla! Generated: 29 August, 2008, 00:11

MC Press Online

//--- True date from character fields with separators ---

Date = %date('12/25/07': *MDY);

Date = %date('25/12/07': *DMY);

Date = %date('07/12/25': *YMD);

Date = %date('12/25/2007': *

USA );

Date = %date('25.12.2007': *EUR);

Date = %date('2007-12-25': *ISO);

See how easy it is? There is no longer any need for data structures, sub-stringing, or concatenation to create legacy dates and times. Nor is any trickery needed to convert a legacy field to a native data type. Just print this code and pin it on your wall as a reference. And be sure to share it with your coworkers who don't read MC Press Online so they know what they are missing.

http://www.mcpressonline.com

Powered by Joomla!

Generated: 29 August, 2008, 00:11

Вам также может понравиться