我需要在oracle中找到特定年份、星期和工作日的日期。在oracle中有内置的函数吗?或者我怎样才能做到这一点呢?
例如:如果是Year=2019,Week=22,Day=2(星期二),那么日期应该是'28-05-2019‘。
发布于 2019-05-28 21:43:52
我认为这没有内置的函数,你必须自己构建一个。下面是你可以使用的解决方案之一。
WITH FUNCTION getDate(p_year IN NUMBER, p_weeks IN NUMBER, p_day in NUMBER) RETURN DATE
IS
v_tmp date;
v_day number;
BEGIN
v_tmp := to_date('01/01/'||to_char(p_year),'dd/mm/yyyy');
v_day := to_char(v_tmp,'D');
RETURN v_tmp+(p_weeks-1)*7+p_day-(v_day)+1;
END;
SELECT getDate(2019,22,2)
FROM DUAL;
/根据我的NLS_TERRITORY设置,Oracle从星期天开始对一周中的某一天进行编号,但从您的示例中,您似乎将星期一视为一周的第一天。因此,对函数进行相同的调整,以返回预期的结果。
此外,请注意,with子句函数是Oracle 12c的新功能,如果您碰巧使用的是较旧版本的Oracle,则必须在调用存储函数之前创建它。
发布于 2019-05-28 21:22:14
根据ISO-8601,假设" week“和" year”表示周和年,您可以使用此函数:
CREATE OR REPLACE FUNCTION ISOWeekDate(YEAR INTEGER, WEEK INTEGER, DAY INTEGER) RETURN DATE DETERMINISTIC IS
res DATE;
BEGIN
IF WEEK > 53 OR WEEK < 1 THEN
RAISE VALUE_ERROR;
END IF;
res := NEXT_DAY(TO_DATE( YEAR || '0104', 'YYYYMMDD' ) - INTERVAL '7' DAY, 'MONDAY') + ( WEEK - 1 ) * 7;
IF TO_CHAR(res, 'fmIYYY') = YEAR THEN
RETURN res + DAY - 1;
ELSE
RAISE VALUE_ERROR;
END IF;
END ISOWeekDate;发布于 2019-05-29 00:42:31
从逻辑上讲,ISO周数是该(公历)历年中出现的星期四。ISO周的ISO年是指该ISO周的星期四所在的公历年份。
在ISO架构中,周始终包含7天。一周从星期一开始,星期天结束,一周中的每一天都是从1到7。
这种工作日编号方案通常不同于从内置WEEKDAY函数返回的编号方案,并且在不同的软件包中类似(或者需要特定的数据库设置),这一点值得注意。您需要一个函数来根据ISO编号方案返回特定日期的星期几。
一年中的第一个星期四可以发生在01-Jan到07-Jan范围内的任何地方。
如果第一个星期四是1月1日,则该年的第一个ISO周将包括上一公历年度的日期(29/31-12月)。
如果第一个星期四是1月7日,则上一公历年度的最后一周ISO将包括本公历年度的天数(01/03-Jan)。
如果第一个星期四是1月4日,那么暗示着今年的第一个ISO周是从1月1日星期一开始的。
要设计一个算法,最简单的方法可能是确定给定年份中04-Jan在哪个工作日,然后应用以下计算4 - weekday。如果发现04-Jan的工作日是星期四,则结果将为0。如果是星期一,结果将是3 (4-1)。如果是星期天,结果将是-3 (4-7)。我们将存储此偏移量,以供下一步使用。
我们可以从国际标准化组织的周和日数字中推导出临时的一年中的日偏移量,如下所示:(((iso_week - 1) * 7) - (4 - iso_day))。
然后,我们将第一阶段中导出的偏移量应用于最终的年中一天的偏移量。这是给定公历年的1月4日的偏移量。如果相关日期在给定年份的1月4日之前,则此偏移量可能为负数。
给定年中某一天的偏移量,然后我们可以使用内置函数来生成给定年份的04-Jan,并应用该日偏移量来生成最终的公历日期。
例如,给定2019-W01-1。
2019-01-04是星期五,所以工作日是5,第一步的结果是-1 (4-5)。第二步的结果是-3 (1-1)*7)- (4-1))。它们加在一起会产生-4的一年中的日期偏移量。2019年1月4日-2018年12月31日偏移量为-4。
这是我们的结果: 2019-W01-1 = 2018-12-31。
https://stackoverflow.com/questions/56342997
复制相似问题