Excel的日期格式约定与解析

Excel的日期格式约定与解析

原理

当Excel单元格内容为=NOW()时,会显示当前的日期/时间,而倘若你将设置为单元格格式改为非日期时间的格式时,会显示一个非负实数。

Excel 支持两个日期系统:1900年日期系统(推荐)和 1904年日期系统。每个日期系统使用日期作为计算的所有其他工作簿中的唯一开始日期。所有版本的 Excel for Windows 都计算基于 1900年日期系统中的日期。Excel 2008 for Mac 和早期 Excel for Mac 版本计算基于 1904年日期系统的日期。Excel 2016 for Mac 和 Excel for Mac 2011 使用 1900年日期系统,保证日期与 Excel for Windows 的兼容性。

正常情况下,就目前而言,这个非负实数的整数位表示该日期距离1900年1月1日的天数,小数位表示该日期的当天时间占据整天时间的比例,因此可以很方便的用代码将其解析成我们的日常使用日期系统。

JAVA实现

// excelDateAnalysis.java

package ms.excelDateAnalysis;

import java.util.Calendar;
import java.util.GregorianCalendar;

public class excelDateAnalysis {
    private static final int SECONDS_PER_MINUTE = 60;
    private static final int MINUTES_PER_HOUR = 60;
    private static final int HOURS_PER_DAY = 24;
    private static final int SECONDS_PER_DAY = (HOURS_PER_DAY    *
                                                MINUTES_PER_HOUR *
                                                SECONDS_PER_MINUTE);

    private boolean onlyTime = false;

    private double excelDate;
    private int sumDay, sumSecond;
    private int year, month, day, week;
    private int hour, minute, second;

    public boolean onlyTime() { return this.onlyTime;  }
    public int getSumDay   () { return this.sumDay;    }
    public int getSumSecond() { return this.sumSecond; }
    public int getYear     () { return this.year;      }
    public int getMonth    () { return this.month;     }
    public int getDay      () { return this.day;       }
    public int getWeek     () { return this.week;      }
    public int getHour     () { return this.hour;      }
    public int getMinute   () { return this.minute;    }
    public int getSecond   () { return this.second;    }

    public void test() {
        excelDateAnalysis eDate = new excelDateAnalysis(this.excelDate);
        System.out.println("sum second in one day: " + eDate.getSumSecond());
        System.out.println("sum days: "+eDate.getSumDay());
        if (!eDate.onlyTime) {
            System.out.println("Date: " + eDate.getYear()  +
                                    "/" + eDate.getMonth() +
                                    "/" + eDate.getDay());
        }
        System.out.println("Time: " + eDate.getHour()   +
                                ":" + eDate.getMinute() +
                                ":" + eDate.getSecond());
    }
    public excelDateAnalysis(double excelDate) {
        this.excelDate = excelDate;
        this.sumDay    = (int)Math.floor(excelDate);
        this.sumSecond = (int)Math.floor((excelDate-(double)this.sumDay)*SECONDS_PER_DAY+0.5);
        sumSecondAnalysis(this.sumSecond);
        sumDayAnalysis(this.sumDay);
    }

    private void sumDayAnalysis(int wholeDays) {
        if (wholeDays==0) {
            this.onlyTime = true;
            return;
        }
        Calendar calendar = new GregorianCalendar();
        boolean use1904windowing = false;
        int startYear = 1900;
        int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't
        if (use1904windowing) {
            startYear = 1904;
            dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day
        } else if (wholeDays < 61) {
            // Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists
            // If Excel date == 2/29/1900, will become 3/1/1900 in Java representation
            dayAdjust = 0;
        }
        calendar.set(startYear,0, wholeDays + dayAdjust, 0, 0, 0);
        calendar.set(GregorianCalendar.MILLISECOND, this.sumSecond*1000);
        this.year  = calendar.get(Calendar.YEAR);
        this.month = calendar.get(Calendar.MONTH)+1;
        this.day   = calendar.get(Calendar.DAY_OF_MONTH);
        this.week  = calendar.get(Calendar.DAY_OF_WEEK)-1;
    }
    private void sumSecondAnalysis(int sumSecond) {
        this.hour   = sumSecond / SECONDS_PER_MINUTE / MINUTES_PER_HOUR;
        this.minute = sumSecond / SECONDS_PER_MINUTE - this.hour * MINUTES_PER_HOUR;
        this.second = sumSecond % SECONDS_PER_MINUTE;
    }
}

使用起来也很简单:

// Main.java

import ms.excelDateAnalysis.*;

public class Main {
    public static void main(String[] args) {
        excelDateAnalysis eDate = new excelDateAnalysis(43529.50258);
        eDate.test(); // 测试输出
    }
}

二级办公AOA中的应用

E练习3-03(员工信息表).xlsx 操作要求(2)在Sheet4中,使用函数,将B1中的时间四舍五入到最接近的15分钟的倍数,结果存放在C1单元格中。
Sheet4.B1 <- {自定义}[13:49:38]

利用Excel内建日期函数和四舍五入函数是能解决这道题目的(=TIME(HOUR(B1),15*ROUND(MINUTE(B1)/15,0),SECOND(0))),但问题是太过繁琐,不够直接,我们用本文提到的原理来解决。

60*24 = 1440

步骤 公式 解释
1 B1*1440 总分钟数
2 Round(B1*1440/15,0)*15 让总分钟数变成15分钟的倍数
3 Round(B1*1440/15,0)*15/1440 将变成更改后的总分钟数变回默认时间约定

Sheet4.C1 <- {自定义}[=Round(B1*1440/15,0)*15/1440]

13:49:38 === 0.576134259

娱乐时间

    excelDateAnalysis eDatePI = new excelDateAnalysis(Math.PI);
    eDatePI.test();
    excelDateAnalysis eDateE = new excelDateAnalysis(Math.E);
    eDateE.test();
sum second in one day: 12234
sum days: 3
Date: 1900/1/3
Time: 3:23:54
sum second in one day: 62060
sum days: 2
Date: 1900/1/2
Time: 17:14:20

原文地址:https://www.cnblogs.com/unixart/p/10475960.html

时间: 2024-11-17 14:33:49

Excel的日期格式约定与解析的相关文章

excel表格日期格式强制修改

症状: 收集上来的各部门填写的excel表格日期格式,有“2013/01/02”.“2013/1/3”.“2013-1-2”.“20130204”等格式,而MSSQL数据库格式要求“2013-01-01”这样格式.一般会这样操作:右键单元格-设置单元格格式-自定义-右侧输入yyyy-mm-dd并确定,这样的操作只是表面显示为“2013-01-02”这样的格式,但是单击此单元格,上方的编辑框里仍显示原格式.所以这种方式治标不治本. 解决: 表格空白列单击一个单元格,此列暂称临时列.输入=text(

POI对Excel自定义日期格式的读取

用POI读取Excel数据:(版本号:POI3.7) 1.读取Excel Java代码   private List<String[]> rosolveFile(InputStream is, String suffix, int startRow) throws IOException, FileNotFoundException { Workbook xssfWorkbook = null; if ("xls".equals(suffix)) { xssfWorkboo

js读取excel中日期格式转换问题

在使用js-xlsx插件来读取excel时,会将2018/10/16这种数据自动装换成48264.12584511. 所以需要自己手动再转换回来 // excel读取2018/01/01这种时间格式是会将它装换成数字类似于46254.1545151415 numb是传过来的整数数字,format是之间间隔的符号 formatDate(numb, format) { const time = new Date((numb - 1) * 24 * 3600000 + 1) time.setYear(

使用NPOI导入Excel注意日期格式和数字格式

//使用NPOI导入Excel public static DataTable importExcelToDataSetUsingNPOI(string FilePath, string fileName) { DataSet myDs = new DataSet(); DataTable dt = new DataTable("mytable"); myDs.Tables.Add(dt); DataRow myRow; myDs.Clear(); try { using (Strea

Java通过jxl解析Excel文件入库,及日期格式处理方式 (附源代码)

JAVA可以利用jxl简单快速的读取文件的内容,但是由于版本限制,只能读取97-03  xls格式的Excel. 本文是项目中用到的一个实例,先通过上传xls文件(包含日期),再通过jxl进行读取上传的xls文件(文件格式见下user.xls),解析不为空的行与列,写入数据库. 文件user.xls格式为: 下面来看代码实例演示: 一.前端jsp页面(本来内容很多,这里精简了) <%@ page language="java" contentType="text/htm

POI处理Excel中各种日期格式问题

前不久写过一篇随笔<EXCEL解析之终极方法WorkbookFactory>,提到使用WorkbookFactory来处理Excel文件数据,最近发现一个问题就是这个办法不能很好的处理各种日期格式,比如下面这些: 那么如何将这些格式正确识别并输出呢?下面来分享一下解决方法. 其实答案已经在之前已经写过.需要回到之前比较笨重的那个办法,就是在读取单元格时对单元格中数据的种类做判断,再将数据做适当转换,POI将EXCEL数据分成以下几种类型: CELL_TYPE_NUMERIC CELL_TYPE

java导入excel时处理日期格式(已验证ok)

在Excel中的日期格式,比如2009-12-24将其转化为数字格式时变成了40171,在用java处理的时候,读取的也将是40171.如果使用POI处理Excel中的日期类型的单元格时,如果仅仅是判断它是否为日期类型的话,最终会以NUMERIC类型来处理.正确的处理方法是先判断单元格的类型是否则NUMERIC类型,然后再判断单元格是否为日期格式,如果是的话, 创建一个日期格式,再将单元格的内容以这个日期格式显示出来.如果单元格不是日期格式,那么则直接得到NUMERIC的值就行了.具体代码如下:

POI导出excel日期格式

参考帖子: [1]http://www.ithao123.cn/content-2028409.html [2]http://javacrazyer.iteye.com/blog/894850 再读本篇文章之前,请先看我的前一篇文章,前一篇文章中有重点讲到POI设置EXCEL单元格格式为文本格式,剩下的设置小数.百分比.货币.日期.科学计数法和中文大写这些将在下面一一写出 以下将要介绍的每一种都会用到这三行中的变量 HSSFWorkbook demoWorkBook = new HSSFWork

桌面支持--Excel表格里的数据全部变成了时间或者日期格式的时候怎么办???

20150601 问题描述:Excel表格里的数据全部变成了时间或者日期格式的时候怎么办??? 解决办法: 1. 打开Excel,任意选中一单元格,单击鼠标右键,选择设置单元格格式. 2. 在数字自定义类型中,找到如图中前缀为[$-F400]的类型格式(或者类似的比如[$-F800]),点击删除.3. 保存,大功告成!再次打开,世界清静了.