Date and Time before this century in Javascript

Hello all,

I would like to create a function with which you can tell the years, months and days between two dates that also includes dates as far back as the Middle Ages! This sounds easier than it is. We had a calender reform somwhere in 1400 something. I vaguely remember a JulianDate function for C and C++ that changes dates into numbers after which you could do all sorts of calculations.

Does something like this exist for Javascript? If not How do I go about with the limited Date and Time functions available?


Maarten van Damme
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

You can't do it completely using JavaScript's getDate function because JavaScript starts on 1 January 1970 at 00:00:00:00:00 (that's in milliseconds).  This is not to say that you can't do what you want.  You just have to do it manually.  You can use the getDate function for the current date, but when the user types in the date they want some time in the dark ages you will have to do the work by hand (so-to-speak).  If you can find the code that converts these dates into the current date system then you can relatively easily to convert the code to JavaScript.  I don't know where you would find the code to do this.
maarten120997Author Commented:
I know the time/date functions have the limitations as described in the answer. That is why Iasked for a different approach. The answer lies in a converting system. This system is called Juliandate. A system also used in Astrology as I found out on the Web. You convert a date to the JulianDate number. You can d all sorts of mathematical operations with the Date number, for instance deduction (which I need here).

Now I can vaguely remember this function from C, but I want to implement it in Javascript. So the question is not answered but has narrowed the solution to the need of a different system or routine that does the trick.

Do you want to find the number of years,months,days between two dates, and the day of week that corresponds to each date?
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

maarten120997Author Commented:
In effect I want to know the timespan between two dates. As there are many examples around about the simple solution. Like: How many weeks, days etc until Christmas.

What I need is a function that just does this but over a larger time span. To make things worse... One of the dates will be long before the 1970 date used when all PC's seem to have started ...

I even need the flexibility to go to dates that lay before the Gregorian calender system now in use. And it still should be accurate. I mentioned in my earlier reply that Juliandate type constructions were used in Astrology. What I ment is Astronomy, but in fact there is not much difference as they both want to establish positions of stars on dates that may lay thousands of years back in the past.

Thanks sofar,

Programming it shouldn't be much more than an exercise in mathematics.  What is left to be done would be a matter of what special cases exist in the time span.  I believe there was some point a century or two back where there was a shift by a couple of days.  If you have a list of these shifts and when they occured, I, or someone else will be able to do it quite easily.
But, this is probably the wrong group to ask an historical question of what those times and dates might be.
 Can you get the source for that C function that said you remembered? Or, do you know how you can convert a date to a 'JulianDate'. It wouldn't be too hard to convert it to JavaScript from either of those.
  And you should be able to get around the 1970 barrier by creating your own date object.

The Bit
I agree with TheBit, and haystor, the JS date is right out the window, and if you can get the mathematics of the conversion, or the information on the historical date shifts, and pre-Gregorian Calendar format, then it becomes just a simple exercise. So if you can post it up, someone will solve it for you...
Ok, this topic peaked my curiosity so I went and did a bit-o-research and for all you time history starved people here goes:

The Julian Calendar was created in 42 B.C. in Rome.  It got it's name in 1771 after Julius Ceaser.  The time system is almost exactly as the one we now use (called Gregorian, derived in 1771, after Pope Gregory XIII) which was adopted in England and US in 1752, but was in general use in 1582.

The difference between the 2 systems is when leap year was determined.  Gregorian says years divisible by 400.  Julian says just every 4 years.  So if someone knows what year(s) were leap years during the Julian calendar time you've got the whole mess laid out in front of you.

Now for a couple of wrenches:
There are 2 other calendars that are used to day.  The Jewish and Islamic.  Both of these use 29 or 30 days for each month and neither is the same.
Whew, this turned out to be more complicated than I figured when I started. I figured I'd just get the perl JulianDate module and convert it.. but I was amazed to discover when I analyzed it that the so-called "JulianDate" conversion really doesn't take the Julian calendar (leap year every 4 years without fail) into account, or account for the days skipped when converting to the Gregorian calendar. (So why they don't call it "Gregorian Date", I don't know - the module prints a warning when you go back too far but still applies Gregorian-style leap year rules). When I tried to adjust for these factors, I found the module's code had been so highly optimized that I basically had to start over, though some of the julian_date function was convertible.

But here they are: the following script has functions allowing you to convert a given date (the current date at the time, Julian-style before 10/4/1582 and Gregorian after that date) to and from a standard JulianDate, with which you can do reliable arithmetic taking into account all leap years and skipped days according to the two calendars. (The date of changeover is according to Pope Gregory, though not all countries converted at the time). This should be valid for date arithmetic from about 8AD (when they finally standardized leap years, supposedly) until the next time an extra leap day is needed sometime after the year 4000.

// calculate the julian day, given year, month and day
// (according to the  calendar in effect at the time)
function  julian_day (year, month, day)
 tmp= day  - 32113
 + Math.floor(1461 * ( year + 4800 - Math.floor(( 14 - month ) / 12) )/4)
 + Math.floor(367 * ( month - 2 + Math.floor( ( 14 - month ) / 12 ) * 12 ) / 12);

 // if Gregorian, adjust for no leap year in years ending in 00 but not divisible by 400
 // first day of pope's gregorian calendar was 10/15/1582
 // (10 days skipped, days after from 10/4/1582 was 10/15/1582)
 if (year * 10000+month*100+day >= 15821015) {
  tmp = tmp - Math.floor(3 * Math.floor( Math.floor( year + 4900 - Math.floor(( 14 - month ) / 12) ) / 100 ) / 4) + 38;
 return tmp;

// Used to calculate the month
// (Feb. [1] modified each time inverse_julian_day is called)
var months = new Array(31,28,31,30,31,30,31,31,30,31,30,31,999);

// calculate the year,month,and day given the julian day
// returns results as an array (year,month,day)
function inverse_julian_day (jd)
var m,d,y;

 // gregorian  (starting 10/15/1582)
 if (jd >= 2299161) {
   d = jd - 1721426;
   y400 = Math.floor(d/146097);
   d -= y400*146097;
   y100 = Math.floor(d/36524);
   if (y100==4) y100=3;
   d -= y100*36524;
   y4 = Math.floor(d/1461);
   d -= y4*1461;
   y1 = Math.floor(d/365);
   if (y1==4) y1=3;
   d = d-y1*365+1;
   y = y400*400 + y100*100 + y4*4 +y1 +1;
   leap = (y % 400) == 0 || ((y % 100) != 0 && (y % 4) == 0);
   months[1]= leap ? 29 : 28;
   for (m=1; d > months[m-1]; m++) d = d-months[m-1];
 else {
   // Julian  (leap year every 4 years, no exceptions, until 10/4/1582)
   y = Math.floor((jd-1721058)/365.25);
   months[1]= (y % 4 == 0) ? 29 : 28;
   for (m=1; d > months[m-1]; m++) d -= months[m-1];
 return new Array(y,m,d);

<form name=frm>
YYYY-M-D: <input type=text size=4 name=year value=1970>
- <input type=text size=2 name=month value=1>
- <input type=text size=2 name=day value=1><br>
 Julian Date: <input type=text size=20 name=jday><br>
Date Y-M-D: <input type=text size=20 name=date><br>
<input type=button value="YYYY-M-D -> Julian"
<input type=button value="Julian -> YYYY-M-D"
 d=new Array;

Good luck!

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.