# Inverting date

**URL:** <https://techcommunity.softwareag.com/t/inverting-date/75866>\
**Category:** Forum\
**Tags:** Adabas-Natural, Natural, Natural-Code-Samples\
**Created:** [December 16, 2007, 9:05pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866 "2007-12-16T21:05:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![John\_Smith](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/john_smith/32/39012_2.png) [@John\_Smith](https://techcommunity.softwareag.com/u/John_Smith)\
**Post date:** [December 16, 2007, 9:05pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/1 "2007-12-16T21:05:11Z")

</div>

Hi,

I would like to know if anyone could provide me a code sample to invert European date DD.MM.YYYY to American date YYYY.MM.DD and vice versa. I don’t want to use day, month and year variables. It seems that there is an easy way to solve it using calculus, for example, multiplying the values. maybe one operation would be enough to invert the date instead of several moves.

If anyone knows how to do it, I’d appreciate receiving the code.

Thanks.

---

<div class="post-metadata">

**Author:** ![Douglas\_Kelly](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/douglas_kelly/32/102_2.png) [@Douglas\_Kelly](https://techcommunity.softwareag.com/u/Douglas_Kelly)\
**Post date:** [December 17, 2007, 1:11pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/2 "2007-12-17T13:11:05Z")

</div>

You could just move the first date value with a MOVE EDITED to a date variable (D), then MOVE EDITED to what ever second format was needed.

```auto
define data
local
01 #date-E (A10) init<'12.25.2007'>
01 #date-i (A10)
01 #date (d)
end-define
move edited #date-e to #date (em=mm.dd.yyyy)
move edited #date (em=yyyy-mm-dd) to #date-i
display #date-e #date-i #date (em=mm/dd/yyyy)
end
```

---

<div class="post-metadata">

**Author:** ![John\_Smith](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/john_smith/32/39012_2.png) [@John\_Smith](https://techcommunity.softwareag.com/u/John_Smith)\
**Post date:** [December 17, 2007, 1:41pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/3 "2007-12-17T13:41:45Z")

</div>

Hi Douglas,

Thank you for the code.

Even though this code is very simply, the code (I’m looking for) used some calculus (math) to get the date (inverted). I have seen this code before, but I cannot remember…

Anyway, if anyone knows how to do it, please let me know.

Thanks.

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [December 17, 2007, 7:16pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/4 "2007-12-17T19:16:49Z")

</div>

There is a reason that you should take a longer look at Douglas’s code.

Suppose you have an alpha variable with contents DD.MM.YYYY. Consider what a mess this would be to convert via a numeric algorithm.

First, you would have to “extract” the values for DD, MM, and YYYY form the alpha variable. This would, of course, be complicated by the possibility that dates exist in a form such as 8.3.2007 rather than 08.03.2007.

Even if you can be assured that such variation does not exist, you would still be faced with the prospects of extracting (e.g. via the use of VAL) numeric values from an alpha field.

This requirement is one of the major uses for Date Format (as in Douglas’s code).

steve

---

<div class="post-metadata">

**Author:** ![Jerome\_LeBlanc](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/jerome_leblanc/32/111_2.png) [@Jerome\_LeBlanc](https://techcommunity.softwareag.com/u/Jerome_LeBlanc)\
**Post date:** [December 17, 2007, 10:07pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/5 "2007-12-17T22:07:54Z")

</div>

> [@Steve Robinson](#):
>
> This would, of course, be complicated by the possibility that dates exist in a form such as 8.3.2007 rather than 08.03.2007.

Steve, That’s not exactly fair. The above complication would befuddle Douglas’ code as well.

It’s an interesting puzzle to try to do this in one line of code. In order to do this using math, I would have to assume that the numbers are stored consistently in N8 fields with leading zeros on day and month. Then I can take advantage of Natural’s penchant for truncating computations and do:

```auto

DEFINE DATA LOCAL                                                    
1 #CYMD (N8) INIT <20071215>                                         
1 #DMCY (N8)                                                         
END-DEFINE                                                           
*                                                                    
COMPUTE #DMCY =                                                      
       (#CYMD - (#CYMD / 100 * 100)) * 1000000 /* dd portion
     + (#CYMD - (#CYMD / 10000 * 10000)) / 100 * 10000 /* mm portion
     + (#CYMD / 10000) /* cy portion
*                                                                    
DISPLAY #CYMD (EM=9999'.'99'.'99)                                    
        #DMCY (EM=99'.'99'.'9999)                                    
```

Which gives:

```auto
   #CYMD #DMCY     
 ---------- ----------  
  2007.12.31 31.12.2007  
```

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [December 17, 2007, 11:27pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/6 "2007-12-17T23:27:28Z")

</div>

Hi Jerome;

Your assumption is not exactly fair either 🙂

The original statement of the problem shows what must be alpha fields (e.g. DD.MM.YYYY). Hence, if nothing else, your code, imaginative as it is, would first require something like EXAMINE #CYMD-ALPHA FOR ‘.’ DELETE; followed by a MOVE of sorts to create a numeric field in the N8 format; whoops, still a problem with the possible anomolies like D.M.YYYY

A SEPARATE of #CYMD-ALPHA into #DAY #M #Y WITH DELIMITER ‘.’ would set up the components for a COMPRESS into the desired formats without any MOVE EDITED statements.

Yes, I saw John’s note to avoid month, day and year variables. I simply do not understand why one would write a lengthy arithmetic statement, following extraction of numeric values from an alpha field, rather than a simple SEPARATE-COMPRESS duo.

steve

---

<div class="post-metadata">

**Author:** ![Jerome\_LeBlanc](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/jerome_leblanc/32/111_2.png) [@Jerome\_LeBlanc](https://techcommunity.softwareag.com/u/Jerome_LeBlanc)\
**Post date:** [December 17, 2007, 11:47pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/7 "2007-12-17T23:47:24Z")

</div>

I didn’t say it was a good solution, just an interesting puzzle. I would use Douglas’ code, with the addition of a mask check before the first move edited to prevent Nat 1143 errors.

```auto

if #date-e = mask (mm'.'dd'.'yyyy)
  move edited #date-e to #date (em=mm.dd.yyyy) 
  move edited #date (em=yyyy.mm.dd) to #date-i 
end-if
```

---

<div class="post-metadata">

**Author:** ![Helmut\_Spichtinger](https://avatars.discourse-cdn.com/v4/letter/h/e0b2c6/32.png) [@Helmut\_Spichtinger](https://techcommunity.softwareag.com/u/Helmut_Spichtinger)\
**Post date:** [December 18, 2007, 6:17pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/8 "2007-12-18T18:17:58Z")

</div>

> [@John Smith](#):
>
> … maybe one operation would be enough to invert the date instead of several moves.

You can accomplish the inversion with one operation by using the COMPRESS statement and by redefining the date variable according to the american date YYYY.MM.DD and the european date DD.MM.YYYY.

```auto
DEFINE DATA LOCAL                                           
1 #DATE (A10) INIT <'2007.12.25'>            
1 REDEFINE #DATE /* redefinition for YYYY.MM.DD 
  2 #YYYY-A (A4)                                 
  2 #MM-A (A4)                                 
  2 #DD-A (A2)                                 
1 REDEFINE #DATE /* redefinition for DD.MM.YYYY 
  2 #DD-E (A2)                                 
  2 #MM-E (A4)                                 
  2 #YYYY-E (A4)                                 
END-DEFINE                                                  
WRITE #DATE '<-- initial YYYY.MM.DD format'                 
*                                                           
COMPRESS #DD-A #MM-A #YYYY-A INTO #DATE LEAVING NO       
WRITE #DATE '<-- DD.MM.YYYY date format'                   
*                                                           
COMPRESS #YYYY-E #MM-E #DD-E INTO #DATE LEAVING NO        
WRITE #DATE '<-- converted back to YYYY.MM.DD date format' 
*                                                           
END
```

---

<div class="post-metadata">

**Author:** ![Helmut\_Spichtinger](https://avatars.discourse-cdn.com/v4/letter/h/e0b2c6/32.png) [@Helmut\_Spichtinger](https://techcommunity.softwareag.com/u/Helmut_Spichtinger)\
**Post date:** [December 18, 2007, 7:21pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/9 "2007-12-18T19:21:35Z")

</div>

> [@Jerome LeBlanc](#):
>
> I didn’t say it was a good solution, just an interesting puzzle. I would use Douglas’ code, with the addition of a mask check before the first move edited to prevent Nat 1143 errors.
> 
> ```auto
> 
> if #date-e = mask (mm'.'dd'.'yyyy)
> move edited #date-e to #date (em=mm.dd.yyyy) 
> move edited #date (em=yyyy.mm.dd) to #date-i 
> end-if
> ```

Your mask check only works, if the compiler option MASKCME is set to ON. If not, the check will not recognize invalid years to prevent NAT1143.  
(valid years are in the range of 1582 - 2699).

If the compiler option MASKCME is set to OFF, you should code the mask check:

```auto
IF #DATE-E EQ MASK(MM.DD.YYYY)        
  AND #DATE-E EQ MASK(......1582-2699)
```

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [December 19, 2007, 12:01am UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/10 "2007-12-19T00:01:20Z")

</div>

Hi Helmut;

Thought about the single COMPRESS. However, it does not “solve” the problem of dates that do not have leading zeroes (e.g. 3.7.2007, or, what I have also seen a lot of; 10/3/07).

The SEPARATE before the COMPRESS takes care of values that do not “fill” the typical allocated space.

steve

---

<div class="post-metadata">

**Author:** ![John\_Smith](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/john_smith/32/39012_2.png) [@John\_Smith](https://techcommunity.softwareag.com/u/John_Smith)\
**Post date:** [December 20, 2007, 4:37am UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/11 "2007-12-20T04:37:24Z")

</div>

Hi,

Thank for this good discussion. I have to say that everyone is correct in your position. Jerome solved the problem using one line and math, even though we have some limitations. Douglas wrote an excellent code and it is complete.

If anyone have other suggestion how to solve it, please let me know.

Thanks for everyone.

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [December 20, 2007, 5:26pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/12 "2007-12-20T17:26:44Z")

</div>

"Douglas wrote an excellent code and it is complete. "

And it is also over ten times as expensive (elapsed and cpu) as it should be. See the following timing comparison.

I used the COMPRESS without the SEPARATE since the computation code also assumes that the data is precisely in YYYYMMDD format without any missing digits.

Please note the COMPRESS is also just one statement; unless you want to count the REDEFINE variables.

DEFINE DATA LOCAL  
1 #CYMD (N8) INIT \<20071215\>  
1 REDEFINE #CYMD  
2 #Y (A4)  
2 #M (A2)  
2 #D (A2)  
1 #DMCY (N8)  
1 #OUT (A8)  
1 #LOOP (I4)  
1 #CPU-START (I4)  
1 #CPU-ELAPSED (I4)  
END-DEFINE  
\*  
MOVE _CPU-TIME TO #CPU-START  
SETA. SETTIME  
FOR #LOOP = 1 TO 10000  
COMPUTE #DMCY =  
(#CYMD - (#CYMD / 100 \* 100)) \* 1000000 /_ dd portion  
+ (#CYMD - (#CYMD / 10000 \* 10000)) / 100 \* 10000 /\* mm portion  
+ (#CYMD / 10000) /\* cy portion  
END-FOR  
COMPUTE #CPU-ELAPSED = \*CPU-TIME - #CPU-START  
WRITE 5T ‘compute’ \*TIMD (SETA.) #CPU-ELAPSED  
\*  
MOVE \*CPU-TIME TO #CPU-START  
SETB. SETTIME  
FOR #LOOP = 1 TO 10000  
COMPRESS #M #D #Y INTO #OUT LEAVING NO SPACE  
END-FOR  
COMPUTE #CPU-ELAPSED = \*CPU-TIME - #CPU-START  
WRITE 5T ‘compress’ \*TIMD (SETB.) #CPU-ELAPSED  
\*  
MOVE \*CPU-TIME TO #CPU-START  
SETC. SETTIME  
FOR #LOOP = 1 TO 10000  
IGNORE  
END-FOR  
COMPUTE #CPU-ELAPSED = \*CPU-TIME - #CPU-START  
WRITE 5T ‘FOR loop’ \*TIMD (SETC.) #CPU-ELAPSED  
END

Page 1 07-12-20 06:54:38

```
compute 12 120
compress 1 8
FOR loop 0 2

```

steve

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [December 20, 2007, 5:37pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/13 "2007-12-20T17:37:02Z")

</div>

Sorry. Mea Culpa. The arithmetic code was Jerome’s, not Doug’s.

Got that backwards.

The COMPRESS also is more efficient than the two MOVE EDITED solution

Page 1 07-12-20 07:08:40

```
move edited 2 18
compress 1 8
FOR loop 0 2

```

However, the MOVE EDITED is nowhere near as slow as the arithmetic solution

steve

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [December 20, 2007, 6:11pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/14 "2007-12-20T18:11:24Z")

</div>

One more note; then I will drop this. The times above were on my PC. Since arithmetic is proportionately faster on the mainframe (compared to complex statements like COMPRESS), I also just ran the code on the mainframe. The times below are for ten times the number of iterations:

First the COMPUTE versus the COMPRESS

compute 5 45  
compress 1 15  
FOR loop 0 6

Now the COMPUTE versus the MOVE EDITED

move edited 3 33  
compress 1 15  
FOR loop 0 6

Although the ratios have changed, the COMPRESS is still at least twice as fast as the MOVE EDITED and three times as fast as the COMPUTE.

steve

---

<div class="post-metadata">

**Author:** ![Jerome\_LeBlanc](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/jerome_leblanc/32/111_2.png) [@Jerome\_LeBlanc](https://techcommunity.softwareag.com/u/Jerome_LeBlanc)\
**Post date:** [December 20, 2007, 9:35pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/15 "2007-12-20T21:35:26Z")

</div>

But, if you are really looking for efficiency, and we can redefine the date fields as needed, MOVE BY NAME is much better. Starting with Steve’s test program, I redefined the dates as follows:

```auto
1 #CYMD (N8) INIT <20071215> 
1 REDEFINE #CYMD             
  2 #CYMD-A (A8)             
1 REDEFINE #CYMD             
  2 #CYMD-G                  
    3 #Y (A4)                
    3 #M (A2)                
    3 #D (A2)                
1 #DMCY (N8)                 
1 REDEFINE #DMCY             
  2 #DMCY-A (A8)             
1 REDEFINE #DMCY             
  2 #DMCY-G                  
    3 #D (A2)                
    3 #M (A2)                
    3 #Y (A4)                
```

Then added another for loop with MOVE BY NAME #CYMD-G TO #DMCY-G  
I had to increase the iterations to 500,000 for our mainframe and got the following results:

```auto
compute 4 34
compress 3 28
move edited 17 139
move by name 0 4
FOR loop 0 4
```

I can’t explain the relative differences between my numbers and Steve’s. My compute is much closer to compress than his and move edited for me is significantly less efficient. But it is clear on our system that move by name has almost no overhead.

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [December 21, 2007, 12:13am UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/16 "2007-12-21T00:13:22Z")

</div>

Taking this to its logical conclusion; I decided to test the MOVE BY NAME versus three MOVE’s. The following are PC V6 times

move by name 5 54  
three move 5 48  
FOR loop 2 19

Later today I will logon to the mainframe and run the code there. also will check the output from the other runs. i too do not understand the differences between Jerome’s times and mine. If nothing else, the CPU-TIMEs should be proportionate, whereas the elapsed times could reflect different background “noise”

steve

---

<div class="post-metadata">

**Author:** ![Douglas\_Kelly](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/douglas_kelly/32/102_2.png) [@Douglas\_Kelly](https://techcommunity.softwareag.com/u/Douglas_Kelly)\
**Post date:** [December 21, 2007, 12:23am UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/17 "2007-12-21T00:23:45Z")

</div>

while you’re at it - are any of the mainframe times using the Optimizing Compiler (NOC)?

---

<div class="post-metadata">

**Author:** ![Jerome\_LeBlanc](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/jerome_leblanc/32/111_2.png) [@Jerome\_LeBlanc](https://techcommunity.softwareag.com/u/Jerome_LeBlanc)\
**Post date:** [December 21, 2007, 12:27am UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/18 "2007-12-21T00:27:14Z")

</div>

Douglas, that thought just occurred to me. Our site recently installed NOC and that makes the difference between my numbers and Steve’s. Here is a comparison:

```auto
NOC Disabled:
 compute 23 226  
 compress 8 78  
 move edited 16 164  
 move by name 5 55  
 FOR loop 3 36  

NOC Enabled:
 compute 3 34  
 compress 2 28  
 move edited 14 139  
 move by name 0 4  
 FOR loop 0 4  
```

It is interesting that MOVE EDITED does not gain much from NOC.

---

<div class="post-metadata">

**Author:** ![Steve\_Robinson](https://sea1.discourse-cdn.com/techcommunity/user_avatar/techcommunity.softwareag.com/steve_robinson/32/107_2.png) [@Steve\_Robinson](https://techcommunity.softwareag.com/u/Steve_Robinson)\
**Post date:** [December 21, 2007, 2:18am UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/19 "2007-12-21T02:18:10Z")

</div>

Hi Jerome;

well that does certainly clear up one mystery.

On the mainframe my results (500,000 iterations; pc numbers were only 100,000)

move by name 5 47  
three move 6 57  
FOR loop 4 30

So these two approaches “flip flopped” from the PC. (why?? behind the scenes the MOVE BY NAME has to be doing the same three moves).

The two MOVE EDITEDs to/from date format are basically just computations (no. of years \* 365 + extra leap year days - century days + century days/4). I too would have thought they would benefit from NOC.

The point of all this is how much CPU time can be saved for a seemingly insignificant piece of code. Depending on the application, this could be performed millions of times a day. Pretty soon, it all adds up to a significant amount of time.

steve

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/techcommunity/original/3X/c/d/cd19967bb605d28a72d77eb83a1cae22f3df2eb8.svg) [@system](https://techcommunity.softwareag.com/u/system)\
**Post date:** [April 2, 2021, 2:49pm UTC](https://techcommunity.softwareag.com/t/inverting-date/75866/20 "2021-04-02T14:49:00Z")

</div>


