Java tutorial
/* * Copyright (C) 2016 normal * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package libepg.epg.util.datetime; import libepg.util.bytearray.ByteConverter; import java.lang.invoke.MethodHandles; import java.text.DecimalFormat; import java.text.MessageFormat; import java.text.ParseException; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang3.Range; import org.apache.commons.logging.Log; import java.util.Arrays; import epgtools.loggerfactory.LoggerFactory; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.ArrayUtils; import libepg.util.bytearray.ByteDataBlock; /** * * @author normal */ public class DateTimeFieldConverter { /** * ???? */ private static final ByteDataBlock UNDEFINED_MJD_DATE_BLOCK = new ByteDataBlock( new byte[] { (byte) 0xff, (byte) 0xff }); /** * ???? */ private static final ByteDataBlock UNDEFINED_BCD_TIME_BLOCK = new ByteDataBlock( new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff }); /** * ???? */ private static final ByteDataBlock UNDEFINED_DATETIME_BLOCK = new ByteDataBlock( ArrayUtils.addAll(UNDEFINED_MJD_DATE_BLOCK.getData(), UNDEFINED_BCD_TIME_BLOCK.getData())); /** * false????????????? */ public static final boolean CLASS_LOG_OUTPUT_MODE = true; private static final Log LOG; static { final Class<?> myClass = MethodHandles.lookup().lookupClass(); LOG = new LoggerFactory(myClass, DateTimeFieldConverter.CLASS_LOG_OUTPUT_MODE).getLOG(); } private static final String DATE_PATTERN = "yyyyMMddHHmmss"; //1?????????0???2??? private static final DecimalFormat ZERO_FILL_FORMAT = new DecimalFormat("00"); private DateTimeFieldConverter() { } /** * ?yyyymmdd????? 1900 3 1 ?2100 2 28 ?????? * * @param mjd mjd??(16) * @return yyyymmdd?? */ public static synchronized String mjdToString(byte[] mjd) { if (mjd.length != 2) { throw new IndexOutOfBoundsException( "?????2????????"); } if (Arrays.equals(mjd, UNDEFINED_MJD_DATE_BLOCK.getData())) { throw new IllegalArgumentException("???????????"); } int tnum = ByteConverter.bytesToInt(mjd); int yy = (int) ((tnum - 15078.2) / 365.25); int mm = (int) (((tnum - 14956.1) - (int) (yy * 365.25)) / 30.6001); int dd = (tnum - 14956) - (int) (yy * 365.25) - (int) (mm * 30.6001); if (mm == 14 || mm == 15) { yy += 1; mm = mm - 1 - (1 * 12); } else { mm = mm - 1; } yy += 1900; if (LOG.isTraceEnabled()) { LOG.trace("yy=" + yy + " mm=" + mm + " dd=" + dd); } StringBuilder sb = new StringBuilder(); sb.append(yy); sb.append(ZERO_FILL_FORMAT.format(mm)); sb.append(ZERO_FILL_FORMAT.format(dd)); return sb.toString(); } private static enum HMS_KEY { HOUR, MINUTE, SECOND; } private static Map<HMS_KEY, Integer> BcdTimeToMap(byte[] hms) throws ParseException { Map<HMS_KEY, Integer> ret = new HashMap<>(); if (hms.length != 3) { throw new IndexOutOfBoundsException( "?????3????????" + " ?=" + Hex.encodeHexString(hms)); } //ARIB???????????????? if (Arrays.equals(hms, UNDEFINED_BCD_TIME_BLOCK.getData())) { throw new ParseException("???????????" + " ?=" + Hex.encodeHexString(hms), 0); } Object[] parameters = null; final int hour = new BCD(hms[0]).getDecimal(); final int minute = new BCD(hms[1]).getDecimal(); final int second = new BCD(hms[2]).getDecimal(); CHECK: { final Range<Integer> HOUR_RANGE = Range.between(0, 23); if (!HOUR_RANGE.contains(hour)) { parameters = new Object[] { Hex.encodeHexString(hms), "", hour }; break CHECK; } final Range<Integer> MINUTE_AND_SECOND_RANGE = Range.between(0, 59); if (!MINUTE_AND_SECOND_RANGE.contains(minute)) { parameters = new Object[] { Hex.encodeHexString(hms), "", minute }; break CHECK; } if (!MINUTE_AND_SECOND_RANGE.contains(second)) { parameters = new Object[] { Hex.encodeHexString(hms), "", second }; break CHECK; } } if (parameters != null) { MessageFormat msg = new MessageFormat( "????????????={0} ={1} ={2}"); throw new ParseException(msg.format(parameters), 0); } if (LOG.isTraceEnabled()) { LOG.trace("hour=" + hour + " minute=" + minute + " second=" + second); } ret.put(HMS_KEY.HOUR, hour); ret.put(HMS_KEY.MINUTE, minute); ret.put(HMS_KEY.SECOND, second); return ret; } private static String BcdTimeToString(byte[] hms) throws ParseException { Map<HMS_KEY, Integer> m = BcdTimeToMap(hms); StringBuilder sb = new StringBuilder(); sb.append(ZERO_FILL_FORMAT.format(m.get(HMS_KEY.HOUR))); sb.append(ZERO_FILL_FORMAT.format(m.get(HMS_KEY.MINUTE))); sb.append(ZERO_FILL_FORMAT.format(m.get(HMS_KEY.SECOND))); return sb.toString(); } /** * (24)6?4210(BCD)????byte?(01:45:30?0x014530????)????????<br> * ((h*60)+m)*60+s<br> * * @param hms * @return ??????? * @throws java.text.ParseException BCD????????????????? */ public static synchronized long BcdTimeToSecond(byte[] hms) throws ParseException { Map<HMS_KEY, Integer> m = BcdTimeToMap(hms); long ret = m.get(HMS_KEY.HOUR) * 60; ret = (ret + m.get(HMS_KEY.MINUTE)) * 60; ret = ret + m.get(HMS_KEY.SECOND); return ret; } /** * ?????java.sql.Timestamp??? <br> * MJD ??16 16 ??????246?4210BCD???<br> * ?????????????1??? <br> * 93/10/13 12:45:00?0xC079124500???? * * @param source * @return ???Timestamp * @throws IndexOutOfBoundsException ?????5??? * @throws java.text.ParseException ??????1???????????????? * */ public static synchronized java.sql.Timestamp BytesToSqlDateTime(byte[] source) throws ParseException { if (source.length != 5) { throw new IndexOutOfBoundsException( "?????5????????" + " ?=" + Hex.encodeHexString(source)); } if (Arrays.equals(source, UNDEFINED_DATETIME_BLOCK.getData())) { throw new ParseException("?????????? ? = " + Hex.encodeHexString(source), 0); } StringBuilder sb = new StringBuilder(); byte[] mjd = new byte[2]; System.arraycopy(source, 0, mjd, 0, mjd.length); sb.append(mjdToString(mjd)); byte[] hms = new byte[3]; System.arraycopy(source, 2, hms, 0, hms.length); sb.append(BcdTimeToString(hms)); String dateStr = sb.toString(); java.text.SimpleDateFormat dateParser = new java.text.SimpleDateFormat(DATE_PATTERN); dateParser.setLenient(false); long dt = dateParser.parse(dateStr).getTime(); if (LOG.isTraceEnabled()) { LOG.trace(dt); } return new java.sql.Timestamp(dt); } }