10

我正在尝试从电子表格中读取日期列和时间列。我可以从工作表中删除日期列,但不能从时间列中删除。

例如,我的工作表将具有以下形式的行:

约会时间

2012 年 11 月 2 日 12:15:01

我有以下代码来获取日期列:

while(cellIterator.hasNext()) {
            HSSFCell cell = (HSSFCell)cellIterator.next();
            switch(cell.getCellType()){
                case HSSFCell.CELL_TYPE_NUMERIC:
                    HSSFCellStyle style = cell.getCellStyle();
                    if (HSSFDateUtil.isCellDateFormatted(cell))
                    {
                        d = (Date)getDateValue(cell);
                        SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
                        System.out.println(dateFormat.format(d));

                    }


            }
        }  

protected static Object getDateValue(HSSFCell cellDate) 
{

         double numericDateValue = cellDate.getNumericCellValue();
         Date date = HSSFDateUtil.getJavaDate(numericDateValue);
         return date;

}

如您所见,我使用

HSSFDateUtil.isCellDateFormatted(单元格)

检查单元格中是否有日期值。我想知道我是否可以使用任何函数检查单元格是否具有时间值。

excel 工作表来自外部来源。因此,我将无法对其格式进行任何修改。

现在,我得到了日期列的正确日期值。但是,对于时间列,我得到

1899 年 12 月 31 日

作为所有行的结果

4

2 回答 2

10

Excel 中日期和时间的快速入门。由于在创建文件格式时很有意义,但现在看起来很混乱,Excel 没有 Date 或 Time 或 DateTime 类型。相反,它拥有的是数字和特殊的格式规则。

这个怎么看?在 Excel 单元格中键入 10.5,然后将其格式化为日期 + 时间。您将在 1900 年 1 月的某个日期获得中午。

因此,当您询问 POI 单元格是否为日期格式时,没有简单的标志/类型可供检查。相反,POI 所能做的就是读取应用于单元格的格式化字符串,并查看它是否看起来像日期一样可疑。

奖励标记 - 尝试存储 1900 年 2 月 28 日,然后添加一个 - Excel 忠实地再现了 1900 年闰年左右的 Lotus 123 错误......

作为一般规则,DateUtil.isCellDateFormatted(cell)将为日期单元格、时间单元格和日期时间单元格返回 true。但是,有时您会得到一种非常奇怪的格式,Excel 知道它是日期或时间,但 POI 无法识别为一种格式。对于那些,您仍然可以要求将单元格值作为日期,POI 会转换它。

因此,在您的情况下,如果 POI 说它是日期格式,则将值作为日期获取。现在,查看格式字符串。如果是日期查找,请格式化为日期。日期和时间看?格式化为您的首选日期 + 时间。只有时间?格式为时间?时区?你一定是在笑...

哦,只要您不使用 1900 年左右的实际日期,您基本上可以只说DateUtil.isCellDateFormatted(cell)+ value < 100 -> 可能只是一个时间(如果是经过的时间,则 >1)。如果你的号码是一个整数,它可能只是一个日期(但它可能是午夜)。如果它是非整数(ish - 记住 excel 使用浮点数),它可能有一个时间组件。

于 2013-04-01T16:20:18.117 回答
10

这是我获取 POI 单元的“仅限日期”、“仅限时间”或“日期时间”值的粗略尝试

    ...
private String getCellValueAsString(Cell poiCell){

    if (poiCell.getCellType()==Cell.CELL_TYPE_NUMERIC && DateUtil.isCellDateFormatted(poiCell)) {
        //get date
        Date date = poiCell.getDateCellValue();

        //set up formatters that will be used below
        SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm:ss");
        SimpleDateFormat formatYearOnly = new SimpleDateFormat("yyyy");

        /*get date year.
        *"Time-only" values have date set to 31-Dec-1899 so if year is "1899"
        * you can assume it is a "time-only" value 
        */
        String dateStamp = formatYearOnly.format(date);

        if (dateStamp.equals("1899")){
            //Return "Time-only" value as String HH:mm:ss
            return formatTime.format(date);
        } else {
            //here you may have a date-only or date-time value

            //get time as String HH:mm:ss 
            String timeStamp =formatTime.format(date);

            if (timeStamp.equals("00:00:00")){
                //if time is 00:00:00 you can assume it is a date only value (but it could be midnight)
                //In this case I'm fine with the default Cell.toString method (returning dd-MMM-yyyy in case of a date value)
                return poiCell.toString();
            } else {
                //return date-time value as "dd-MMM-yyyy HH:mm:ss"
                return poiCell.toString()+" "+timeStamp;
            }
        }
    }

    //use the default Cell.toString method (returning "dd-MMM-yyyy" in case of a date value)
    return poiCell.toString();
}
于 2013-08-09T14:52:23.603 回答