如何在Javascript中使用date史前date?
我正在处理JavaScriptdate不够大的项目。
我想在同一时间轴上放置多个事件,其中一些有一个月和一天,一些不这样做,所以只使用一年不是一个选项。 我希望能够在同一轴线上登月和大爆炸。
如果我可以使用现有的Date对象所具有的function,这将有很大的帮助。 它只有27万年,我需要回到大爆炸(138亿年前)。 我不需要date来包含秒或毫秒。
我怎样才能扩展date对象来包含这样的date表示?
我试图find这个图书馆或本地function,但没有运气。 我也开始寻找一个我可以修改的Date对象的JavaScript实现,但是我在这里也没有运气。
更新:
我从remdevtec解决scheme开始,但最终修改了很多。 我希望date以数字顺序排列,以便更容易sorting和排列date。
所以我所做的是如果年份在-100,000之前,我把毫秒值看作小时。 这是我到目前为止,它在我们的项目中,但如果我有更多的时间,我会清理它,并把它放在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(); };
我不需要date来包含秒或毫秒。
请注意,公历以400年为周期,因此以240000年为周期。 因此,您可以采取Date
的60000毫秒表示,您不想使用,在240000年周期(最多60000个这样的周期)返回。 这可以带你到公元前144亿年 (大爆炸:)之前),分钟的分辨率。
以下示例未考虑Date对象的所有function。 然而,随着进一步的实施,我相信有可能具有类似的function。 例如,如果两个date都是AC
并且x.original > y.original
或者x.isAC()
但是!y.isAC()
,或者如果两个date都是BC
,那么一个BigDate x
比另一个BigDate y
大。例如x.getFullYear() < y.getFullYear()
或x.getFullYear() === y.getFullYear() && x.original > y.original
。
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..
肉来了:
// 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; }
一些演示(也可以用来生成BigDate.prototype.toString()
等):
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";
结果内容是: 4847996014 Jan 28 8: 21 BC
这是一个JSFiddle 。
澄清
关于(合理的)devise评论,我知道上面提到的BigDate
对象体现了糟糕的界面和devise。 该对象仅作为消耗秒和毫秒的未使用信息来满足该问题的示例 。 我希望这个例子有助于理解这个技术。
如果你只需要代表几年,一个简单的数字可能是足够的:他们可以代表高达+/- 9007199254740991。
您可以将其包装到自定义类中,以提供date函数。
包裹date
创build一个自己的类,通过添加一个长整型字段“年偏移量”来扩展Date类。
更新你想用来申请今年抵消的所有方法 – 因为你没有触及处理时间和日子的复杂性,所以你可以把所有的东西都保留下来。 也许它甚至足以让你改变构造函数和string格式化例程以在其中包含“你的”年份。
ECMAScript说:
Date对象包含一个数字,指示一个毫秒内的特定瞬间。 这样的数字被称为时间值。 时间值也可以是NaN,表示Date对象不代表特定的时间。
时间自1970年1月1日起以毫秒为单位在ECMAScript中测量。 在闰秒的时间值被忽略。 假定每天正好有86,400,000毫秒。 ECMAScript数值可以表示从-9,007,199,254,740,992到9,007,199,254,740,992的所有整数; 这个范围足以测量在1970年1月1日UTC以前的或大约285,616年内任何瞬间的毫秒精度的时间。
由ECMAScript Date对象支持的实际时间范围略小:UTC时间1970年1月1日开始的午夜,相当于-100,000,000天至100,000,000天。 1970年1月1日UTC的任何一边的时间范围为864000000000毫秒。
1970年1月1日午夜UTC的准确时刻由值+0表示。
因此,您可以为date创build自定义方法,您可以使用整数值作为年份。 但是实际上,Ecmascript的date范围足以保存所有的实际date。 你试图达到的那一个没有真正的实际意义/意义,因为即使不确定它是否跟随巴比伦占星术 ?