Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 在给定的示例中,最接近参考日期的是同一天(2012年1月1日),年份日期=1。如果我的问题不够清楚,很抱歉。也许我不明白,但您要查找的日期是存储在表中还是只查找最近的日期?问得好。我认为捕获的是闰年。如果您查找2000年前后的366,最近的可能是4年。@B_Oracle_Date - Fatal编程技术网

Oracle 在给定的示例中,最接近参考日期的是同一天(2012年1月1日),年份日期=1。如果我的问题不够清楚,很抱歉。也许我不明白,但您要查找的日期是存储在表中还是只查找最近的日期?问得好。我认为捕获的是闰年。如果您查找2000年前后的366,最近的可能是4年。@B

Oracle 在给定的示例中,最接近参考日期的是同一天(2012年1月1日),年份日期=1。如果我的问题不够清楚,很抱歉。也许我不明白,但您要查找的日期是存储在表中还是只查找最近的日期?问得好。我认为捕获的是闰年。如果您查找2000年前后的366,最近的可能是4年。@B,oracle,date,Oracle,Date,在给定的示例中,最接近参考日期的是同一天(2012年1月1日),年份日期=1。如果我的问题不够清楚,很抱歉。也许我不明白,但您要查找的日期是存储在表中还是只查找最近的日期?问得好。我认为捕获的是闰年。如果您查找2000年前后的366,最近的可能是4年。@Ben,不幸的是,日期是存储在表中的注释。它包含修改的日期、开始日期、结束日期(例如:2012年12月31日、365、1,在这种情况下,预期转换为365=2012年12月30日和2013年1月1日。修改的日期接近日期值,但可以在日期值之前、之间或


在给定的示例中,最接近参考日期的是同一天(2012年1月1日),年份日期=1。如果我的问题不够清楚,很抱歉。也许我不明白,但您要查找的日期是存储在表中还是只查找最近的日期?问得好。我认为捕获的是闰年。如果您查找2000年前后的366,最近的可能是4年。@Ben,不幸的是,日期是存储在表中的注释。它包含修改的日期、开始日期、结束日期(例如:2012年12月31日、365、1,在这种情况下,预期转换为365=2012年12月30日和2013年1月1日。修改的日期接近日期值,但可以在日期值之前、之间或之后(例如:2012年12月31日、1、1)。现在,我面临一个将这些日期转换为实际日期值的问题。虽然日期之间的间隔保证小于365,因此不需要复杂的解决方案,但我认为我将使函数足够简单,可以处理任何一般情况。为什么
sysdate=“01/01/2012”input=1 result=“01/01/2012”
而不是
result=“01/02/2012”
?@rene,我认为有一些混淆。要求是,对于参考日期(比如sysdate),找到与年中日期最接近的日期(sql中的“DDD”)。因此,任何日期都可以作为参考,并且一个介于1和366之间的值作为年中的日期。对于给定的示例,它本身就是同一天(2012年1月1日)最接近参考日期,日期=1。如果我的问题不够清楚,很抱歉。谢谢彼得森。这有点暴力(但不是你的错)。这无疑为结合我的逻辑简化执行提供了可能性。谢谢彼得森。这有点暴力(但这不是你的错)。这无疑为结合我的逻辑简化执行提供了一种可能性。
sysdate = "01/01/2012" input = 365     result = "31/12/2011"  
sysdate = "01/01/2012" input = 366     result = "31/12/2012"
sysdate = "01/01/2012" input =   1     result = "01/01/2012"
sysdate = "31/12/2012" input =   1     result = "01/01/2013"
CREATE OR REPLACE PROCEDURE test(ref_date_str varchar2, doy number) IS  
    ref_date         date ;  
    nearest_date     date ;  
BEGIN  
    ref_date := to_date(ref_date_str, 'dd/mm/yyyy') ;  

    WITH choices AS  
    (  
        SELECT trunc(ref_date, 'yyyy') + doy - 1 AS choice_date FROM dual  
        UNION  
        SELECT trunc(trunc(ref_date, 'yyyy') - 1, 'yyyy') + doy - 1 AS choice_date FROM dual  
        UNION  
        SELECT add_months(trunc(ref_date, 'yyyy'), 12) + doy - 1 AS choice_date FROM dual  
    )  
    SELECT choice_date INTO nearest_date FROM choices WHERE abs(ref_date - choice_date) =  
        (SELECT min(abs(ref_date - choice_date)) FROM choices) AND rownum < 2 ;  

    dbms_output.put_line(to_char(nearest_date, 'dd/mm/yyyy')) ;  
END ;  
/  
for each year backwards from current year
  if a valid date found for the doy, and it is <= sysdate
     first_date = this valid date
     exit loop

for each year forward from current year
  if a valid date found for the doy, and it is > sysdate
     second_date = this valid date
     exit loop

chosen_date = closest_to_sysdate_among(first_date, second_date)
CREATE OR REPLACE FUNCTION GetNearestDate(reference_date DATE, day_of_year NUMBER) RETURN DATE IS  
    valid_date_1    DATE ;  
    valid_date_2    DATE ;  
    iter_date       DATE ;  
BEGIN  
    iter_date := trunc(reference_date, 'yyyy') ;  

    WHILE TRUE  
    LOOP  
        valid_date_1 := iter_date + day_of_year - 1 ;  

        IF valid_date_1 < add_months(iter_date, 12) AND valid_date_1 <= reference_date THEN  
            EXIT ;  
        END IF ;  

        iter_date := trunc(iter_date - 1, 'yyyy') ;  
    END LOOP ;  

    iter_date := trunc(reference_date, 'yyyy') ;  

    WHILE TRUE  
    LOOP  
        valid_date_2 := iter_date + day_of_year - 1 ;  

        IF valid_date_2 < add_months(iter_date, 12) AND valid_date_2 > reference_date THEN  
            EXIT ;  
        END IF ;  

        iter_date := add_months(iter_date, 12) ;  
    END LOOP ;  

    IF abs(valid_date_1 - reference_date) <= abs(valid_date_2 - reference_date) THEN  
        RETURN valid_date_1 ;  
    END IF ;  

    RETURN valid_date_2 ;  
END ;  
/  
with dates as
(SELECT to_date('01-01-1980', 'DD-MM-YYYY') + rownum day,
     to_number(to_char(to_date('01-01-1980', 'DD-MM-YYYY') + rownum,
                       'DDD')) day_of_year
  FROM ALL_OBJECTS
 WHERE ROWNUM <= 100 * 365)
 select t.*
 from (select dates.*,
           abs(to_date('01-01-2012', 'DD-MM-YYYY') - dates.day) diff
      from dates
     where dates.day_of_year = 1
     order by 3) t
 where rownum <= 1
CREATE OR REPLACE FUNCTION GetNearestDate(reference_date DATE, day_of_year NUMBER) RETURN DATE IS  
    nearest_date DATE ;  
BEGIN  
    SELECT valid_date INTO nearest_date  
    FROM  
    (  
        SELECT first_date + day_of_year - 1 AS valid_date  
        FROM  
        (  
            SELECT add_months(trunc(reference_date, 'YYYY'), (rownum-10) * 12) AS first_date  
            FROM all_objects  
            WHERE rownum <= 20  
        )  
        WHERE to_char(first_date, 'YYYY') = to_char(first_date + day_of_year - 1, 'YYYY')  
        ORDER BY abs(first_date + day_of_year - 1 - reference_date), first_date  
    )  
    WHERE rownum < 2 ;  

    RETURN nearest_date ;  

EXCEPTION WHEN OTHERS THEN  
    RETURN nvl(reference_date, sysdate) ;  
END ;  
/