Java数值类型时间转换为标准时间


一. 前言

  我在读取客户提供的excel中发现某几列时间是数值类型,最开始还以为客户给错了,最后才发现这属于一种时间格式,一起来看看如果遇到这种该怎么处理吧

二. 分析这种时间

       

   假如在我们excel中有一列数据,我们需要读取出来,使用POI读取一下试试

 1 //获取字符串
 2 public static String getCellValueString(Cell cell) {
 3         if (cell == null) return "";
 4         cell.setCellType(CellType.STRING);
 5         return cell.getRichStringCellValue().getString().trim();
 6     }
 7 //获取时间
 8 public static Long getCellValueLong(Cell cell) throws Exception {
 9         if (cell == null) return null;
10         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
11         Date cellD = cell.getDateCellValue();
12         if (cellD == null) return null;
13         long res = cellD.getTime();
14         String format = simpleDateFormat.format(res);
15         Date parse = simpleDateFormat.parse(format);
16         // Long long1 = Long.valueOf(format);
17         return parse.getTime();
18     }
19 public static void main(String[] args){
20         String path = "时间测试.xlsx";
21         try {
22             FileInputStream fileInputStream = new FileInputStream(new File(path));
23             Map<String, Integer> titleIndexMap = new HashMap<>();
24             XSSFWorkbook hssfWorkbook = new XSSFWorkbook(fileInputStream);
25             XSSFSheet sheet = hssfWorkbook.getSheetAt(0);
26             XSSFRow titleRow = sheet.getRow(0);
27             int lastRowNum = sheet.getLastRowNum();
28             for (int j = 0; j <= titleRow.getLastCellNum(); j++) {
29                 titleIndexMap.put(getCellValueString(titleRow.getCell(j)), j);
30             }
31             String time1 = "";
32             Long time2 = null;
33             for (int k = 1; k <= lastRowNum; k++) {
34                 XSSFRow rowTemp = sheet.getRow(k);
35                 if (null == rowTemp) {
36                     continue;
37                 }
38                 time1 = getCellValueString(rowTemp.getCell(titleIndexMap.get("日期")));
39                 System.out.println(time1);
40                 //time2 = getCellValueLong(rowTemp.getCell(titleIndexMap.get("日期")));
41                 //System.out.println(time2);
42             }
43             hssfWorkbook.close();
44             fileInputStream.close();
45         }catch (Exception e){
46             e.printStackTrace();
47         }
49     }

第一种通过读取字符串来读取,结果如下

 

 我们可以看到是数字,这种时间类型当时可能不太理解,这里我们可以直接用第二种Long类型来读取,如果读取出来是时间戳,那么就不需要转换,但是有些时候excel的数据就是这些数字,这时候就必须开始转换了,如果在强行读取会报错,下边看看如何转换,提供两个方法,两种方式都可以

三.转换数字类型时间为时间戳

 1     public static String getDateByString(String value){
 2         SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
 3         //Excel读取日期读到全为数字,数字是从1900年到该日期的天数
 4         if(value.matches("^[0-9]+$")){
 5             Long dayNum=Long.valueOf(value);
 6             //获取初始时间
 7             Calendar calendar=new GregorianCalendar(1900,0,-1);
 8             Date initDate=calendar.getTime();
 9             //获取相差秒数
10             Long addTime=dayNum*24*60*60*1000;
11             //得到当前时间
12             Long time=initDate.getTime()+addTime;
13             Date actualDate=new Date(time);
14             return simpleDateFormat.format(actualDate);
15         }
16         //if(value.contains("-")){
17         //    try{
18         //        Date temp=simpleDateFormat.parse(value);
19         //        return simpleDateFormat.format(temp);
20         //    }catch (Exception e){
21         //        e.printStackTrace();
22         //    }
23         //}
24         //if(value.contains("无")){
25         //    return "";
26         //}
27         //return "";
28         return "";
29     }
30     public static String HSSFDateFormat(String value){
31         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
32         //这里使用POI自带方法传入数字,自动转换为Date
33         Date javaDate = HSSFDateUtil.getJavaDate(Double.parseDouble(value));
34         //System.out.println(javaDate.getTime());
35         String format = simpleDateFormat.format(javaDate);
36         return format;
37     }

这里我调用这两个方法,看看效果

传入的参数就是读取到的第一个数字日期,2016-3-5

 

结果就是格式化后的String类型的日期,时间戳同理,这里我们就可以存入数据库或者其他的操作了 

四. 大家可能不知道这种时间是如何出现,简单说一下,如果有兴趣,可以看一下

这个时间是1900年1月1日到某个日期经过了多少天,例如1900-1-1到2016-3-5经过了42434天,要考虑到平闰年的差值,那么我们可以简单得出一个理论

我们推断一个算法,X=当前年 Y=当前月 N=当前日  Z =  (X-1900)中闰年的数量     那么我们需要 (X-1900)*365 + Z + Y(闰年中当前月需要判断月份)+ N 即可

下边用代码实现,大部分内容为 https://blog.csdn.net/weixin_49689284/article/details/108168783 其中做了一些修改

 1     public static void main(String[] args) {
 2         //Scanner sc = new Scanner(System.in);
 3         //System.out.println("输入年份:");
 4         //int year = sc.nextInt();
 5         //System.out.println("输入月份:");
 6         //int month = sc.nextInt();
 7         //System.out.println("输入日期:");
 8         //int days = sc.nextInt();
 9         int year = 2020;
10         int month = 5;
11         int days = 20;
12         /*1,年:(闰年能将4整除,不能将100整除)
13                 1.1,按平年算,每年365天
14                 1.2,每个闰年加1天,若输入的那年是闰年,2月后,要加1天,反之不用*/
15         int yDays = (year -1900)*365;
16 
17         int rDays = 0;//每个润年加1
18         for (int i = 1900; i <=year ; i++) {
19             if (DateUtil.isLeapYear(i)) {
20                 rDays++;
21                 if (month < 3) {//若输入的年份为润,判断其是否过了2月,没过减1
22                     rDays = rDays - 1;
23                 }
24             }
25         }
26 
27         /*2,月:按照平年每个月的天数:31,28,31,30,31,30,31,31,30,31,30,31*/
28         int[] months = {31,28,31,30,31,30,31,31,30,31,30,31};
29         int mDays = 0;
30         //如果当前 年是闰年并且月份大于3,那么月份需要先累加+1
31         if(DateUtil.isLeapYear(year)&&month>3){
32             mDays++;
33         }
34         if (month == 1){//如果等于1月份,不算月份直接加天数即可
35             mDays = 0;
36         }else{
37             for (int i = 0; i <month-1 ; i++){ //减1,因为当月没过,按下面的日期来算
38                 mDays += months[i]; //累加当月之前的天数
39             }
40         }
41         /*4,日期: 天数直接相加*/
42         int sum = yDays + rDays + mDays +days;
43         System.out.println(yDays);
44         System.out.println(rDays);
45         System.out.println(mDays);
46         System.out.println(days);
47         System.out.println(sum);
48     }
    //改用DataUtil判断平润,下边是maven
    <dependency>
     <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
     <version>5.7.9</version>
    </dependency>

可以用前边的代码,验证一下


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM