How to use Date in Javascript for prehistoric dates?

前端 未结 4 1578
盖世英雄少女心
盖世英雄少女心 2021-01-30 12:42

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

4条回答
  •  清歌不尽
    2021-01-30 12:46

    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

    
    
    
    
    
    
    

    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.

提交回复
热议问题