记一次Excel读取时间格式遇到的问题

本文探讨如何处理Excel中的公式单元格,识别其NUMERIC类型并转换为日期后遇到的问题,揭示了时间计算的秘密,介绍了如何通过计算时间戳还原原始时间格式。重点在于使用getSumHours方法解析1900年1月1日计时法的技巧。
摘要由CSDN通过智能技术生成
  • 如图所示单元格数据是通过公式计算累加得到
    在这里插入图片描述

  • 当读取该单元格时,可以发现单元格数据类型为FORMULA
    在这里插入图片描述

  • 我们先尝试直接读取String,很显然报错了,并且提示我们,该单元格是数字
    在这里插入图片描述

  • 经过验证也确实是NUMERIC:
    在这里插入图片描述

  • 既然是NUMERIC,我们再尝试判断是否日期类型(日期类型也属于NUMERIC类型),得到的结果是确实日期类型:
    在这里插入图片描述

  • 尝试获取日期类型的值, 很遗憾,得到的是这样一个日期,很显然不是我们想要的结果:
    在这里插入图片描述

  • 再次尝试,先转换为String,再读取:
    在这里插入图片描述
    这回不报错了,但读取到的仍然不是我们想要的结果

  • 最后再观察 1900-01-16 20:30:00 这个时间, 16 * 24 + 20 = 404, 而excel中的数据正好是404:30, 可以猜想,这个时间是以1900年1月1日开始计算的?
    在这里插入图片描述

  • 这样的话我们只需要用这个时间计算出时间戳减去开始的(经过验证是1899-12-31 00:00:00)时间戳,得到这个时间的毫秒数,然后再经过取余等计算即可得到excel中的原样字符串(风转成工具类如下, hasSecond为true时带秒数,false不带秒数):

    /**
     * 一小时对应的毫秒数
     */
    public static final int HOUR_MILLISECOND = 1000 * 60 * 60;

    /**
     * 一分钟对应的毫秒数
     */
    public static final int MINUTE_MILLISECOND= 1000 * 60;

    /**
     * 1899-12-31 00:00:00 对应的时间戳毫秒数
     */
    public static final long TIMESTAMP_OF_1899_12_31 = -2209104000000L;
    public static String getSumHours(String dateStr, boolean hasSecond) {
        Date date = ImportExportUtil.parseDate(dateStr, null);
        if (StringUtils.isBlank(dateStr)) {
            return dateStr;
        }
        if (date == null) {
            return dateStr;
        }
        long difference = date.getTime() - Constant.TIMESTAMP_OF_1899_12_31;
        long hour = difference / Constant.HOUR_MILLISECOND;
        long minute = (difference % Constant.HOUR_MILLISECOND) / Constant.MINUTE_MILLISECOND;
        long second = (difference % Constant.MINUTE_MILLISECOND) / 1000;
        // 分钟只有1位时补0
        String result = hour + ":" + (minute < 10 ? "0" + minute : minute);
        if (hasSecond) {
            // 秒钟只有1位时补0
            result += ":" + (second < 10 ? "0" + second : second);
        }
        return result;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值