Real'sHowTo AddThis Feed Button
Custom Search

Get a julian dateTag(s): Date and Time


A Julian date is the number of elapsed days since the beginning of a cycle of 7,980 years invented by Joseph Scaliger in 1583. The purpose of the system is to make it easy to compute an integer (whole number) difference between one calendar date and another calendar date.

The starting point for the first Julian cycle began on January 1, 4713 B.C. and will end on January 22, 3268 (3268-01-22 G). The following day will begin the first day of the second Julian date period (or 7,980 year cycle).

import java.util.Calendar;
public class JulianDate {
 /**
  * Returns the Julian day number that begins at noon of
  * this day, Positive year signifies A.D., negative year B.C.
  * Remember that the year after 1 B.C. was 1 A.D.
  *
  * ref :
  *  Numerical Recipes in C, 2nd ed., Cambridge University Press 1992
  */
  // Gregorian Calendar adopted Oct. 15, 1582 (2299161)
  public static int JGREG= 15 + 31*(10+12*1582);
  public static double HALFSECOND = 0.5;

  public static double toJulian(int[] ymd) {
   int year=ymd[0];
   int month=ymd[1]; // jan=1, feb=2,...
   int day=ymd[2];
   int julianYear = year;
   if (year < 0) julianYear++;
   int julianMonth = month;
   if (month > 2) {
     julianMonth++;
   }
   else {
     julianYear--;
     julianMonth += 13;
   }

   double julian = (java.lang.Math.floor(365.25 * julianYear)
        + java.lang.Math.floor(30.6001*julianMonth) + day + 1720995.0);
   if (day + 31 * (month + 12 * year) >= JGREG) {
     // change over to Gregorian calendar
     int ja = (int)(0.01 * julianYear);
     julian += 2 - ja + (0.25 * ja);
   }
   return java.lang.Math.floor(julian);
 }

 /**
 * Converts a Julian day to a calendar date
 * ref :
 * Numerical Recipes in C, 2nd ed., Cambridge University Press 1992
 */
 public static int[] fromJulian(double injulian) {
   int jalpha,ja,jb,jc,jd,je,year,month,day;
   double julian = injulian + HALFSECOND / 86400.0;
   ja = (int) julian
   if (ja>= JGREG) {
     jalpha = (int) (((ja - 1867216) - 0.25) / 36524.25);
     ja = ja + 1 + jalpha - jalpha / 4;
   }

   jb = ja + 1524;
   jc = (int) (6680.0 + ((jb - 2439870) - 122.1) / 365.25);
   jd = 365 * jc + jc / 4;
   je = (int) ((jb - jd) / 30.6001);
   day = jb - jd - (int) (30.6001 * je);
   month = je - 1;
   if (month > 12) month = month - 12;
   year = jc - 4715;
   if (month > 2) year--;
   if (year <= 0) year--;

   return new int[] {year, month, day};
  }

  public static void main(String args[]) {
   // FIRST TEST reference point
   System.out.println("Julian date for May 23, 1968 : "
      + toJulian( new int[] {1968, 5, 23 } ));
   // output : 2440000
   int results[] = fromJulian(toJulian(new int[] {1968, 5, 23 }));
   System.out.println
     ("... back to calendar : " + results[0] + " "
       + results[1] + " " + results[2]);

   // SECOND TEST today
   Calendar today = Calendar.getInstance();
   double todayJulian = toJulian
      (new int[]{today.get(Calendar.YEAR), today.get(Calendar.MONTH)+1,
       today.get(Calendar.DATE)});
   System.out.println("Julian date for today : " + todayJulian);
   results = fromJulian(todayJulian);
   System.out.println
      ("... back to calendar : " + results[0] + " " + results[1]
       + " " + results[2]);

   // THIRD TEST
   double date1 = toJulian(new int[]{2005,1,1});
   double date2 = toJulian(new int[]{2005,1,31});
   System.out.println("Between 2005-01-01 and 2005-01-31 : "
      + (date2 - date1) + " days");

   /*
      expected output :
         Julian date for May 23, 1968 : 2440000.0
         ... back to calendar 1968 5 23
         Julian date for today : 2453487.0
         ... back to calendar 2005 4 26
         Between 2005-01-01 and 2005-01-31 : 30.0 days
   */
   }
 }
There is a lot of variation around the idea of a "Julian date". You can have the Modified Julian Date (JD) or the Truncated Julian Date (TJD). The main difference is the starting for counting the days.


Before Y2K, many applications (especially mainframe systems) were storing dates in a format called "the Julian format". This format is a 5 digit number, consisting of a 2 digit year and a 3 digit day-of-year number. For example, 17-July-1998 is stored as 98221, since 17-July is the 221th day of the year. This format is not really useful since Y2K! The main reason for using the 5-digits Julian date was to save disk space and still have a format easy to use to handle. dates.

A variation of this idea is to used the first four digits for the year and 3 digits for day-of-year, 17-July-1998 will be represented by 1998221.

This is a very simple format which can be manipulated easily from Java.

import java.util.Calendar;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateUtils {
  private DateUtils() {  }

  public static Date getDateFromJulian7(String julianDate)
  throws ParseException
  {
    return new SimpleDateFormat("yyyyD").parse(julianDate);
  }

  public static String getJulian7FromDate(Date date) {
    StringBuilder sb = new StringBuilder();
    Calendar cal  = Calendar.getInstance();
    cal.setTime(date);

    return  sb.append(cal.get(Calendar.YEAR))
              .append(String.format("%03d", cal.get(Calendar.DAY_OF_YEAR)))
              .toString();
  }

  public static void main(String[] args) throws Exception {
    String test = "1998221";
    Date d = DateUtils.getDateFromJulian7(test);
    System.out.println(d);
    System.out.println(DateUtils.getJulian7FromDate(d));

    /*
     * output :
     *    Sun Aug 09 00:00:00 EDT 1998
     *    1998221
     */
  }
}


blog comments powered by Disqus


If you find this article useful, consider making a small donation
to show your support for this Web site and its content.

Written and compiled by Réal Gagnon ©1998-2014
[ home ]