SimpleDateFormat - 日,月,时间不正确

时间:2015-02-11 05:42:19

标签: java simpledateformat unix-timestamp

此代码将十六进制(radix16)格式的供应商专有时间戳转换为Unix时间。我从Java文档中知道SimpleDateFormat是从零开始的月份(Jan=0),但是,当使用格式字符串从Unix时间戳转换为人类可读格式时,无论是月,日也不是时间是正确的(参见结尾附近的评论结果)。

预期:

Yr 2010 Mo 1 Da 4 Time 13513407 (03:45:13:407).  

结果:

HR:20100205_032123239.  

月份为02而不是01(按预期方式),但该日期为05而非04。小时(03)是正确的,但minssecsmillis不是。

我在评论中包含了用于测试的通过“text”值。

public static long parseUnsignedHex(String text) {
    // text = "07DA010400CE32BF"
    long bsUnixTs = 0;
    if (text.length() == 16) {
        String bsYr = text.substring(1, 4);
        String bsMo = text.substring(5,6);
        String bsDa = text.substring(7,8);
        String bsTime = text.substring(9,16);
        try {
            long bsYrL = Long.decode("0x" + bsYr);
            long bsMoL = Long.decode("0x" + bsMo);
            long bsDaL = Long.decode("0x" + bsDa);
            long bsTimeL = Long.decode("0x" + bsTime);
            Calendar bsCal = Calendar.getInstance();
            bsCal.set((int)bsYrL, (int)bsMoL, (int)bsDaL);
            bsCal.setTimeInMillis(bsCal.getTimeInMillis() + bsTimeL);
            bsUnixTs = bsCal.getTimeInMillis();
            System.out.printf("Yr %d Mo %d Da %d Time %d%n", bsYrL, bsMoL, bsDaL, bsTimeL);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (Throwable e){
            e.printStackTrace();
        }
    }
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmssSSS");
    // convert unix into yyyyMMdd_HHmmssSSS Human Readable (HR) format
    String[][] arTimeString = new String[1][2];
    for(int i=0; i<arTimeString.length; i++){
        arTimeString[i][0] = Long.toString(bsUnixTs);
        arTimeString[i][1] = sdf.format(bsUnixTs);
        try {
                System.out.format("Unix:" + arTimeString[i][0] + " HR:" + arTimeString[i][1]);
                System.out.println();
                // result:
                // SimpleDateFormat - month is zero-based
                //                    the day of month may be incremented because the time is 03:45:13:407
                // Yr 2010 Mo 1 Da 4 Time 13513407
                // Unix:1265358083239 HR:20100205_032123239
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    return bsUnixTs;
}

1 个答案:

答案 0 :(得分:1)

基本上,改变......

Calendar bsCal = Calendar.getInstance();
bsCal.set((int)bsYrL, (int)bsMoL, (int)bsDaL);
bsCal.setTimeInMillis(bsCal.getTimeInMillis() + bsTimeL);

Calendar bsCal = Calendar.getInstance();
bsCal.set((int) bsYrL, (int) bsMoL - 1, (int) bsDaL, 0, 0);
bsCal.set(Calendar.SECOND, 0);
bsCal.set(Calendar.MILLISECOND, 0);

这将导致输出

Yr 2010 Mo 1 Da 4 Time 13513407
Unix:1262537113407 HR:20100104_034513407

Calendar使用基于0的月份,而不是SimpleDateFormat,当使用Calendar#set时,它只会影响您提供的字段,只留下hourminutesecond以及millisconds与创建Calendar时相比没有变化(这是该时间/日期值的快照)

原始代码所做的是捕获当前日期和时间的快照,重置年,月和日值,为CURRENT时间添加额外的时间值......