Oracle中不使用TO_CHAR如何获取DD-MM-YY格式日期?
首先得纠正你一个常见的误区:Oracle中的日期类型(DATE)本身是没有显示格式的,它存储的是一个内部数值,最终显示成什么样完全取决于会话的NLS_DATE_FORMAT参数,或者你主动把它转换成字符串类型。
关于你的查询疑问:为什么select TO_DATE(SYSDATE,'DD-MM-YY') from dual输出是29-Mar-18?
你这里用错函数了!TO_DATE()的作用是把字符串解析成日期类型,而不是把日期格式化成字符串。当你把SYSDATE(已经是DATE类型)传给TO_DATE()时,Oracle会先把SYSDATE隐式转换成字符串——用当前会话默认的NLS_DATE_FORMAT(比如你的会话默认是DD-Mon-RR),然后再把这个字符串用'DD-MM-YY'的格式规则转成DATE类型,最后显示这个DATE类型时,又用回会话默认的NLS_DATE_FORMAT,所以结果还是29-Mar-18,完全达不到你想要的格式。
要得到29-03-18的格式,正确的做法是用TO_CHAR()把日期转成字符串:
SELECT TO_CHAR(SYSDATE, 'DD-MM-RR') FROM dual;
这里用RR而不是YY是更稳妥的年份处理方式(能更好应对跨世纪的日期场景),不过如果你的业务场景确定只需要两位年份,YY也可以满足需求。
不使用TO_CHAR函数,怎么得到'DD-MM-YY'格式的日期字符串?
因为日期类型本身没有格式,要得到指定格式的字符串,本质上还是要做类型转换,但如果严格要求不用TO_CHAR(),有两个可行的方案:
方案1:修改当前会话的NLS_DATE_FORMAT参数
通过修改会话参数,让Oracle在显示DATE类型时自动使用你想要的格式:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MM-YY';
之后再执行查询:
SELECT SYSDATE FROM dual;
就会直接输出29-03-18。注意这个设置只对当前会话生效,退出会话后会恢复默认值。
方案2:使用TO_NCHAR()函数替代
TO_NCHAR()是TO_CHAR()的Unicode版本,返回NVARCHAR2类型,如果你只是不想用TO_CHAR(),这个函数可以达到同样的格式转换效果:
SELECT TO_NCHAR(SYSDATE, 'DD-MM-YY') FROM dual;
额外提醒:如果是在应用程序中使用日期格式,更推荐在应用层处理显示逻辑,而不是依赖数据库的会话参数,因为不同会话的NLS设置可能存在差异,容易导致显示不一致。
内容的提问来源于stack exchange,提问作者goonerboi

