1.字符串转为日期格式(to_date)
例1:把字符串类型2005-01-01 13:14:20 转成 2005/1/1 13:14:20日期格式
1 | select to_date( '2005-01-01 13:14:20' , 'yyyy-MM-dd HH24:mi:ss' ) from dual; |
结果:
例2:把字符串类型30-11月-19 转成 2018/12/31 日期格式
1 | select to_date( '30-11月-19 ' , 'dd-mon-yy' ) from dual |
结果:
注意:字符串转日期时,字符串和日期格式要匹配,如字符串格式为30-11月-19,如果后边跟yyyy-MM-dd就会报格式不匹配的错误,必须使用dd-mon-yy
2.日期格式转字符串(to_char)
例1:把sysdate(2020/5/12 17:31:23)转化为yyyy-MM-dd HH24:mi:ss字符串格式
1 | select to_char(sysdate, 'yyyy-MM-dd HH24:mi:ss' ) from dual; |
结果:
例2:表car.lp_totallpdata中有一个字段enddate字段,代表了结束日期。enddate字段中的数据格式是varchar2类型的:(30-11月-19),现在要求查出表中结束日期等于字符串’2019-11’的数据
也就是说找出enddate = ‘2019-11’的数据
分析:
首先30-11月-19 和 2019-12都属于字符串类型的,但是他们的格式不一样,我们可以先把enddate字段中的数据转化为正常的日期格式,再把他转化为字符串,看他与2019-12是否相等
1.先把enddate字段中的数据转化为正常的日期格式
1 | to_date(t.enddate, 'dd-mon-yy' ) //先转化为日期30-11月-19==> 2019/11/30 |
2.再把他转化为我们想要的字符串
1 | to_char(to_date(t.enddate, 'dd-mon-yy' ), 'yyyy-mm' ) // 2019/11/30 ==> 2019-11 |
3.完整的过滤sql
1 2 3 | select t.* from car.lp_totallpdata t where to_char(to_date(t.enddate, 'dd-mon-yy' ), 'yyyy-mm' )= '2019-11' |
3.日期范围查询
日期的范围查询,假设要查询 2011-05-02 到 2011-05-30 之间的数据
这条查询语句有两种实现方式:
假设数据库的字段 time 为 日期类型,传来的数据为字符串类型!!!
1. to_date 方式
把传来的数据 2011-05-02 、 2011-05-02 转化为日期再与time比较
1 2 3 | select * from tablename where time >= to_date( '2011-05-02' , 'yyyy-mm-dd' ) and time |
运行的结果是:可以显示05-02的数据,但是不能显示05-30的数据。
解决方案:
①如果想显示05-30的数据可以
②如果想要显示05-30的数据可以
2.to_char方式:
把time转化为字符串再与传来的数据 2011-05-02 、 2011-05-02 做比较
1 2 3 | select * from tablename where to_char( time , 'yyyy-mm-dd' ) >= '2011-05-02' and to_char( time , 'yyyy-mm-dd' ) |
查询结果:可以同时显示05-02和05-30的数据。
3. between … and
经常看到有人在某段时间区间上喜欢用between … and … ,其实,可以直接地说:这种用法是错误的!
查看某一天的数据,或某一段时间内的数据,其实是一个左闭、右开的区间内的数据;
例如:我要查一张表 2011年3月11日到2011年3月24日内所生成的数据,其区间应该为[2011-03-11 00:00:00, 2011-03-25 00:00:00)
– 即:不包括右边2011-03-25 00:00:00时间点的值!
4. 等于某日期的查询
1 2 3 4 | 格式化传入的日期字符串与数据库比较 select * from goods where g_time=to_date( '2018/12/26 10:05:17' , 'yyyy-MM-dd hh:mi:ss' ); |
1 2 3 4 5 | 格式化数据库的日期与传入的日期字符串比较 select * from goods where carnum = '粤BEK735' and to_char(damageStartdate, 'yyyy-MM-dd HH24:mi:ss' ) = '2017-04-05 12:00:00' ; |
1 2 3 4 5 | 传入值与数据值模糊匹配 select * from goods where carnum = '粤BEK735' and to_char(damageStartdate, 'yyyy-MM-dd HH24:mi:ss' ) like '2017-04-05%' ; |
5. LocalDateTime的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | //转换器 DateTimeFormatter df = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" ); //当前时间 LocalDateTime time = LocalDateTime.now(); //日期转字符串 String localTime = df.format(time); System.out.println( "LocalDateTime转成String类型的时间:" + localTime); //字符串转日期 LocalDateTime ldt = LocalDateTime.parse( "2017-09-28 17:07:05" , df); System.out.println( "String类型的时间转成LocalDateTime:" + ldt); //日期转时间戳 System.out.println( "LocalDateTime:2017-09-28T17:07:05 转时间戳:" +ldt.toEpochSecond(ZoneOffset.of( "+8" ))); System.out.println( "===================================" ); //LocalDateTime把字符串转日期互转 (不带时、分、秒的) DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern( "yyyy/M/d" ); //字符串转日期 LocalDate parse = java.time.LocalDate.parse( "2016/03/28" , dateTimeFormatter1); System.out.println( "2016/03/28转成日期后:" + parse); //日期转字符串 String format = dateTimeFormatter1.format(parse); System.out.println( "2016/03/28转成合适的字符串后:" + format); |
运行结果如下:
查看日期范围间隔
1 2 3 4 5 6 7 | LocalDate today = LocalDate.now(); System.out.println( "Today:" + today); LocalDate oldDate = LocalDate.of( 2018 , 9 , 23 ); System.out.println( "OldDate:" + oldDate); Period p = Period.between(oldDate, today); System.out.printf( "目标日期距离今天的时间差:%d 年 %d 个月 %d 天n" , p.getYears(), p.getMonths(), p.getDays()); |
运行结果
案例:
“startTime”:“2021-10-08 13:21:08”,
“endTime”:“2021-10-08 13:21:12”,
求两者的时间差:
1 2 3 4 5 6 7 8 | DateTimeFormatter df = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" ); LocalDate ldate = LocalDateTime.parse(settlementDetailRequest.getStartTime(), df).toLocalDate(); LocalDate rdate = LocalDateTime.parse(settlementDetailRequest.getEndTime(), df).toLocalDate(); Period p = Period.between(ldate, rdate); if (p.getYears() > 1 || p.getMonths() > 3 ||(p.getMonths()== 3 &&p.getDays()> 0 )) { return BaseResp.fail( "查询日期范围仅支持三个月!" ); } |
需求案例:找出所有任务中,离当前时间最近的任务信息,并返回!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | @RequestMapping (value = "/memory" ,method = RequestMethod.GET) @ApiOperation ( "修理厂录入定损任务-记忆功能" ) @ApiImplicitParam (paramType = "query" , name = "openid" , value = "修理厂openid" , required = true , dataType = "String" ) public R memory( @RequestParam ( "openid" ) String openid) { // 1.获取该openid下的所有定损任务 List memoryInfo = kfAppointmentDsService.list( new QueryWrapper().eq( "factory_openid" , openid)); // 2.收集所有已提交的定损任务的-提交时间戳 List collect = memoryInfo.stream() .map(KfAppointmentDsEntity::getApplyTime) .map(x -> { DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" ); // 把Date格式转化为时间戳 return LocalDateTime.parse(x, formatter).toEpochSecond(ZoneOffset.of( "+8" )); }).collect(Collectors.toList()); // 3.通过比较时间戳大小,收集最近一次的提交时间戳 Long maxTime = collect.get( 0 ); for ( int i = 0 ; i entitity = memoryInfo.stream().filter(x -> { DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" ); Long everyTime = LocalDateTime.parse(x.getApplyTime(), formatter).toEpochSecond(ZoneOffset.of( "+8" )); return everyTime.equals(finalMaxTime); }).collect(Collectors.toList()); // 5.属性copy,并返回 MemoryVo memoryVo = new MemoryVo(); BeanUtils.copyProperties(entitity.get( 0 ),memoryVo); return R.ok().put( "data" ,memoryVo); } |
6. between…and查询日期时存在的问题
场景:用 select * from TABLE where date between ‘2009-1-22’ And ‘2009-1-22’ ,或者 select * from TABLE where date >= ‘2009-1-22’ And date
原因:短日期类型默认Time为00:00:00,所以当使用between作限制条件时,就相当于 between ‘2009-1-22 00:00:00’ and ‘2009-1-22 00:00:00’,因此就查不出数据。使用 >=、
解决方法:
方法一:
如果 2009-01-23 00:00:00 没有业务发生的话,也可以让前端直接加一天,写成
1 | select * from table where date between '2009-01-22' and '2009-01-23' |
但这样写会包含 2009-01-23 00:00:00 !
也可后端直接增加一天,后端解决代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class MianTest { public static void main(String[] args) { //转换器 SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); //当前日期 Date date = new Date( 2021 - 1900 , 1 , 28 ); System.out.println(format.format(date)+ "+++++++++" ); Calendar instance = Calendar.getInstance(); //把当前日期放进去 instance.setTime(date); //日期向后推一天 instance.add(instance.DATE, 1 ); //这个日期就是日期向后推 1天 的结果 Date realyTime = instance.getTime(); System.out.println(format.format(realyTime)+ "+++++++++" ); } } |
结果如下:
方法二:
如果用String接收的日期,可以让前端按如下方式传数据
我们在后台对endTime进行修改,增加59:59:59
1 2 3 4 | //endTime增加一天 String endTime = vo.getEndTime(); String replaceTime = endTime.replace( "00:00:00" , "59:59:59" ); vo.setEndTime(replaceTime); |
也可完成正确的查询结果
方法三:
如果用Data接收的日期,可以让前端还按这种方式传数据
后台为Data类型的endTime增加59:59:59
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class MianTest { public static void main(String[] args) { //转换器 SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); //当前日期 Date date = new Date( 2021 - 1900 , 1 , 8 ); System.out.println(format.format(date)+ "+++++++++" ); Calendar instance = Calendar.getInstance(); //把当前日期放进去 instance.setTime(date); //日期向后推,整数往后推,负数向前推 instance.add(Calendar.HOUR, 23 ); instance.add(Calendar.MINUTE, 59 ); instance.add(Calendar.SECOND, 59 ); //这个日期就是日期向后推 23:59:59的结果 Date realyTime = instance.getTime(); System.out.println(format.format(realyTime)+ "+++++++++" ); } } |
结果如下,也可达成正确的效果
以上就是oracle中日期与字符串的相互转化的方法详解的详细内容,更多关于oracle日期与字符串相互转化的资料请关注IT俱乐部其它相关文章!