Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8542605
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T12:06:32+00:00 2026-06-11T12:06:32+00:00

I am looking for a simpler solution to find the nearest date (with respect

  • 0

I am looking for a simpler solution to find the nearest date (with respect to sysdate) for a given day of year value. Examples (in format “dd/mm/yyyy”)

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"

Basically the resulting date can be in current year, previous year or next year. Initially I wrote a small procedure as given below. Here I am using a reference date instead of sysdate to test the results. This works for cases where the input day of year is not 366. But when it is 366, this fails and one may need to travel further backwards and forward to find the nearest valid date. After adding the checks for leap year (all conditions 4,100,400 etc) the code became a real mess.

I would appreciate if you can suggest a simpler, better and foolproof solution (function or single query). Please do not use complex constructs too specific to Oracle as I will have to port the same to DB2 as well. Also, efficiency is of least concern as it is not going to be executed heavily.

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 ;  
/  

Logically the algorithm I am considering is

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)

EDIT 1 : Given below is the implementation of the algorithm I have given above (there is some redundancy in the code). I am still looking forward for alternatives or refinements to the solutions.

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 ;  
/  

EDIT 2 : The check “valid_date_? < add_months” is to ensure that this date is on the same (iterated) year itself (otherwise, a value of 366, for a non-leap year will return next year start day). Also, the associated comparison with reference date is to guard against cases like (reference = “30/01/2012”, input = 365). Here the valid_date_1 should be “31/12/2011” and not “30/12/2012”, as the first one is the closest date to the reference, with day of year value as 365.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T12:06:33+00:00Added an answer on June 11, 2026 at 12:06 pm

    Following is the solution that I am planning to use for the time being. I had to avoid WITH clause in order to make it work with DB2. Peterson’s solution helped to think in this direction.

    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 ;  
    /  
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have been looking around for hours trying to find a clear simple solution
I am looking for simple and short solution of accessing SELECT value on HTML
I'm looking for a simple solution using Python to store data as a flat
I am looking for a simple solution to do Exception Logging combined with Error
I'm looking for a simple C# solution to manage a playlist. Not the actual
I'm looking at a SSO (Single Sign On) solution to fit our relatively simple
Omar Al Zabir is looking for a simpler way to do AOP style coding.
I'm looking for a framework that offers something simpler to the books in the
i am looking for a way to sort the results of find returning a
I'm looking for a way to find the longest word ( base on length

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.