JAVA导入Excel后,时间变为数字,转日期方法

博客主要介绍了Excel导入相关内容。一是通常Excel导入后获取时间数据的情况;二是当不使用poi等工具,导入后日期显示为数字时,需保存时间戳到数据库,还给出了校验日期格式的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、先说一下通常的Excel 导入:

           Excel 导入后,获取时间数据: <在这里 format 就是时间格式>

    private static String getCellStringVal(Cell cell, String format) {
        CellType cellType = cell.getCellTypeEnum();
        switch (cellType) {
            case NUMERIC:
                String value;
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    Date date = cell.getDateCellValue();
                    value = TimeTool.dateToFormatTime(date, format);
                } else {
                    double dValue = cell.getNumericCellValue();
                    DecimalFormat df = new DecimalFormat("0");
                    value = df.format(dValue);
                }
                return value;
            case STRING:
                return cell.getStringCellValue();
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            case BLANK:
                return "";
            case ERROR:
                return String.valueOf(cell.getErrorCellValue());
            default:
                return "";
        }
    }

 

二、如果说我们使用的不是poi,或者其他。导入后日期为数字:

           getTime();// ditNumber = 43607.4166666667

           这里,我们需要保存时间戳到数据库,所以这里做了判断,且返回String。

           Date、Timestamp已有,需要直接返回即可。

    //Mysql支持的时间戳限制
    static long minTime = Timestamp.valueOf("1970-01-01 09:00:00").getTime();
    static long maxTime = Timestamp.valueOf("2038-01-19 11:00:00").getTime();
    static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

    //判断 并转换时间格式 ditNumber = 43607.4166666667
    public static String getTime(String ditNumber) {
        //如果不是数字
        if(!isNumeric(ditNumber)){
            return null;
        }
        //如果是数字 小于0则 返回
        BigDecimal bd = new BigDecimal(ditNumber);
        int days = bd.intValue();//天数
        int mills = (int) Math.round(bd.subtract(new BigDecimal(days)).doubleValue() * 24 * 3600);

        //获取时间
        Calendar c = Calendar.getInstance();
        c.set(1900, 0, 1);
        c.add(Calendar.DATE, days - 2);
        int hour = mills / 3600;
        int minute = (mills - hour * 3600) / 60;
        int second = mills - hour * 3600 - minute * 60;
        c.set(Calendar.HOUR_OF_DAY, hour);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, second);

        Date d = c.getTime();//Date
        Timestamp t = Timestamp.valueOf(dateFormat.format(c.getTime()));//Timestamp
        try {
            //时间戳区间判断
            if(minTime <= d.getTime() && d.getTime() <= maxTime){
                return dateFormat.format(c.getTime());
            }else{
                return "outOfRange";
            }
        } catch (Exception e) {
            System.out.println("传入日期错误" + c.getTime());
        }
        return "Error";
    }

    //校验是否数据含小数点
    private static boolean isNumeric(String str){
        Pattern pattern = Pattern.compile("[0-9]+\\.*[0-9]*");
        Matcher isNum = pattern.matcher(str);
        if(!isNum.matches()){
            return false;
        }
        return true;
    }

           

 

 

 

 

 

 

 

 

 

 

 

          继上,给大家提供校验日期格式的方法:

   static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
   //传入String,返回boolean
   public static boolean checkDate(String date) {
        if (date != null && date.isEmpty()) {
            try {
                //禁止SimpleDateFormat的自动计算功能,严格解析日期
                dateFormat.setLenient(false);
                dateFormat.parse(date);
            } catch (Exception e) {
                System.out.println("传入日期错误" + date);
                return false;
            }
            return true;
        }
        return false;
    }
    //传入java.util.Date,返回boolean
    public static boolean checkDate(Date date) {
        if (date != null) {
            try {
                //禁止SimpleDateFormat的自动计算功能,严格解析日期
                dateFormat.setLenient(false);
                dateFormat.format(date);
            } catch (Exception e) {
                System.out.println("传入日期错误" + date);
                return false;
            }
            return true;
        }
        return false;
    }

 

 

<think>嗯,用户问的是如何在导入Excel文件正确存储时间数据。首先,我需要回忆一下之前处理Excel导入遇到的常见问题,尤其是时间字段的处理。记得Excel中的日期时间通常是以数字格式存储的,比如从1900年1月1日开始的序列数,或者是1904年后的,这取决于系统设置。如果不处理的话,导入后可能会变成整数或者浮点数,而不是正确的日期格式。 然后,用户提到的参考引用里提到了EasyExcel和PHP-ExcelReader这些工具。我需要结合这些工具来给出解决方案。比如,在使用EasyExcel,可能需要自定义换器来处理时间字段,把Excel的数值换成Java的Date或者LocalDateTime类型。另外,数据库存储的候也需要确保字段类型正确,比如MySQL的DATETIME或DATE类型。 还要考虑区的问题,不同的系统可能有不同的区设置,导致时间显示不一致。这个候需要统一区,或者在指定区。另外,数据校验也很重要,比如检查时间是否在合理范围内,避免无效数据入库。 可能还需要提到处理不同的时间格式,比如有的Excel单元格可能用文本格式存储时间,这候需要解析文本格式的时间字符串,而不是直接读取数值。这候需要用到像DateTimeFormatter这样的工具来解析不同的格式。 另外,用户可能没有明确说出来的问题是,导入候如何避免因为格式不一致导致的错误,比如有些行的时间数据格式不正确,这候需要有异常处理机制,比如跳过错误数据或者记录日志。 最后,可能需要给出一个代码示例,比如使用EasyExcel的@ExcelProperty注解配合自定义换器,或者使用PHP-ExcelReader读取时间格式。还要提醒用户测试不同情况,比如闰年、不同的日期格式等,确保换的准确性。</think>在Excel数据导入过程中,时间字段的处理需要特别注意数据格式换和存储兼容性。以下是分步骤解决方案: ### 一、理解Excel时间存储原理 1. **Excel时间基准**:Windows系统下以1900年1月1日为基准(Mac系统为1904年),时间值以浮点数形式存储,例如: - `1.5`表示1900-01-01 12:00:00 - `44562.75`表示2022-01-01 18:00:00[^2] ### 二、关键处理步骤 1. **数据读取阶段** ```java // EasyExcel自定义换器示例 public class CustomConverter implements Converter<Date> { @Override public Date convertToJavaData(ReadCellData<?> cellData) { double excelValue = cellData.getNumberValue().doubleValue(); return DateUtil.getJavaDate(excelValue); } } ``` 2. **数据库存储配置** ```sql -- MySQL时间字段定义示例 CREATE TABLE import_data ( event_time DATETIME(3) -- 支持毫秒级存储 ); ``` 3. **区统一处理** ```yaml # Spring Boot区配置 spring: jackson: time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss ``` ### 三、常见问题解决方案 1. **格式混合问题**:当单元格同包含日期和文本,使用正则表达式清洗数据: ```java String cleanDate = rawValue.replaceAll("[^0-9/-:]", ""); ``` 2. **跨平台兼容性**: - Windows/Mac时间基准差异需做天数补偿 - 处理闰年错误(Excel误将1900年识别为闰年) ### 四、最佳实践建议 1. 数据验证应包含: ```java if(date.before(minDate) || date.after(maxDate)){ throw new InvalidDataException("时间超出有效范围"); } ``` 2. 使用Joda-Time或java.time替代java.util.Date[^1]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张小帅和刘美美

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值