Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Date in Javascript for prehistoric dates?

I’m working on a project where the JavaScript Date isn't big enough.

I want to place multiple events on the same time axis, some of them have month and day and some don't, so just using year is not an option. I want to be able to have the moon landing and big bang on the same axis.

It would help a lot if I could use the functionality that the existing Date object has. It only goes back 270,000 years and I need to go all the way back to big bang (13,800,000,000 years ago). I don’t need the dates to contain seconds or milliseconds.

How can I extend the Date object to include representation for such dates?

I have tried to find libraries or native functions for this but without luck. I also started looking for a JavaScript implementation of the Date object that I could modified, but I had no luck here either.

Update:

I started with remdevtec solution but ended up modifying it quite a lot. I wanted the dates to come in numeric order to make it easier sort and order the dates.

So what I did was that if the year is before -100,000 I treat the millisecond value as hours. This is what i got so far, and it works in our project, but if I get more time I will clean it up and put it on github.

JSFiddle

function BigDate(date){      if(!date){          this.original = new Date();       }else if(date instanceof BigDate){          this.original = date.original;      }else{          this.original = new Date(date);        }      this.yearBreakpoint = -100000;      this.breakPoint = Date.UTC(this.yearBreakpoint,0,0).valueOf();      this.factor = 360000;//needed for our project to make extra space on our axis  }    BigDate.UTC = function (year, month, day, hour, minute, second, millisecond) {      var temp = new BigDate();      if(year < -temp.yearBreakpoint){          temp.setUTCFullYear(year);          return temp;      }else{          temp.original = Date.UTC(year,month,day,hour,minute,second,millisecond);      }      return temp.valueOf();  };    BigDate.now = function (){      var temp = new BigDate();      temp.original = Date.now();      return temp.valueOf();  };    BigDate.parse = function (val){      throw "not implemnted";  };    //custom functions    BigDate.prototype.getUTCDate = function () {     if(this.valueOf() < this.breakPoint){         return 0;     }     return this.original.getUTCDate();  };  BigDate.prototype.getUTCDay = function () {     if(this.valueOf() < this.breakPoint){          return 0;      }      return this.original.getUTCDay();  };  BigDate.prototype.getUTCFullYear = function () {      if(this.valueOf() < this.breakPoint){          return (this.valueOf() - this.breakPoint) / this.factor;      }      return this.original.getUTCFullYear();  };  BigDate.prototype.getUTCHours = function () {      if(this.valueOf() < this.breakPoint){          return 0;      }      return this.original.getUTCHours();  };  BigDate.prototype.getUTCMilliseconds = function () {      if(this.valueOf() < this.breakPoint){          return 0;      }      return this.original.getUTCMilliseconds();  };  BigDate.prototype.getUTCMinutes = function () {      if(this.valueOf() < this.breakPoint){          return 0;      }      return this.original.getUTCMinutes();  };  BigDate.prototype.getUTCMonth = function () {      if(this.valueOf() < this.breakPoint){          return 0;      }      return this.original.getUTCMonth();  };  BigDate.prototype.getUTCSeconds = function () {      if(this.valueOf() < this.breakPoint){          return 0;      }      return this.original.getUTCSeconds();  };    BigDate.prototype.setUTCDate = function (val) {      if(val >= this.yearBreakpoint){        return this.original.setUTCDate(val);     }  };  BigDate.prototype.setUTCFullYear = function (val) {      if(val < this.yearBreakpoint){          this.original.setTime((parseInt(val) * this.factor) + this.breakPoint);      }else{          this.original.setUTCFullYear(val);      }      return this.valueOf();  };  BigDate.prototype.setUTCHours = function (val) {      if(val >= this.yearBreakpoint){        return this.original.setUTCHours(val);      }  };  BigDate.prototype.setUTCMilliseconds = function (val) {      if(val >= this.yearBreakpoint){        return this.original.setUTCMilliseconds(val);      }  };  BigDate.prototype.setUTCMinutes = function (val) {      if(val >= this.yearBreakpoint){          return this.original.setUTCMinutes(val);      }  };  BigDate.prototype.setUTCMonth = function (val) {      if(val >= this.yearBreakpoint){        return   this.original.setUTCMonth(val);      }  };  BigDate.prototype.setUTCSeconds = function (val) {      if(val >= this.yearBreakpoint){         return  this.original.setUTCSeconds(val);      }  };    BigDate.prototype.setTime = function (val) {      this.original.setTime(val);      return this.valueOf();  };  BigDate.prototype.valueOf = function () {      return this.original.valueOf();  };      BigDate.prototype.toDateString = function () {      if(this.valueOf() < this.breakPoint){          return "Jan 01 " + this.getUTCFullYear();      }      return this.original.toDateString();  };  BigDate.prototype.toISOString = function () {      if(this.valueOf() < this.breakPoint){          return this.getUTCFullYear() + "-01-01T00:00:00.000Z";      }      return this.original.toISOString();  };    BigDate.prototype.toJSON = function () {      throw "not implemnted";  };  BigDate.prototype.toLocaleDateString = function () {      throw "not implemnted";  };  BigDate.prototype.toLocaleTimeString = function () {      throw "not implemnted";  };  BigDate.prototype.toLocaleString = function () {      throw "not implemnted";  };  BigDate.prototype.toTimeString = function () {      throw "not implemnted";  };  BigDate.prototype.toUTCString = function () {      if(this.valueOf() < this.breakPoint){          return "01 Jan "+ this.getFullYear() +" 00:00:00 GMT";      }      return this.original.toUTCString();  };          /**   * Don't need no timezones   */    BigDate.prototype.getDate = function () {      return this.getUTCDate();  };  BigDate.prototype.getDay = function () {      return this.getUTCDay();  };  BigDate.prototype.getFullYear = function () {      return this.getUTCFullYear();  };  BigDate.prototype.getHours = function () {      return this.getUTCHours();  };  BigDate.prototype.getMilliseconds = function() {      return this.getUTCMilliseconds();  };  BigDate.prototype.getMinutes = function() {       return this.getUTCMinutes();  };  BigDate.prototype.getMonth = function () {      return this.getUTCMonth();  };  BigDate.prototype.getSeconds = function () {      return this.getUTCSeconds();  };  BigDate.prototype.getTimezoneOffset = function () {      return 0;  };  BigDate.prototype.getTime = function () {      return this.valueOf();  };    BigDate.prototype.setDate = function (val) {      return this.setUTCDate(val);  };  BigDate.prototype.setFullYear = function (val) {      return this.setUTCFullYear(val);  };  BigDate.prototype.setHours = function (val) {      return this.setUTCHours(val);  };  BigDate.prototype.setMilliseconds = function (val) {      return this.setUTCMilliseconds(val);  };  BigDate.prototype.setMinutes = function (val) {      return this.setUTCMinutes(val);  };  BigDate.prototype.setMonth = function (val) {      return this.setUTCMonth(val);  };  BigDate.prototype.setSeconds = function (val) {      return this.setUTCSeconds(val);  };    BigDate.prototype.toString = function () {      return this.toUTCString();  };
like image 459
Ogge Avatar asked Jan 20 '16 09:01

Ogge


People also ask

How do you code a Date in JavaScript?

We can create a date using the Date object by calling the new Date() constructor as shown in the below syntax. Syntax: new Date(); new Date(value); new Date(dateString); new Date(year, month, day, hours, minutes, seconds, milliseconds);

How does JavaScript store dates in Adate object?

JavaScript Stores Dates as Milliseconds JavaScript stores dates as number of milliseconds since January 01, 1970, 00:00:00 UTC (Universal Time Coordinated). Zero time is January 01, 1970 00:00:00 UTC.

How do you check Date is before or after in JavaScript?

To check if a date is before another date, compare the Date objects, e.g. date1 < date2 . If the comparison returns true , then the first date is before the second, otherwise the first date is equal to or comes after the second. Copied!

Is Date a primitive JavaScript?

There is no "Date" in the list of primitive and object types, why "Date" is considered as type if it's just an object and in JavaScript if I am correct it's not possible to create our own types.


2 Answers

I don’t need the dates to contain seconds or milliseconds.

Note that Gregorian calendar moves in cycles of 400 years, hence in cycles of 240,000 years. Therefore you can take the 60000 milliseconds representation of Date, that you don't want to use, to go back in 240000 years cycles (up to 60000 such cycles). This can take you to about year 14.4 billion BC (just before Big Bang :) ), with minute resolution.

The following example is not taking into consideration all the functionality of Date object. However with further implementation, I believe it is possible to have similar functionality. For instance, one BigDate, x, is bigger than another BigDate, y, if both dates are AC and x.original > y.original or if x.isAC() but !y.isAC(), or if both dates are BC such that either x.getFullYear() < y.getFullYear() or x.getFullYear() === y.getFullYear() && x.original > y.original.

BigDate usage:

var time = new Date (   [year /*range: 0-239999*/],    [month /*range: 0-11*/],    [day of month /*range: 1-31*/],    [hours /*range: 0-23*/],    [minutes /*range: 0-59*/],    [a factor of 240,000,000 years to go back (from the first parameter year) /*range: 0-59*/],   [a factor of 240,000 years to go back (from the first parameter year) /*range: 0-999*/]);  var bigDate = new BigDate(time); 

HTML

<span id="years"></span> <span id="months"></span> <span id="date"></span> <span id="hours"></span> <span id="minutes"></span> <span id="acbc"></span> 

JAVASCRIPT

function BigDate (date) { this.original = date; }      // set unchanged methods, BigDate.prototype.getMinutes = function () { return this.original.getMinutes(); } BigDate.prototype.getHours = function () { return this.original.getHours(); } BigDate.prototype.getDate = function () { return this.original.getDate(); } BigDate.prototype.getMonth = function () { return this.original.getMonth(); }  // implement other BigDate methods.. 

And here comes the meat:

// now return non-negative year BigDate.prototype.getFullYear = function () {     var ms = this.original.getSeconds() * 1000 + this.original.getMilliseconds();   if (ms === 0) return this.original.getFullYear();   else return (ms * 240000) - this.original.getFullYear(); }  // now add AC/BC method BigDate.prototype.isAC = function () {   var result = this.original.getSeconds() === 0 &&     this.original.getMilliseconds() === 0;   return result; } 

Some demo (can as well be used to produce BigDate.prototype.toString(), etc.) :

var years = document.getElementById("years"); var months = document.getElementById("months"); var date = document.getElementById("date"); var hours = document.getElementById("hours"); var minutes = document.getElementById("minutes"); var acbc = document.getElementById("acbc");  // SET A TIME AND PRESENT IT var time = new Date (2016, 1, 28, 8, 21, 20, 200);  var bigDate = new BigDate(time); var monthsName = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; years.innerHTML = bigDate.getFullYear(); months.innerHTML = monthsName[bigDate.getMonth()];     date.innerHTML = bigDate.getDate(); hours.innerHTML = bigDate.getHours() + ":"; minutes.innerHTML = bigDate.getMinutes(); acbc.innerHTML = (bigDate.isAC()) ? "AC":"BC"; 

The resulted content would be: 4847996014 Jan 28 8: 21 BC

Here's a JSFiddle.

Clarification

Regarding (justified) design comments, I am aware that the BigDate object presented above manifests poor interface and design. The object is only presented as an example of consuming the unused information of seconds and milliseconds to satisfy the question. I hope this example helps to understand the technique.

like image 160
guysigner Avatar answered Sep 17 '22 12:09

guysigner


If you only need to represent years, a simple Number might be enough : they can represent up to +/- 9007199254740991.

You could wrap it into a custom class to provide it with date functions.

like image 41
Aaron Avatar answered Sep 18 '22 12:09

Aaron