TOD clock time to java.util.Date or milliseconds

故事扮演 提交于 2019-12-13 17:00:42

问题


I have a database table, which is filled with data from a mainframe via ETL. One column of that table is called "TOD" as in Time-Of-Day.

This columns stores values such as : "CAE7631DC43DC686" "CAE7631C4AC6DC0B" "CAE6216DF2BC0D04" "CAE621D8F9916E8E"

all these values are around Feb 10th 2013 and Feb 11th 2013. now, on mainframe, this is a time-date representation (TOD clock).

it represents the time past from 01.01.1900 in macroseconds (1/1 000 000 of a second).

What I need is a java library / method / algorithm implementation that could convert these strings to java.util.Date's.

Found these sites on the web : http://paul.saers.com/Tod_howto.html http://www.longpelaexpertise.com.au/toolsTOD.php

This page explains how to calculate it, but it's a little too much for me. I'm sure I'd do some errors somewhere.

So, my question is; do you know about a library (Joda Time ?) that I could use ? I need to convert these value to a java.util.Date and a Date object to a string representation, (like "CAE621D8F9916E8E").

Thanks in advance.


回答1:


Step by step, using Joda:

Data used in the calculation can be found on the website you referred to The other reference you gave states that TOD is expressed in UTC

// we start with your string minus the three last digits
// which are some internal z/Series cruft
BigInteger bi = new BigInteger    ("CAE7631DC43DC", 16); // 686 stripped off
// then, from tables the website we get the TOD value for start of epoch
// here also, minus the three last digits                                 
BigInteger startOfEpoch70 = new BigInteger ("7D91048BCA000", 16); // 000 stripped off
// using that we calculate the offset in microseconds in epoch
BigInteger microsinepoch = bi.subtract(startOfEpoch70);
// and reduce to millis
BigInteger millisinepoch = microsinepoch.divide(new BigInteger("1000"));
// which we convert to a long to feed to Joda
long millisinepochLong = millisinepoch.longValue();
// Et voila, the result in UTC
DateTime result = new DateTime(millisinepochLong).withZone(DateTimeZone.UTC);
// Now, if you want a result in some other timezone, that's equally easy
// with Joda:
DateTime result2 = result.toDateTime(DateTimeZone.forID("EET"));

System.out.println("The result is " + result + " or represented in timezone EET "
                   + result2);

Which gives this output:

The result is 2013-02-10T21:59:46.420Z or represented in timezone EET 2013-02-10T23:59:46.420+02:00

The "cruft" I refer to is explained as follows:

We skip the last 12 bits (normally,some of these bits are used by MVS to tell what processor was used to read the TOD clock and what LPAR was active).

Of course, instead of brutally snipping these bytes off the string, one could also do

bi = bi.divide(new BigInteger("1000", 16));

as dividing by hex 1000 will also get rid of the last 12 bits.

EDIT: as Mehmet pointed out in the comments, TOD is in UTC and this means that the resulting DateTime should be told so. For convenience I also showed how to transpose that DateTime to another time zone (using EET as an example)




回答2:


In my use case I have a getter method that directly reads the 8 bytes TOD as byte array and translates it into a long, but here to adhere to the poster:

BigInteger bi = new BigInteger    ("CAE7631DC43DC686", 16); //  no strip off of 686 
long tod = bi2.longValue();

I used the following to avoid the BigDecimal calculation overhead:

tod = tod >>> 12;  // remove rightmost 3 bytes and replace with zeros
tod = tod - 2208988800000000l;  // substract 1970
tod = tod/1000; // make millis out of micros
// timeformatter and dateformatter without Joda
SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm:ss.SS z Z", Locale.getDefault());
SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy", Locale.getDefault());
// Display
System.out.println(timeFormatter.format(new Date(tod)));
System.out.println(dateFormatter.format(new Date(tod)));

The output will be:

22:59:46.420 CET +0100

10.02.2013




回答3:


Parse your hex date using BigInteger:

new BigInteger("CAE7631DC43DC686", 16);

Then do the necessary conversions to the Unix epoch using the various methods offered by BigInteger (multiply, ...).



来源:https://stackoverflow.com/questions/14817202/tod-clock-time-to-java-util-date-or-milliseconds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!