Frage Wie verwende ich Date in Javascript für prähistorische Daten?


Ich arbeite an einem Projekt, bei dem das JavaScript-Datum nicht groß genug ist.

Ich möchte mehrere Ereignisse auf derselben Zeitachse platzieren, einige von ihnen haben Monat und Tag und andere nicht, so dass nur die Verwendung von Jahr keine Option ist. Ich möchte in der Lage sein, den Mond und den Big Bang auf der gleichen Achse landen zu lassen.

Es würde mir sehr helfen, wenn ich die Funktionalität des vorhandenen Date-Objekts nutzen könnte. Es geht nur 270.000 Jahre zurück und ich muss den ganzen Weg zurück zum Urknall (13.800.000.000 Jahren) gehen. Ich brauche die Daten nicht, um Sekunden oder Millisekunden zu enthalten.

Wie kann ich das Date-Objekt erweitern, um die Darstellung für solche Daten einzuschließen?

Ich habe versucht, Bibliotheken oder native Funktionen dafür zu finden, aber ohne Glück. Ich begann auch nach einer JavaScript-Implementierung des Date-Objekts zu suchen, das ich modifizieren konnte, aber ich hatte auch kein Glück.

Aktualisieren:

Ich habe mit der remdevtec-Lösung angefangen, aber am Ende habe ich ziemlich viel geändert. Ich wollte, dass die Daten in numerischer Reihenfolge erscheinen, um das Sortieren und Sortieren der Daten zu erleichtern.

Also, was ich getan habe, war, dass, wenn das Jahr vor -100.000 ist, ich den Millisekundenwert als Stunden behandle. Das ist, was ich bis jetzt bekommen habe, und es funktioniert in unserem Projekt, aber wenn ich mehr Zeit bekomme, werde ich es aufräumen und es auf GitHub setzen.

JSFidel

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
2018-01-20 09:40


Ursprung


Antworten:


Ich brauche die Daten nicht, um Sekunden oder Millisekunden zu enthalten.

Beachten Sie, dass sich der Gregorianische Kalender in Zyklen von 400 Jahren bewegt, also in Zyklen von 240.000 Jahren. Daher können Sie die 60000-Millisekunden-Darstellung von Date, die Sie nicht verwenden möchten, um in Zyklen von 240000 Jahren zurückzugehen (bis zu 60000 solcher Zyklen). Dies kann Sie zu ungefähr Jahr bringen 14,4 Milliarden BC (kurz vor Big Bang :)), mit Minutenauflösung.

Das folgende Beispiel berücksichtigt nicht die gesamte Funktionalität des Date-Objekts. Mit der weiteren Implementierung glaube ich, dass es möglich ist, ähnliche Funktionalität zu haben. Zum Beispiel, ein BigDate, x, ist größer als ein anderes BigDate, y, wenn beide Daten sind AC und x.original > y.original oder wenn x.isAC() aber !y.isAC()oder wenn beide Daten sind BC so dass entweder x.getFullYear() < y.getFullYear() oder x.getFullYear() === y.getFullYear() && x.original > y.original.

BigDate Nutzung:

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..

Und hier kommt das Fleisch:

// 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;
}

Einige Demo (kann auch verwendet werden, um zu produzieren 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";

Der resultierende Inhalt wäre: 4847996014 Jan 28 8: 21 BC

Hier ist ein JSFidel.

Klärung

Bezüglich (begründeter) Design - Kommentare bin ich mir bewusst, dass die BigDate Das oben dargestellte Objekt zeigt eine schlechte Schnittstelle und ein schlechtes Design. Das Objekt ist nur als ein Beispiel dargestellt die ungenutzten Informationen von Sekunden und Millisekunden zu verbrauchen, um die Frage zu erfüllen. Ich hoffe, dieses Beispiel hilft, die Technik zu verstehen.


81
2018-01-20 10:49



Wenn Sie nur Jahre darstellen müssen, kann eine einfache Zahl ausreichen: Sie können bis zu +/- 9007199254740991 darstellen.

Sie könnten es in eine benutzerdefinierte Klasse einfügen, um es mit Datumsfunktionen zu versehen.


31
2018-01-20 09:46



Wickeln Sie das Datum ein

Erstellen Sie eine eigene Klasse, die die Date-Klasse erweitert, indem Sie ein langes ganzzahliges Feld "Year Offset" hinzufügen.

Aktualisieren Sie alle Methoden, die Sie verwenden möchten, um dieses Jahr Offset anzuwenden - Sie können fast alles so lassen, wie es ist, da Sie die Komplexität der Bearbeitungszeit und der Tage nicht berühren; Vielleicht ist es sogar genug für Sie, die Konstruktoren und Formatierungsroutinen zu ändern, um "Ihr" Jahr in sie aufzunehmen.


18
2018-01-20 11:53



Das ECMAScript sagt:

Ein Date-Objekt enthält eine Zahl, die einen bestimmten Zeitpunkt angibt   Zeit bis zu einer Millisekunde. Eine solche Nummer wird als Zeitwert bezeichnet. EIN   Der Zeitwert kann auch NaN sein, was anzeigt, dass das Date-Objekt dies nicht tut   repräsentieren einen bestimmten Zeitpunkt.

Die Zeit wird in ECMAScript in Millisekunden seit dem 1. Januar 1970 gemessen   KOORDINIERTE WELTZEIT. In Zeitwerten werden Schaltsekunden ignoriert. Es wird angenommen, dass dort   sind genau 86.400.000 Millisekunden pro Tag. ECMAScript Number-Werte   kann alle Ganzzahlen von -9.007.199.254.740.992 bis   9,007,199,254,740,992; Dieser Bereich reicht aus, um Zeiten zu messen   Millisekunden-Genauigkeit für jeden Augenblick, der innerhalb von ungefähr ist   285.616 Jahre, entweder vorwärts oder rückwärts, ab dem 1. Januar 1970 UTC.

Die tatsächliche Zeitspanne, die von ECMAScript Date-Objekten unterstützt wird, ist   etwas kleiner: genau -100.000.000 Tage bis 100.000.000 Tage   gemessen zu Mitternacht zu Beginn des 1. Januar 1970   KOORDINIERTE WELTZEIT. Dies ergibt einen Bereich von 8.640.000.000.000.000.000 Millisekunden   beide Seiten vom 1. Januar 1970, UTC.

Der genaue Zeitpunkt der Mitternacht zu Beginn des 1. Januar 1970 UTC   wird durch den Wert +0 dargestellt.

Sie können also eine benutzerdefinierte Methode für Datumsangaben erstellen, in der Sie den Ganzzahlwert als Jahr verwenden können. Aber in praktischer Hinsicht ist der Ecmascript-Bereich für Daten gut genug, um alle praktischen Daten zu enthalten. Derjenige, den Sie zu erreichen versuchen, macht keinen praktischen Sinn / Sinn, da selbst einer nicht sicher ist, ob er dem entspricht Babylonische Astrologie?


11
2018-01-20 09:48