历史版本2 :时间类型计算 返回文档
编辑时间: 内容长度:图片数:目录数: 修改原因:

前言:再处理单元格报表时,难免会出现很多单元格之间的计算,目前帆软的公式没有直接时间类型相加减的公式,日期类型的有,SO这篇文档诞生了;

1、最终的效果图:


222

2、算法

2.1、简单的时间计算

首先新建个CPT文件,在A2单元格中输入13:00:00、B2输入13:26:00

C2单元格输入小时差:HOUR(B2) - HOUR(A2) 

D2单元格输入分钟差:MINUTE(B2) - MINUTE(A2)

因为小时差可能的大于0,SO:E2单元格输入实际分钟差为C2 * 60 + D2;

F2单元格输入最终的时间差:TRUNC(E2 / 60) + "小时" + MOD(E2, 60) + "分钟";

单元格效果图如下:
222

2.2、特殊处理

如果时间格式不是标准的hh:MM:ss怎么办?

没问题,用以下公式处理:

在A4单元格中输入13:50、B4输入14:20

C4单元格输入小时差:HOUR(FORMAT(TIME(INDEXOFARRAY(SPLIT(B4, ":"), 1), INDEXOFARRAY(SPLIT(B4, ":"), 2), 00), "HH:mm:ss")) - HOUR(FORMAT(TIME(INDEXOFARRAY(SPLIT(A4, ":"), 1), INDEXOFARRAY(SPLIT(A4, ":"), 2), 00), "HH:mm:ss"))

D4单元格输入分钟差:MINUTE(FORMAT(TIME(INDEXOFARRAY(SPLIT(B4, ":"), 1), INDEXOFARRAY(SPLIT(B4, ":"), 2), 00), "HH:mm:ss")) - MINUTE(FORMAT(TIME(INDEXOFARRAY(SPLIT(A4, ":"), 1), INDEXOFARRAY(SPLIT(A4, ":"), 2), 00), "HH:mm:ss"))

因为小时差可能的大于0,SO:E4单元格输入实际分钟差为C4 * 60 + D4;

F4单元格输入最终的时间差:TRUNC(E4 / 60) + "小时" + MOD(E4, 60) + "分钟";

单元格效果图如下:
222
针对于特殊情况,主要是把时间类型格式化下然后再做处理,最重要的公式还是基本的时间公式HOUR(),MINUTE()基础公式;

还有另外一种情况,如果时间格式yyyy-mm-dd hh:MM:ss怎么办?

这种情况跟以上类似,只不过需要再计算天数了;

在A6单元格中输入2017-01-20 13:30:30、B6输入2017-01-22 11:19:20

C6单元格输入小时差:TRUNC((DATETONUMBER(B6) - DATETONUMBER(A6)) / 1000 / 60 / 60) + "小时"

D6单元格输入分钟差:TRUNC((DATETONUMBER(B6) - DATETONUMBER(A6)) / 1000 / 60) - TRUNC((DATETONUMBER(B6) - DATETONUMBER(A6)) / 1000 / 60 / 60) * 60 + "分"

E6单元格输入秒数差:if(right(B6, 2) - right(A6, 2) > 0, right(B6, 2) - right(A6, 2), right(B6, 2) - right(A6, 2) + 60) + "秒"

F6单元格输入最终的时间差:C6 + D6 + E6;

单元格效果图如下:
222

同时我们也可以使用一些其他公式来获取也可以,例如:

小时差:DATESUBDATE(B6, A6, "h") + "时"

分钟差:DATESUBDATE(B6, A6, "m") - DATESUBDATE(B6, A6, "h") * 60 + "分"

秒数差:DATESUBDATE(B6, A6, "s") - (DATESUBDATE(B6, A6, "m") - DATESUBDATE(B6, A6, "h") * 60) * 60 - DATESUBDATE(B6, A6, "h") * 60 * 60 + "秒"

如果感觉公式嵌套太繁琐,可以直接找迈神要插件,传递2个时间段直接就相加减了,公式DateDiff();效果图如下


222
是不是超级简单;

DateDiff插件源码:

package com.func; import com.fr.script.AbstractFunction; import com.fr.stable.Primitive; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DateDiff extends AbstractFunction { private static final long serialVersionUID = -2863679010825725885L; public String format = null; private Long dif = Long.valueOf(0L); public Object run(Object[] paramArrayOfObject) { try { Long localLong1 = Long.valueOf(((Date)paramArrayOfObject[0]).getTime()); Long localLong2 = Long.valueOf(((Date)paramArrayOfObject[1]).getTime()); this.dif = Long.valueOf(localLong2.longValue() - localLong1.longValue()); this.format = ((String)paramArrayOfObject[2]); replace("((?i)y)", Long.valueOf(31536000000L)); replace("((?i)q)", Long.valueOf(7776000000L)); replace("M", Long.valueOf(2592000000L)); replace("((?i)w)", Long.valueOf(604800000L)); replace("((?i)d)", Long.valueOf(86400000L)); replace("((?i)h)", Long.valueOf(3600000L)); replace("m", Long.valueOf(60000L)); replace("((?i)s)", Long.valueOf(1000L)); try { return Long.valueOf(Long.parseLong(this.format)); } catch (Exception localException2) { return this.format; } } catch (Exception localException1) { } return Primitive.ERROR_VALUE; } public void replace(String paramString, Long paramLong) { Pattern localPattern = Pattern.compile(paramString + "\\{\\d*?\\}"); Matcher localMatcher = localPattern.matcher(this.format); int i = (int)(this.dif.longValue() / paramLong.longValue()); int j = 1; while (localMatcher.find()) { String str1 = localMatcher.group(); str1 = str1.replaceAll(paramString + "\\{", ""); str1 = str1.replaceAll("\\}", ""); int k = Integer.parseInt(str1); String str2 = String.format("%0" + k + "d", new Object[] { Integer.valueOf(i) }); if (j != 0) { j = 0; this.dif = Long.valueOf(this.dif.longValue() - i * paramLong.longValue()); } this.format = this.format.replaceFirst(paramString + "\\{\\d*?\\}", str2); } } }