> On 29. Aug 2017, at 21:51, Dave Day <[email protected]> wrote:
> 
>     Greetings List,
> 
>     I've got an 8 byte value that is the output of a Store Clock instruction 
> on a mainframe.  The value created by the instruction is a 64 bit hex value 
> where  bit 51 is equal to one microsecond. To get a value that is 
> microseconds, the original clock value is shifted to the right 12 bits. The 
> clock started at all 0's on January 1st, 1900.
> 
>     I need to be able to store and do basic math(addition and subtraction) on 
> the value in microseconds.  And, these values will need to be displayed on a 
> browser in HH:MM:SS.TTTTTT format.
> 
>     If I create the decimal value for the integer on the mainframe when 
> creating the XML record, I will have to go thru some conversion logic.  There 
> could be possibly millions of these records in one XML database.
> 
>     It seems to me to make more sense to create the value as a hexBinary 
> element, and then have some code running within  BaseX do the conversion to 
> create the correct time value.
> 
>     Is this the way to do something like this?
> 
>     Regards,
> 
>     -- Dave Day

Hi Dave,

regarding performance a more dedicated approach may be needed.  However, to do 
some first experiments with XML data that originates form the mainframe, BaseX 
has extensions to do bit shifting and conversions.  Following examples can be 
copied into the XQuery editor of the latest BaseX version for testing.

tl;dr:

```xquery
<mainframe>
  <event start="00000000FF"/>
</mainframe>
/event/@start/string()                                => trace('t1: ')
=> convert:integer-from-base(16)                      => trace('t2: ')
=> bin:pack-integer(8, 'big-endian')                  => trace('t3: ')
=> bin:shift(-1)                                      => trace('t4: ')
=> bin:unpack-integer(0, 8, 'big-endian')             => trace('t5: ')
=> convert:integer-to-dateTime()                      => trace('t6: ')
=> fn:format-dateTime("[H01]:[m01]:[s01].[f000001]")  => trace('t7: ')
```

```BaseX Query Info (trace output)
t1: "00000000FF"
t2: 255
t3: xs:base64Binary("AAAAAAAAAP8=")
t4: xs:base64Binary("AAAAAAAAAH8=")
t5: 127
t6: xs:dateTime("1970-01-01T00:00:00.127Z")
t7: "00:00:00.127000"
```

============================================================

long version:

let's assume you have an input xml such as:

  ```xml
  <mainframe>
    <event start="00000000FF"/>
  </mainframe>
  ```
  
- you access the value using XPath as xs:string

  ```xquery
  <mainframe>
    <event start="0" start1="D2DE66B76C0FF200"/>
  </mainframe>
  /event/@start1/string()
  ```
  
  ```result
  D2DE66B76C0FF200
  ```


- from (hex) xs:string to xs:integer one can use [1]: 

  ```signature
  convert:integer-from-base($str as xs:string, $base as xs:integer) as 
xs:integer
  ```

  ```xquery
  convert:integer-from-base('0000000000FF', 16)
  ```
  
  ```result
  255
  ```
  
- bit operations work on xs:base64Binary
  
  - from xs:integer to xs:base64Binary one can use [2]:

  ```signature
  bin:pack-integer($in as xs:integer, $size as xs:integer, $octet-order as 
xs:string) as xs:base64Binary
  ```
    
  ```xquery
  bin:pack-integer(255, 8, 'big-endian')
  ```
  
  ```result
  xs:base64Binary("AAAAAAAAAP8=")
  ```
  
  - to perform bit shifting one can use [3]

  ```signature
        bin:shift($in as xs:base64Binary?, $by as xs:integer) as 
xs:base64Binary?
  ```
  
  ```xquery
  bin:shift(xs:base64Binary("AAAAAAAAAP8="), -1)
  ```
  
  ```result
  xs:base64Binary("AAAAAAAAAH8=")
  ```
  
  - to go back from xs:base64Binary to xs:integer one can use [4]:
  
  ```signature
  bin:unpack-integer($in as xs:base64Binary, $offset as xs:integer, $size as 
xs:integer, $octet-order as xs:string) as xs:integer
  ```
  
  ```xquery
  bin:unpack-integer(xs:base64Binary("AAAAAAAAAH8="), 0, 8, 'big-endian')
  ```
  
  ```result
  127
  ```
  
- to interprete an xs:integer as xs:dateTime one can use [5]

  ```signature
  convert:integer-to-dateTime($ms as xs:integer) as xs:dateTime
  ```

  ```xquery
  convert:integer-to-dateTime(127)
  ```
  
  ```result
  1970-01-01T00:00:00.127Z
  ```
  
- to display an xs:dateTime according to a pattern such as HH:MM:SS.TTTTTT one 
can use [6]

  ```signature
  fn:format-dateTime($value as xs:dateTime?, $picture as xs:string) as 
xs:string?
  ```
  
  ```xquery
  fn:format-dateTime(
    xs:dateTime("1970-01-01T00:00:00.127Z"),
    "[H01]:[m01]:[s01].[f000001]"
  )
  ```
  
  ```result
  00:00:00.127000
  ```

Cheers,
  Alex
  

[1] http://docs.basex.org/wiki/Conversion_Module#convert:integer-from-base
[2] http://docs.basex.org/wiki/Binary_Module#bin:pack-integer
[3] http://docs.basex.org/wiki/Binary_Module#bin:shift
[4] http://docs.basex.org/wiki/Binary_Module#bin:unpack-integer
[5] http://docs.basex.org/wiki/Conversion_Module#convert:integer-to-dateTime
[6] https://www.w3.org/TR/xpath-functions-30/#func-format-dateTime

Reply via email to