× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



On 28-Jun-2016 16:17 -0500, Buck Calabro wrote:
<<SNIP>>
But if you want to roll your own, you need to convert the pack to
char, then substring out all the pieces, assemble them with ISO
editing and perform a DATE() over that. I have an RPG sub-procedure
that does all of that, similar to IDATE.

While that is _a_ way to accomplish the task, that is also probably one of the more complicated ways; using a string representation of the /date/ without separators is less work. And starting with a simple arithmetic expression can be /better/, even if just for enabling a value for C [of CYYMMDD] BETWEEN 0 AND 9 to enable conversion for, extending, the domain of dates spanning 1900-01-01 to 2899-12-31


I have a tiny test file I use for testing this stuff; it has a field
called BINARY which holds dates in CYYMMDD form.

Knowing the precision and scale is often imperative, for ensuring a proper expression to convert from a numeric value to a DATE value.

Note: BINARY is a reserved word, so the references to the field name are best made as "BINARY" to avoid errors in composing any SQL requests that might refer to that identifier. Better yet, choose a field name that is not a reserved word :-)

Here are a couple variations of such a table:

create table datesampl7
( "BINARY" dec(7) )
;
create table datesamplA
( "BINARY" int )
;
insert into datesampl7 values
( 0180401 ), ( 0960301 ), ( 1000229 ), ( 1160628 )
, ( 1991231 ), ( 2990101 ), ( 9990101 ), ( 9991231 )
;
insert into datesamplA select * from datesampl7
;

Here is an SQL statement that looks like it'll do the conversion:

select binary,
date(
case
when substr(char(binary), 1, 1) = '1' then '20'
else '19'
end concat
substr(char(binary), 2, 2) concat '-' concat
substr(char(binary), 4, 2) concat '-' concat
substr(char(binary), 6, 2)
) as truedate
from buck.datesample
where binary <> 0;

If the input is 1160628, the output is 2016-06-28
<<SNIP>>

The above expression against the data in my sample variants [i.e. the above query with the table-reference modified in the FROM clause to be either table created\populated in my earlier script] gives mapping errors for the first two values, and assigns the '19' prefix [as incorrect output] for the last three values for which the value of C [of CYYMMDD] is greater than one.

Darryl already alluded to that flaw diagnosed as a mapping error, arising per use of the CHAR vs DIGITS scalar; using CHAR makes the above expression fail for values outside of the domain of the numeric data with date representations 2000-01-01 to 2099-12-31, due to there being no leading zero for those values, thus the substring start-positions are invalid. That effect conspicuously omits support for all of the dates in the 1900s, invalidating the purpose of the C=0 of the CYYMMDD :-( To /fix/ that in the above expression requires that DIGITS be used in the first argument of the SUBSTR scalars with constant start-positions; at least to avoid more CASE logic. I figure no point in offering the revised, and instead offer:

A /better/ solution [albeit not nearly as conspicuous for the effect, as with the formatting of an *ISO date-string], is to take advantage of the 14-digit string format [i.e. no separators] for representation of a TIMESTAMP:

date(digits(dec("BINARY"+19000000 , 8)) concat '000000' )

And while Mike referred to the TIMESTAMP_FORMAT [aka TO_DATE and TO_TIMESTAMP] in [http://archive.midrange.com/midrange-l/201606/msg00544.html], just like the arithmetic expression can be easier than a string expression coming from numeric, the numeric value is easier tested in the CASE expression as a numeric than as an expression for a string result; again [and most likely not an issue], this CASE reduces the C of CYYMMDD to support for just values of '0' and '1', and would produce incorrect output for any larger digit:

date( to_date( case when "BINARY" > 1000000 then '20'
else '19'
end concat substr( digits( "BINARY" ), 2 )
, 'YYYYMMDD' ) )


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.