如何在Javascript中使用日期作为史前日期?


76

我正在研究JavaScript Date不够大的项目。

我想在同一时间轴上放置多个事件,其中一些事件有月和日,而有些则没有,所以仅使用年份是不可选项。我希望能够使月亮落在同一轴上并发生大爆炸。

如果我可以使用现有Date对象所具有的功能,那将有很大帮助。它只能追溯到270,000年,而我需要一直回到大爆炸(138亿年前)。我不需要日期包含秒或毫秒。

如何扩展Date对象以包括此类日期的表示形式?

我试图为此找到库或本机函数,但是没有运气。我也开始寻找可以修改Date对象的JavaScript实现,但是我在这里也没有运气。

更新:

我从remdevtec解决方案开始,但最终对其进行了很多修改。我希望日期按数字顺序排列,以便于对日期进行排序和排序。

所以我所做的是,如果年份在-100,000之前,则将毫秒值视为小时。这是我到目前为止所获得的,并且可以在我们的项目中使用,但是如果我有更多时间,我将对其进行清理并放在github上。

JSFiddle


14
您应该指定这些日期的要求。您是否需要执行日期算术?
亚伦

23
如果一年是公元前45,000,000,您真的需要知道几天和几个月吗?如果是这样,您要使用哪个日历(特别是因为该日期早于日历和人类)?我想记录Dippy的生日可能会很好。
MT0

2
了解日历系统再维持27万年的可能性极小。哎呀,甚至1000年。非常长距离的日期计算可能是徒劳的。这也适用于时光倒流:第一次世界大战后大约一百年前,当前的格里高利历系统才在全球根深蒂固。
Simba

13
代表27万年=最好的第一世界问题。
CodeAngry

1
您是否考虑过使用对数刻度?
sampathsris '16

Answers:


81

我不需要日期包含秒或毫秒。

请注意,公历以400年为周期移动,因此以240,000年为周期移动。因此,您可以将Date不想使用的60000毫秒表示形式返回到240000年的循环中(最多60000个这样的循环)。这可以将您带到大约144亿年的BC(仅在Big Bang之前):)。

下面的示例未考虑Date对象的所有功能。但是,通过进一步的实施,我相信可能具有类似的功能。举例来说,一个BigDate,x是比另一个BigDate更大,y如果这两个日期ACx.original > y.original或者x.isAC()不过!y.isAC(),或者如果这两个日期是BC这样的,要么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

澄清度

关于(合理的)设计评论,我知道BigDate上面介绍的对象表现出较差的界面和设计。提出该对象仅作为使用秒和毫秒的未使用信息来满足该问题的示例。我希望该示例有助于理解该技术。


@Zach Ross-Clyne感谢您的编辑建议。我已经编辑了更多内容,包括您的getSeconds()使用建议。
remdevtec

12
不仅将偏移量/因子存储在BigDate实例上,还不将其隐藏在包装的Date对象中?另外,您应该公开一个有用的构造函数,而不要让人们弄乱“因素”。
Bergi

2
我在@Bergi。劫持秒和毫秒是不必要的,并且非常令人困惑。这是非常糟糕的设计。-1。
jpmc26 2016年

2
在编辑之前,我没有看到原始文档,但我认为您没有将给定的批评真正纳入到您的修订中。我仍然看到偏移Date没有特别的原因(无论如何也没有解释的原因)被塞入对象的秒和毫秒字段中。为什么不将偏移量放在旁边的单独字段中this.original?更不用说将来的大日期不能不间断地表示isAC()。正如其他评论员所指出的那样,这是较差的设计,并且IMO在当前状态下不应是最高评级/可接受的答案。
sv 2016年

@sv这个问题不在乎表示将来的较大日期。关于您的其他评论,请参阅帖子中的附加说明。
remdevtec

31

如果只需要表示年份,那么一个简单的数字可能就足够了:它们最多可以表示+/- 9007199254740991。

您可以将其包装到一个自定义类中,以为其提供日期函数。


18

包装日期

创建自己的类,通过添加一个长整数字段“ year offset”来扩展Date类。

更新您要在今年的偏移量中使用的所有方法-您几乎可以保留所有内容,因为您无需担心处理时间和日期的复杂性;也许您甚至足以更改构造函数和字符串格式化例程以在其中包含“ your”年份。


11

ECMAScript中说:

Date对象包含一个数字,该数字指示毫秒内的特定时间点。这样的数字称为时间值。时间值也可以是NaN,表示Date对象不代表特定的时间点。

自1970年1月1日UTC以来,时间以ECMAScript表示,以毫秒为单位。在时间值上,leap秒将被忽略。假设每天精确地有86,400,000毫秒。ECMAScript Number值可以表示从–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天。这给UTC 1970年1月1日的任一侧提供了8,640,000,000,000,000毫秒的范围。

UTC 1970年1月1日开始时的确切午夜时刻由值+0表示。

因此,您可以为Dates创建一个自定义方法,您可以在其中使用整数值作为年份。但实际上,Ecmascript日期范围足以容纳所有实际日期。您尝试实现的目标没有真正的实际意义/意义,因为甚至不能确定它是否遵循 巴比伦占星术

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.