当前位置: 代码网 > it编程>数据库>Oracle > oracle中日期与字符串的相互转化的方法详解

oracle中日期与字符串的相互转化的方法详解

2024年09月24日 Oracle 我要评论
1.字符串转为日期格式(to_date)例1:把字符串类型2005-01-01 13:14:20 转成 2005/1/1 13:14:20日期格式select to_date('2005-01-01

1.字符串转为日期格式(to_date)

例1:把字符串类型2005-01-01 13:14:20 转成 2005/1/1 13:14:20日期格式

select to_date('2005-01-01 13:14:20','yyyy-mm-dd hh24:mi:ss') from dual;

结果:

在这里插入图片描述

例2:把字符串类型30-11月-19 转成 2018/12/31 日期格式

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字符串格式

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字段中的数据转化为正常的日期格式

to_date(t.enddate, 'dd-mon-yy') //先转化为日期30-11月-19==> 2019/11/30

2.再把他转化为我们想要的字符串

to_char(to_date(t.enddate, 'dd-mon-yy'),'yyyy-mm') // 2019/11/30 ==> 2019-11

3.完整的过滤sql

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比较

select * from tablename 
where time >= to_date('2011-05-02','yyyy-mm-dd')    
and  time <= to_date('2011-05-30','yyyy-mm-dd') 

运行的结果是:可以显示05-02的数据,但是不能显示05-30的数据。

解决方案:

①如果想显示05-30的数据可以<to_date(‘2011-05-31’,‘yyyy-mm-dd’),这样就能显示30号的了。

②如果想要显示05-30的数据可以<=to_date(‘2011-05-30 23:59:59 999’,‘yyyy-mm-dd hh24:mi:ss’)也是可以查出来的。

2.to_char方式:

把time转化为字符串再与传来的数据 2011-05-02 、 2011-05-02 做比较

select * from tablename 
where to_char(time,'yyyy-mm-dd') >= '2011-05-02'    
and to_char(time,'yyyy-mm-dd') <= '2011-05-30' 

查询结果:可以同时显示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. 等于某日期的查询

格式化传入的日期字符串与数据库比较
select * 
from goods
where g_time=to_date('2018/12/26 10:05:17','yyyy-mm-dd hh:mi:ss');
格式化数据库的日期与传入的日期字符串比较
select *  
from goods
where carnum = '粤bek735' and 
to_char(damagestartdate, 'yyyy-mm-dd hh24:mi:ss') = '2017-04-05 12:00:00'; 
传入值与数据值模糊匹配
select *  
from goods
where carnum = '粤bek735' and 
to_char(damagestartdate, 'yyyy-mm-dd hh24:mi:ss')  like '2017-04-05%'; 

5. localdatetime的使用

        //转换器
        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);

运行结果如下:

在这里插入图片描述

查看日期范围间隔

  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”,

求两者的时间差:

   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("查询日期范围仅支持三个月!");
   }

 需求案例:找出所有任务中,离当前时间最近的任务信息,并返回!

    @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<kfappointmentdsentity> memoryinfo = kfappointmentdsservice.list(new querywrapper<kfappointmentdsentity>().eq("factory_openid", openid));

        // 2.收集所有已提交的定损任务的-提交时间戳
        list<long> 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 < collect.size(); i++) {
            if (maxtime < collect.get(i)) {
                maxtime = collect.get(i);
            }
        }

        // 4.收集最近一次提交时间的任务信息
        long finalmaxtime = maxtime;
        list<kfappointmentdsentity> 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 <= ‘2009-1-22’ 查询当天数据,结果查不到数据。

原因:短日期类型默认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 没有业务发生的话,也可以让前端直接加一天,写成

select * from table where date between '2009-01-22' and '2009-01-23' 

但这样写会包含 2009-01-23 00:00:00 !
也可后端直接增加一天,后端解决代码如下:

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

  //endtime增加一天
  string endtime = vo.getendtime();
  string replacetime = endtime.replace("00:00:00", "59:59:59");
  vo.setendtime(replacetime);

也可完成正确的查询结果

方法三:

如果用data接收的日期,可以让前端还按这种方式传数据

在这里插入图片描述

后台为data类型的endtime增加59:59:59

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日期与字符串相互转化的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com