导读:本期聚焦于小伙伴创作的《符合中国人习惯的Oracle取周的日期函数怎么实现》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《符合中国人习惯的Oracle取周的日期函数怎么实现》有用,将其分享出去将是对创作者最好的鼓励。

在Oracle数据库开发里,处理周相关的日期计算是常见需求,但默认的日期函数逻辑和国内用户的使用习惯存在差异,比如Oracle默认一周从周日开始,而国内大多习惯周一作为一周起始。下面介绍几种符合中国人习惯的取周日期函数实现方式。

符合中国人习惯的Oracle取周的日期函数怎么实现

一、获取本周起始日和结束日

1. 周一作为一周起始的情况

国内最常用的周起始规则是周一为第一天,周日最后一天,可以用trunc函数结合日期运算实现:

-- 获取指定日期所在周的周一(周起始日)
-- 入参p_date为要计算的日期,返回该周周一的日期
CREATE OR REPLACE FUNCTION get_week_start_monday(p_date DATE) RETURN DATE IS
    v_day_num NUMBER; -- 存储当前日期是周几,1是周日,2是周一...7是周六
BEGIN
    -- 获取当前日期对应的周几数字,Oracle中day返回的是1(周日)到7(周六)
    v_day_num := TO_CHAR(p_date, 'D');
    -- 计算周一的日期:如果当前是周日(v_day_num=1),则减6天,否则减(v_day_num-2)天
    IF v_day_num = 1 THEN
        RETURN TRUNC(p_date) - 6;
    ELSE
        RETURN TRUNC(p_date) - (v_day_num - 2);
    END IF;
END get_week_start_monday;
/

-- 获取指定日期所在周的周日(周结束日)
CREATE OR REPLACE FUNCTION get_week_end_sunday(p_date DATE) RETURN DATE IS
    v_start_date DATE;
BEGIN
    -- 先拿到本周周一,再加6天就是周日
    v_start_date := get_week_start_monday(p_date);
    RETURN v_start_date + 6;
END get_week_end_sunday;
/

-- 测试示例
SELECT 
    get_week_start_monday(SYSDATE) AS 本周周一,
    get_week_end_sunday(SYSDATE) AS 本周周日
FROM dual;

2. 周日作为一周起始的情况

部分场景会把周日作为一周的开始,实现逻辑更简单:

-- 获取指定日期所在周的周日(周起始日)
CREATE OR REPLACE FUNCTION get_week_start_sunday(p_date DATE) RETURN DATE IS
    v_day_num NUMBER;
BEGIN
    v_day_num := TO_CHAR(p_date, 'D');
    -- 如果当前是周日,直接返回,否则减(v_day_num-1)天
    IF v_day_num = 1 THEN
        RETURN TRUNC(p_date);
    ELSE
        RETURN TRUNC(p_date) - (v_day_num - 1);
    END IF;
END get_week_start_sunday;
/

-- 获取指定日期所在周的周六(周结束日)
CREATE OR REPLACE FUNCTION get_week_end_saturday(p_date DATE) RETURN DATE IS
    v_start_date DATE;
BEGIN
    v_start_date := get_week_start_sunday(p_date);
    RETURN v_start_date + 6;
END get_week_end_saturday;
/

二、获取日期属于当年的第几周

国内统计周数时,通常要求每年的第一周是包含1月1日的那一周,且周一为周起始,实现如下:

-- 获取指定日期属于当年的第几周,符合国内习惯:周一为起始,第一周包含1月1日
CREATE OR REPLACE FUNCTION get_week_num_of_year(p_date DATE) RETURN NUMBER IS
    v_year_start DATE; -- 当年1月1日
    v_first_week_start DATE; -- 当年第一周的周一
    v_week_num NUMBER;
BEGIN
    -- 获取当年1月1日
    v_year_start := TO_DATE(TO_CHAR(p_date, 'YYYY') || '0101', 'YYYYMMDD');
    -- 计算当年第一周的周一:如果1月1日是周日,第一周周一是1月2日,否则按周几计算
    v_first_week_start := get_week_start_monday(v_year_start);
    -- 如果1月1日在第一周周一之前,说明第一周属于上一年,调整第一周起始
    IF v_year_start < v_first_week_start THEN
        v_first_week_start := v_first_week_start - 7;
    END IF;
    -- 计算周数:(当前日期 - 第一周周一) / 7 向上取整
    v_week_num := CEIL((TRUNC(p_date) - v_first_week_start + 1) / 7);
    RETURN v_week_num;
END get_week_num_of_year;
/

-- 测试示例
SELECT 
    TO_CHAR(SYSDATE, 'YYYY') AS 年份,
    get_week_num_of_year(SYSDATE) AS 当年第几周
FROM dual;

三、使用注意事项

  • Oracle的TO_CHAR(date, 'D')返回值受数据库NLS_TERRITORY参数影响,建议在使用前确认参数配置,或者按照上述逻辑显式计算周几,避免环境差异导致结果错误。
  • 函数中的TRUNC(p_date)是为了去掉日期的时间部分,保证只按日期维度计算,如果需要保留时间可以去掉trunc调用。
  • 如果业务场景有特殊周规则,比如要求第一周必须至少有4天在当年,可以调整第一周起始的计算逻辑适配需求。

Oracle日期函数周计算trunc函数to_char函数修改时间:2026-05-25 00:00:49

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。