我有一个数据库表,其中通过ETL填充了来自大型机的数据。该表中的一列称为"TOD“,如Time- of -Day。
此列存储以下值:"CAE7631DC43DC686“"CAE7631C4AC6DC0B”"CAE6216DF2BC0D04“"CAE621D8F9916E8E”
所有这些值都在2013年2月10日和2013年2月11日左右。现在,在大型机上,这是一个时间-日期表示(TOD时钟)。
它表示从01.01.1900过去的时间,单位为宏秒(1/1 000000秒)。
我需要的是一个java库/方法/算法实现,它可以将这些字符串转换为java.util.Date。
在web上找到了这些站点:http://paul.saers.com/Tod_howto.html http://www.longpelaexpertise.com.au/toolsTOD.php
这一页解释了如何计算它,但它对我来说有点太多了。我肯定我会在某个地方犯一些错误。
所以,我的问题是:你知道图书馆(Joda Time吗?)我能用到的吗?我需要将这些值转换为java.util.Date,并将Date对象转换为字符串表示形式(如"CAE621D8F9916E8E")。
提前谢谢。
发布于 2013-02-12 02:08:22
一步一步,使用Joda:
计算中使用的数据可以在other reference you gave中找到,TOD是以协调世界时为单位表示的
// 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位(通常,这些位中的一些位被
用来告诉哪个处理器被用来读取TOD时钟,以及哪个LPAR是活动的)。
当然,也可以这样做,而不是粗暴地从字符串中截取这些字节
bi = bi.divide(new BigInteger("1000", 16));除以十六进制1000也会去掉最后12位。
编辑:正如Mehmet在评论中指出的那样,TOD是协调世界时的,这意味着结果DateTime应该被告知。为方便起见,我还展示了如何将该DateTime转置到另一个时区(以EET为例)
发布于 2015-09-24 15:10:21
在我的用例中,我有一个getter方法,它直接读取8字节的TOD作为字节数组,并将其转换为long,但这里是为了遵守海报:
BigInteger bi = new BigInteger ("CAE7631DC43DC686", 16); // no strip off of 686
long tod = bi2.longValue();我使用以下方法来避免BigDecimal计算开销:
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)));输出将为:
22:59:46.420欧洲中部时间+0100
10.02.2013
发布于 2013-02-12 01:31:34
使用BigInteger解析十六进制日期:
new BigInteger("CAE7631DC43DC686", 16);然后使用BigInteger提供的各种方法(乘法,...)对Unix纪元进行必要的转换。
https://stackoverflow.com/questions/14817202
复制相似问题