首页 > 数据库 >Oracle SQL 两个日期类型毫秒值求差,日期转毫秒,时间差(ms)自定义函数解决毫秒差

Oracle SQL 两个日期类型毫秒值求差,日期转毫秒,时间差(ms)自定义函数解决毫秒差

时间:2023-01-12 17:00:15浏览次数:58  
标签:11 06 instr 33 31 40.89 毫秒 日期 求差


前言

实际业务经常遇到求平均响应时间等操作,理论上应该可以直接求日期格式毫秒值,便可以计算时间差,But,Oracle没有对应函数,同时网上的方法求得是日期格式化的double类型数据,相加减时,遵循的是十进制,日期格式为60进制,所以毫秒值并不和我们理解的一样,目前提出几个解决思路,但是SQL稍微有点长,以后想办法优化,应该有其他思路,欢迎指正。目前解决思路就是自定义函数Thinking 4

1.Thinking 1 精确到秒 TO_DATE()

赶时间直接看​​4.Thinking 4 自定义函数解析时间​​,有时间的慢慢看,4为解决办法
分三段写;
2019-05-28 23:59:59

--1559059199000
SELECT TO_NUMBER(TO_DATE('2019-05-28 23:59:59', 'YYYY-MM-DD HH24:MI:SS') -
TO_DATE('1970-01-01 8:0:0', 'YYYY-MM-DD HH24:MI:SS')) * 24 * 60 * 60 * 1000
FROM DUAL;

2019-05-29 00:01:00

--1559059260000
SELECT TO_NUMBER(TO_DATE('2019-05-29 00:01:00', 'YYYY-MM-DD HH24:MI:SS') -
TO_DATE('1970-01-01 8:0:0', 'YYYY-MM-DD HH24:MI:SS')) * 24 * 60 * 60 * 1000
FROM DUAL;

两数相减

--61000
select 1559059260000-1559059199000 from dual;

缺点

通过获取当前时间,直接日期相减,获得当天到1970年的毫秒值,but,to_date 函数只能精确到 ,误差会出现,无法精确到毫秒,但是可以精确到秒求得我们所需毫秒值

2.Thinking 2 精确到毫秒 TO_TIMESTAMP()

实时计算日期函数TO_TIMESTAMP使用链接

既然to_date函数只能精确到秒,那么,我们使用Oracle的另一个可以精确到 毫秒 的函数 to_timestamp
2019-06-06 14:13:00

--2019-06-06 14:13:00.000000000
select to_timestamp('2019-06-06 14:13:00', 'YYYY-MM-DD HH24:MI:SS.ff') from dual;

out
2019-06-06 14:13:00.000000000

模拟日期相减
2019-06-06 14:13:0.100
2019-06-06 14:10:0.200

select to_timestamp('2019-06-06 14:13:0.100', 'YYYY-MM-DD HH24:MI:SS.ff') 
-to_timestamp('2019-06-06 14:10:0.200', 'YYYY-MM-DD HH24:MI:SS.ff') from dual;

out
0 0:2:59.9

缺点

算出来为时间类型,几分几秒,很精准的算法。
如果你需要时间展示为毫秒形式long类型,使用Thinking 4

3.Thinking 3 精确到毫秒 EXTRACT()

换一个函数继续做毫秒问题
​oracle中 extract() 函数----用于截取年、月、日、时、分、秒 详解链接​​

--4200
select EXTRACT(SECOND FROM(to_timestamp('2019-06-06 14:12:4.200', 'YYYY-MM-DD HH24:MI:SS.ff') )) * 1000 from dual;

缺点

这个只能计算到秒,两个时间差如果大于59秒,涉及到分钟,还是没办法,就算计算分钟,它也只会显示分钟,之后精度丢失
out
4200

4 Thinking 4 自定义函数解析时间

因为实在没有办法,所以决定自定义时间解析,Thinking 2出的时间类型 解析成毫秒
注:自定义函数可以随数据库一直存在,使用时调用即可 ?
TestSQL
我们解析Thinking 2返回的这个 0 0:2:59.9时间,然后把它截取字符串,我选择一个比较全的时间进行测试,然后把这个SQL转化为函数 传参式

select day* 24 * 60 * 60 * 1000+ hour * 60 * 60 * 1000 + min * 60 * 1000 + ss * 1000 + mi from (
select INSTR( '31 11:33:40.89', ' ' ) konggeIndex,SUBSTR('31 11:33:40.89',1,2) testIndex,
instr('31 11:33:40.89', '.', 1) - instr('31 11:33:40.89', ':', 1,2) - 1 secondIndex,
instr('31 11:33:40.89', ':', 1,2) - instr('31 11:33:40.89', ':', 1)-1 minuteIndex,
instr('31 11:33:40.89', ':', 1) - instr('31 11:33:40.89', ' ', 1)-1 hourIndex,
instr('31 11:33:40.89', ' ', 1) -1 dayIndex,
to_number(SUBSTR( '31 11:33:40.89', INSTR( '31 11:33:40.89', '.') + 1, 3)) mi,
to_number(SUBSTR( '31 11:33:40.89', INSTR( '31 11:33:40.89', ':',1,2) + 1, instr('31 11:33:40.89', '.', 1) - instr('31 11:33:40.89', ':', 1,2) - 1)) ss,
to_number(SUBSTR( '31 11:33:40.89', INSTR( '31 11:33:40.89', ':',1,1) + 1, instr('31 11:33:40.89', ':', 1,2) - instr('31 11:33:40.89', ':', 1)-1 )) min,
to_number(SUBSTR( '31 11:33:40.89', INSTR( '31 11:33:40.89', ' ') + 1 , instr('31 11:33:40.89', ':', 1) - instr('31 11:33:40.89', ' ', 1)-1) )hour,
to_number(SUBSTR( '31 11:33:40.89' , 1, (instr('31 11:33:40.89', ' ') ) )) day
from dual) time;

自定义函数编写

创建函数

CREATE OR REPLACE FUNCTION get_timestamp_cha(endtime   in TIMESTAMP,
starttime in TIMESTAMP)

RETURN INTEGER


AS


str VARCHAR2(50);
misecond INTEGER;
seconds INTEGER;
minutes INTEGER;
hours INTEGER;
days INTEGER;


BEGIN

str := to_char(endtime - starttime);

misecond := to_number(SUBSTR(str, INSTR(str, '.') + 1, 3));

seconds := to_number(SUBSTR(str, INSTR(str, ':',1,2) + 1, instr(str, '.', 1) - instr(str, ':', 1,2) - 1));

minutes := to_number(SUBSTR(str, INSTR(str, ':',1,1) + 1, (instr(str, ':', 1,2) )- instr(str, ':', 1)-1 ));

hours := to_number(SUBSTR(str, INSTR(str, ' ') + 1 , (instr(str, ':', 1) )- instr(str, ' ', 1)-1));

days := to_number(SUBSTR(str, 1, INSTR(str, ' ')));

RETURN days * 24 * 60 * 60 * 1000 + hours * 60 * 60 * 1000 + minutes * 60 * 1000 + seconds * 1000 + misecond;

END;

调用函数

select get_timestamp_cha( 
to_timestamp('2019-06-06 14:13:0.100', 'YYYY-MM-DD HH24:MI:SS.ff'),
to_timestamp('2019-06-06 14:10:0.200', 'YYYY-MM-DD HH24:MI:SS.ff') )
millisecond
from dual;

out

Oracle SQL 两个日期类型毫秒值求差,日期转毫秒,时间差(ms)自定义函数解决毫秒差_extract


顺便测试一下自己的时间

Oracle SQL 两个日期类型毫秒值求差,日期转毫秒,时间差(ms)自定义函数解决毫秒差_extract_02


注:也可以单独计算当前时间毫秒值,开始时间传值为1970年毫秒日期就行

至此,终于解决了日期时间差毫秒值问题 ???祝你幸福

送你一首歌:《The Nights》 Avicii / RAS​​

附图:小蓬草

Oracle SQL 两个日期类型毫秒值求差,日期转毫秒,时间差(ms)自定义函数解决毫秒差_extract_03


标签:11,06,instr,33,31,40.89,毫秒,日期,求差
From: https://blog.51cto.com/u_15939406/6004199

相关文章

  • 【EasyUI篇】Datebox日期输入框组件
    微信公众号:​​程序yuan​​关注可了解更多的教程。问题或建议,请公众号留言;​​查看-->全套EasyUI示例目录​​23.Datebox日期输入框组件     JSP文件<%--Created......
  • vue el-date-picker多选日期时间时,支持时间排序
    需求背景:当el-date-picker可以多选日期时,时间的顺序是按照选择的顺序来的,体验不是很好。需要在选时间的同时进行时间排序 解决方案:使用watch监听v-model绑定的值的变......
  • el-date-picker组件日期显示错误,前一天
    原文链接:https://blog.csdn.net/qq_14993591/article/details/126411913使用element-uiDatePicker日期选择器,选中日期是2021-08-02至2021-08-03,浏览器中日期的值是2021......
  • Java 解析 带 T Z 的 UTC 时间格式 日期
    直接上代码吧publicstaticvoidmain(String[]args)throwsParseException{SimpleDateFormatdf=newSimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")......
  • Sentinel Go-毫秒级统计数据结构揭秘
    作者:binbin0325背景介绍随着微服务的流行,服务和服务之间的稳定性变得越来越重要。在2020年,Sentinel社区推出SentinelGo版本,朝着云原生方向演进。SentinelGo是一......
  • 修改日期前缀年月日,后缀时分秒不变
    修改日期前缀年月日,后缀时分秒不变--修改日期date前缀指定日期年月日2023-01-10,后缀时分秒不变updatetable_namesetdate=STR_TO_DATE(concat('2023-01-10',DATE_F......
  • T-SQL查询:连续输出2个日期间的日期
    declare@startdatetimedeclare@enddatetimeset@start='2013-09-25'set@end='2013-09-30'selectdateadd(dd,num,@start)FROM(SELECTROW_NUMBER()OVER(......
  • js只比较日期(月日)的大小,不比较年份
    需求背景:   要求验证选择的时间是否在可选的时间范围内(即应用的时间范围),但是可选的时间范围是只有月份和天数,不限制年份,所以选择的时间也只验证月日,不校验年份解决......
  • SQL Server日期与字符串之间的转换
    本文导读:在SQLServer数据库中,SQLServer日期时间格式转换字符串可以改变SQLServer日期和时间的格式,是每个SQL数据库用户都应该掌握的。下面主要就介绍一下SQLServer日期......
  • PHP 之计算当月之前12个月的日期
    一、效果图 二、示例<?php//获取日期$now_year=date('Y');$now_month=date('m');$date1=$date2=array();for($i=1;$i<=$now_month;$i++){......