[Oracle] - 关于星期(IW和WW)的算法
1. 查看数据库字符集(如果字符集不同,可能显示乱码)
select DECODE(parameter, 'NLS_TERRITORY', 'TERRITORY', 'NLS_LANGUAGE', 'LANGUAGE', 'NLS_CHARACTERSET', 'CHARACTER SET') name, value from v$nls_parameters WHERE parameter IN ('NLS_TERRITORY', 'NLS_LANGUAGE', 'NLS_CHARACTERSET')
2. 查看数据库中指定日期为周几
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | create or replace function Get_weekday(pDate date ) return number is vResult number; begin select case to_char(pDate, 'FmDay' , 'nls_date_language=english' ) when 'Monday' then 1 when 'Tuesday' then 2 when 'Wednesday' then 3 when 'Thursday' then 4 when 'Friday' then 5 when 'Saturday' then 6 when 'Sunday' then 7 end d into vResult from dual; return vResult; end ; |
不推荐(根据NLS设置不同结果不同,例如周一为第一天和周日为第一天的Weekday结果不同)
select sysdate Today,
to_char(sysdate, 'D') Weekday,
trunc(sysdate, 'DD') - to_char(sysdate, 'D') + 1 WeekFirstDay,
trunc(sysdate, 'DD') - to_char(sysdate, 'D') + 7 WeekLastDay
from dual;
3. Oracle 中关于星期(IW和WW)的算法
Oracle中对于星期的计算规则中,其中关于计算本周是一年的第几周,有两种格式,IW和WW,其中的区别官方文档解释如下:
- IW:基于 ISO标准计算出来的该年的第几周(1-52 or 1-53) 。
- WW:该年的第几周(1-53),其中第1周指该年的第1天至第7天。
从文档中可以看出,WW的算法是: int(dayOfYear+6)/7,个人觉得这种算法有点“2”。相信一般情况下,我们不会使用WW的吧,应该IW使用的比较多。
关于Oracle提到的这个星期的计算ISO标准,是这样的:
- 每个星期总是从周一开始,周日结束。
- 如果1月1日是周五、周六或周日,则这一周算为上一年的最后一周,因为这周的大部分时间属于上一年。
- 如果1月1日是周一、周二、周三或周四,则这一周算为新年的第一周,因为这周的大部分时间属于新的一年。
下面这两张表格,是从Oracle官方文档中截取出来的:
Table 3-7 First ISO Week of the Year: Example 1, January 1998
Mo | Tu | We | Th | Fr | Sa | Su | ISO Week |
---|---|---|---|---|---|---|---|
- | - | - | 1 | 2 | 3 | 4 | First ISO week of 1998 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | Second ISO week of 1998 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | Third ISO week of 1998 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | Fourth ISO week of 1998 |
26 | 27 | 28 | 29 | 30 | 31 | - | Fifth ISO week of 1998 |
Table 3-8 First ISO Week of the Year: Example 2, January 1999
Mo | Tu | We | Th | Fr | Sa | Su | ISO Week |
---|---|---|---|---|---|---|---|
- | - | - | - | 1 | 2 | 3 | Fifty-third ISO week of 1998 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | First ISO week of 1999 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | Second ISO week of 1999 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | Third ISO week of 1999 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | Fourth ISO week of 1999 |
从表中可以看出,按照ISO标准算法,同样是1月1日,1998年是算第一周,而1999年的1月1日却算为上一年的最后一周。
这里需要注意的是,ISO标准中星期的第一天是周一,而Oracle中其他一些日期处理算法中(如D),默认每周的第一天是周日。因为第一天是周日还是周一,由参数NLS_TERRITORY决定,而该参数的默认值是从NLS_LANG继承过来的,NLS_LANG默认值为AMERICA,因此默认周日是每周的第一天)。
我们很多人认为中国人每周第一天从周一开始,其实不是这样哦,从Oracle上可以看出来,其实我国的每周第一天仍然是周日,与美国一致,只有德国、法国等一些欧洲国家是从周一开始的:
SQL> select to_char(sysdate,’yyyymmdd’) from dual; TO_CHAR( ——– 20110901 SQL> ALTER SESSION SET NLS_TERRITORY=AMERICA; Session altered. SQL> select to_char(sysdate,’d') from dual; T - 5 SQL> ALTER SESSION SET NLS_TERRITORY=China; Session altered. SQL> select to_char(sysdate,’d') from dual; T - 5 SQL> ALTER SESSION SET NLS_TERRITORY=GERMANY; Session altered. SQL> select to_char(sysdate,’d') from dual; T - 4
参考资料
http://www.dw4e.com/?p=108
https://community.oracle.com/message/9511573#9511573
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探