Thread: Convert a Julian Day to gregorian

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    6

    Convert a Julian Day to gregorian

    I need to write a function in C that will be passed the current julian date for the current year for e.g

    333 is today 28/11/2008 format required 20081128

    60 is the 29/02/2008 format required 20080229

    I have a function but it is very cumbersome and I am sure it could be far simpler than the way it is written.

    Code:
    char* getpaydate(char *date)
    {
      time_t  currtime;
      char charJuli[8] = {0};
      char charYear[6] = {0};
      char caldate[8] = {0};
      int Yr,Dy,JDD;
      int q = 0;
      int Mt[] = {31,28,31,30,31,30,31,31,30,31,30,31};
    
      time(&currtime);
      strftime(charJuli,sizeof(charJuli)-1,"%j",localtime(&currtime));
      strftime(charYear,sizeof(charYear)-1,"%Y",localtime(&currtime));
    
      Yr = atoi(charYear);
      JDD = atoi(charJuli);
      Dy = atoi(date);
    
      if (Dy > 345 && JDD < 20)
      {
        Yr--;
      }
      if ((Yr/4)*4==Yr)
      {
        Mt[1] = 29;
      }
      if (((Yr/100)*100==Yr)&&((Yr/400)*400!=Yr))
      {
        Mt[1] = 28;
      }
      while ( Dy > Mt[q] )
      {
        Dy = Dy - Mt[q];
        q++;
      }
      q++;
      sprintf(caldate,"%i%02i%02i",Yr,q,Dy);
      printf("Start of the debug:%s\n", date );
      printf("Value of date equals :%s\n", date );
      printf("Value of charJuli equals :%s\n", charJuli );
      printf("Value of charYear equals :%s\n", charYear );
      printf("Value of caldate equals :%s\n", caldate );
      printf("Value of Yr equals :%d\n", Yr );
      printf("Value of JDD equals :%d\n", JDD    );
      printf("Value of Dy equals :%d\n", Dy );
      printf("End of Initial debug:%s\n", date );
      return caldate;
    }
    This if passed in a day of the year will get the current year and return the gregorian date 2008mmdd - so if it were returning today's date you would pass in the number 333 to get 20081128 and say 60 to get 20080229 (leap year).

    Does this make sense ?

    There was a super post of a function that presented the current julian date see below.
    Code:
    #include <stdio.h>
    #include <time.h>
    
    int main(void)
    {
       time_t now;
       if ( time(&now) != (time_t)(-1) )
       {
          struct tm *mytime = localtime(&now);
          if ( mytime )
          {
             char jday [ 4 ];
             if ( strftime(jday, sizeof jday, "%j", mytime) )
             {
                printf("mytime->tm_yday = %d, jday = \"%s\"\n", mytime->tm_yda
    y, jday);
             }
          }
       }
       return 0;
    }
    Thanks in advance.

  2. #2
    Resu Deretsiger Nightowl's Avatar
    Join Date
    Nov 2008
    Location
    /dev/null
    Posts
    186
    Looking at the wiki entries for the Julian calendar and the Gregorian calendar . . .

    The difference seems to be that in the Gregorian calendar, each day is 365.24 days long rather than 365.25 days long . . .

    Looking here, the conversion is fairly simple, is it not?
    Do as I say, not as I do . . .

    Experimentation is the essence of programming. Just remember to make a backup first.

    "I'm a firm believer that <SomeGod> gave us two ears and one mouth for a reason - we are supposed to listen, twice as much as we talk." - LEAF

    Questions posted by these guidelines are more likely to be answered.

    Debian GNU/Linux user, with the awesome window manager, the git version control system, and the cmake buildsystem generator.

  3. #3
    Resu Deretsiger Nightowl's Avatar
    Join Date
    Nov 2008
    Location
    /dev/null
    Posts
    186
    Something like (in pseduocode)

    Code:
    juliandate = (((gregoriandate-1800)/100) + 12)
    if(juliandate > daysinthemonth[gregorianmonth]) juliandate -= daysinthemonth[gregorianmonth++]
    Would work, no?
    Do as I say, not as I do . . .

    Experimentation is the essence of programming. Just remember to make a backup first.

    "I'm a firm believer that <SomeGod> gave us two ears and one mouth for a reason - we are supposed to listen, twice as much as we talk." - LEAF

    Questions posted by these guidelines are more likely to be answered.

    Debian GNU/Linux user, with the awesome window manager, the git version control system, and the cmake buildsystem generator.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    OP, you are not working with the Julian date; the Julian date is much much larger than that. In particular, wikipedia says this: "The Julian date (JD) is the interval of time in days and fractions of a day, since 4713 BC January 1, Greenwich noon, Julian proleptic calendar.[1] " You are working with the ordinal date.

    In which case it is much easier to find the date.

    A good guess for the month is ordinal / 30

    A good guess for the day of the month is the difference between the ordinal number and the days that have elapsed since the start of the month, i.e.: ordinal - ( mm - 1 ) * 30

    But these are simply guesses and will need to be corrected more often than not depending on several factors, including leap years. I would stick with what you already have.
    Last edited by whiteflags; 11-28-2008 at 11:54 AM.

  5. #5
    Resu Deretsiger Nightowl's Avatar
    Join Date
    Nov 2008
    Location
    /dev/null
    Posts
    186
    . . . right . . . Julian Calendar and Julian dates. *sigh*

    The wiki entry has some nice information on calculating Julian dates.
    Do as I say, not as I do . . .

    Experimentation is the essence of programming. Just remember to make a backup first.

    "I'm a firm believer that <SomeGod> gave us two ears and one mouth for a reason - we are supposed to listen, twice as much as we talk." - LEAF

    Questions posted by these guidelines are more likely to be answered.

    Debian GNU/Linux user, with the awesome window manager, the git version control system, and the cmake buildsystem generator.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    The Julian date isn't always in the range of 1-366. OP is not working with Julian dates. For some reason people mix up the meaning of Julian dates and ordinal dates, when they are really not related at all.

  7. #7
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    The following function is based on a formula from Deshowitz and Reingold's Calendrical Calculations. Refer to to footnote #5 at Julian dates which is the same link from post #5. Now all you need to do is some repetitive subtraction from the ordinal date.


    Code:
    int DaysInMonth(int iYear, int iMonth) 
    {
        return iMonth*275%9 > 3 ? 31
            : iMonth != 2     ? 30
            : iYear % 4     ? 28
            : iYear % 100  ? 29
            : iYear % 400 ? 28
            : 29;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Formula to convert Calaneder Date to Julian ?
    By colmustang in forum C Programming
    Replies: 2
    Last Post: 03-21-2008, 05:17 AM
  2. Julian day of year
    By marcelowuo in forum C Programming
    Replies: 6
    Last Post: 06-15-2005, 05:11 PM
  3. error with code
    By duffy in forum C Programming
    Replies: 8
    Last Post: 10-22-2002, 09:45 PM
  4. debug program
    By new_c in forum C Programming
    Replies: 3
    Last Post: 03-18-2002, 11:50 PM
  5. Simplified code
    By soonerfan in forum C Programming
    Replies: 2
    Last Post: 12-05-2001, 03:50 PM