How to use Date in Javascript for prehistoric dates?

Im working on a project in which the JavaScript date is not long enough.

I want to place several events on the same time axis, some of them have a month and a day, and some do not, so just using the year is not an option. I want to be able to land on the moon and a big bang on the same axis.

This will help a lot if I can use the functionality that exists on an existing Date object. He’s only returning 270,000 years, and I need to return to the Big Bang (13,800,000,000 years ago). I don't need dates to hold seconds or milliseconds.

How can I extend a Date object to include a view for such dates?

I tried to find libraries or my own functions for this, but with no luck. I also started looking for a JavaScript implementation of a Date object that I could change, but I was also out of luck.

Update:

I started with remdevtec, but ended up changing it quite a lot. I wanted the dates to come in numerical order to simplify the sorting and ordering of dates.

So, I did that if the year is up to -100,000, I treat the millisecond value as a clock. This is what I got so far, and it works in our project, but if I get more time, I will clear it 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(); }; 
+75
javascript date
Jan 20 '16 at 9:40
source share
4 answers

I don't need dates to hold seconds or milliseconds.

Please note that the Gregorian calendar moves in cycles of 400 years, therefore, in cycles of 240,000 years. Therefore, you can take the 60,000 millisecond Date representation that you do not want to use to return to cycles of 240,000 years (up to 60,000 such cycles). This could take about 14.4 billion BC. E. (just before Big Bang :)), with minimal resolution.

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

Using BigDate:

 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 also be used to create 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 content 4847996014 Jan 28 8: 21 BC will be: 4847996014 Jan 28 8: 21 BC

Here's the JSFiddle .

Explanation

As for the (reasonable) design comments, I know that the BigDate object presented above demonstrates poor interface and design. An object is provided as an example for using unused seconds and milliseconds information to satisfy a question. Hope this example helps to understand the technique.

+81
Jan 20 '16 at 10:49 on
source share

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

You can port it to a custom class to provide it with date functions.

+30
Jan 20 '16 at 9:46 on
source share

Wrap date

Create your own class that extends the Date class by adding a long integer field "year offset".

Update all the methods that you want to use to apply the bias this year - you can leave almost everything as it is, since you do not touch the complexity of processing time and days; maybe it’s even enough for you to change the constructors and string formatting procedures to include β€œyour” year in them.

+18
Jan 20 '16 at 11:53 on
source share

ECMAScript says:

The Date object contains a number indicating a specific moment in time within milliseconds. This number is called the time value. the time value can also be NaN, indicating that the Date object does not represent a specific point in time.

Time is measured in ECMAScript in milliseconds since January 01, 1970. UNIVERSAL GLOBAL TIME. In time values, jump seconds are ignored. It is estimated to be exactly 86.4 million milliseconds per day. ECMAScript numbers can represent all integers from -9.007,199,254,740,992 to 9.007.199.254.740.992; this range is sufficient to measure time to millisecond accuracy for any moment that is within approximately 285,616 years, either forward or backward, from January 01, 1970 UTC.

The actual time range supported by ECMAScript Date objects is slightly less: exactly -100,000,000 days to 100,000,000 days measured relative to midnight in early January - 1970. UNIVERSAL GLOBAL TIME. This gives a range of 8,640,000,000,000,000 milliseconds from January 1, 1970 UTC.

The exact time of midnight at the beginning of January 01, 1970, UTC is +0.

So, you can create your own method for dates in which you can use the integer value as a year. But in practice, the note The interval range for dates is good enough to hold all the practical dates. The one you are trying to achieve does not give real practical meaning / meaning, since even one is not sure whether Babylonian astrology should follow it

+11
Jan 20 '16 at 9:48
source share



All Articles