我有一个数据库表,该表通过ETL填充了来自大型机的数据。
该表的一列在“每日时间”中称为“ TOD”。
该列存储诸如以下值:
“ CAE7631DC43DC686”
“ CAE7631C4AC6DC0B”
“ CAE6216DF2BC0D04”
“ CAE621D8F9916E8E”
所有这些值都在2013年2月10日和2013年2月11日左右。
现在,在大型机上,这是一个时间日期表示形式(TOD时钟)。
它表示从01.01.1900开始经过的时间(以毫秒为单位)(1/1 000 000秒)。
我需要的是一个Java库/方法/算法实现,可以将这些字符串转换为java.util.Date。
在网上找到了这些网站:
http://paul.saers.com/Tod_howto.html
http://www.longpelaexpertise.com.au/toolsTOD.php
本页说明了如何计算,但对我来说有点过多。
我确定我会在某个地方犯一些错误。
所以,我的问题是;您知道我可以使用的图书馆(Joda Time吗?)吗?
我需要将这些值转换为java.util.Date,并将Date对象转换为字符串表示形式(例如“ CAE621D8F9916E8E”)。
提前致谢。
最佳答案
使用Joda逐步操作:
可以找到计算中使用的数据on the website you referred to other reference you gave指出TOD以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);
给出以下输出:
结果为2013-02-10T21:59:46.420Z或以时区表示
EET 2013-02-10T23:59:46.420 + 02:00
我所指的“任务”解释如下:
我们跳过最后12位(通常,MVS使用这些位中的某些位来告诉使用什么处理器读取TOD时钟以及激活了哪个LPAR)。
当然,除了残酷地从字符串中截取这些字节外,还可以
bi = bi.divide(new BigInteger("1000", 16));
因为除以十六进制1000也会去除最后的12位。
编辑:正如Mehmet在评论中指出的那样,TOD是UTC,这意味着应该告知生成的DateTime。为了方便起见,我还展示了如何将DateTime转换为另一个时区(以
EET
为例)