Der Datumskonstruktor gibt NaN im IE zurück, funktioniert jedoch in Firefox und Chrome

79

Ich versuche einen kleinen Kalender in JavaScript zu erstellen. Ich habe meine Daten in Firefox und Chrome hervorragend, aber im IE geben die Datumsfunktionen NaN zurück.

Hier ist die Funktion:

function buildWeek(dateText){
    var headerDates='';
    var newDate = new Date(dateText);

    for(var d=0;d<7;d++){
        headerDates += '<th>' + newDate + '</th>';
        newDate.setDate(newDate.getDate()+1);
    }                       

    jQuery('div#headerDates').html('<table><tr>'+headerDates+'</tr></table>');
}

dateTextist der Montag der aktuellen Woche, der tatsächlich in PHP im Format 'm, d, Y' eingestellt ist, z "02, 01, 2010".

Pedalpete
quelle
2
Sie haben einige Fehler beim Kopieren und Einfügen in Ihrem Codebeispiel. Sehen Sie sich die for-Anweisung an: for(var d=0;d';Das wird einen SyntaxError...
Christian C. Salvadó
Beantwortet das deine Frage? Warum liefert Date.parse falsche Ergebnisse?
Heretic Monkey

Antworten:

67

Der Date-Konstruktor akzeptiert einen beliebigen Wert. Wenn das Grundelement [[Wert]] des Arguments die Zahl ist, hat das Erstellungsdatum diesen Wert. Wenn primitiv [[Wert]] String ist, garantiert die Spezifikation nur, dass der Date-Konstruktor und die Analysemethode das Ergebnis von Date.prototype.toString und Date.prototype.toUTCString () analysieren können.

Eine zuverlässige Möglichkeit, ein Datum festzulegen, besteht darin, eines zu erstellen und die Methoden setFullYearund zu setTimeverwenden.

Ein Beispiel dafür finden Sie hier: http://jibbering.com/faq/#parseDate

ECMA-262 r3 definiert keine Datumsformate. Das Übergeben von Zeichenfolgenwerten an den Date-Konstruktor oder Date.parse hat ein implementierungsabhängiges Ergebnis. Es wird am besten vermieden.


Bearbeiten: Der Eintrag aus den häufig gestellten Fragen zu comp.lang.javascript lautet: Ein erweitertes lokales ISO 8601-Datumsformat YYYY-MM-DDkann wie Datefolgt analysiert werden : -

/**Parses string formatted as YYYY-MM-DD to a Date object.
 * If the supplied string does not match the format, an 
 * invalid Date (value NaN) is returned.
 * @param {string} dateStringInRange format YYYY-MM-DD, with year in
 * range of 0000-9999, inclusive.
 * @return {Date} Date object representing the string.
 */

  function parseISO8601(dateStringInRange) {
    var isoExp = /^\s*(\d{4})-(\d\d)-(\d\d)\s*$/,
        date = new Date(NaN), month,
        parts = isoExp.exec(dateStringInRange);

    if(parts) {
      month = +parts[2];
      date.setFullYear(parts[1], month - 1, parts[3]);
      if(month != date.getMonth() + 1) {
        date.setTime(NaN);
      }
    }
    return date;
  }
Garrett
quelle
Danke Garrett. Diese Funktion, die Sie im Link bereitgestellt haben, ist die beste, die weitaus präziser ist als alles andere, was ich finden konnte, und sie funktioniert mit dem Datumsformat, das ich über die anderen 99% der App verwende! Viel konsistenter als das, was ich verwendet habe.
Pedalpete
Dies ist leider nicht gut, da viele strukturierte Formate nur W3C-Datums- / Zeitformate verwenden (ISO-8601 mit vollständigen Spezifikationen oder so). Während Zeitstempel in vielerlei Hinsicht besser sind (einfacher, effizienter, mit allen Browsern kompatibel), ist es häufig erforderlich, dass Standarddaten für Datum und Uhrzeit aus Javascript analysiert werden. Ich frage mich, ob jQuery oder dergleichen bessere Analysemethoden hätte.
StaxMan
3
Vielen Dank für den Hinweis, verrückt zu werden, warum Chrome gut funktioniert, um Daten zu analysieren, während ie7 NAN sagt. Gut, dass $ .datepicker.parseDate von jquery Daten analysieren kann
Carlos Jaime C. De Leon
Was ist, wenn Sie auch die Millisekunden wollen?
Okysabeni
Ich habe eine Funktion verwendet, die aus diesem Code abgeleitet wurde, um ein ISO-Datum / eine ISO-Uhrzeit aus einer Zeichenfolge zu analysieren. In seltenen Fällen wird ein scheinbar gültiger Wert in die if (month != date.getMonth() + 1)Anweisung eingegeben , wodurch das Datum ungültig wird. Zum Beispiel 2014-06-01T01:09:22.68. Können Sie den Zweck dieser ifAussage erklären ?
Grinn
87

Aus einem MySQL-Datums- / Zeitstempelformat:

var dateStr="2011-08-03 09:15:11"; //returned from mysql timestamp/datetime field
var a=dateStr.split(" ");
var d=a[0].split("-");
var t=a[1].split(":");
var date = new Date(d[0],(d[1]-1),d[2],t[0],t[1],t[2]);

Ich hoffe, es ist nützlich für jemanden. Funktioniert in IE FF Chrome

Qlimax
quelle
Funktioniert mit allen Browsern. Danke
Tejas
1
const a = dateStr.split(' '); const d = a[0].split('-'); const t = a[1].split(':'); currentValue.created_date = new Date(+d[0], (+d[1] - 1), +d[2], +t[0], +t[1]);für ES5 oder besser.
Sydwell
15

Verwenden Sie nicht "new Date ()", da die eingegebene Datumszeichenfolge als Ortszeit verwendet wird:

new Date('11/08/2010').getTime()-new Date('11/07/2010').getTime();  //90000000
new Date('11/07/2010').getTime()-new Date('11/06/2010').getTime();  //86400000

wir sollten "NewDate ()" verwenden, es nimmt die Eingabe als GMT-Zeit:

function NewDate(str)
         {str=str.split('-');
          var date=new Date();
          date.setUTCFullYear(str[0], str[1]-1, str[2]);
          date.setUTCHours(0, 0, 0, 0);
          return date;
         }
NewDate('2010-11-07').toGMTString();
NewDate('2010-11-08').toGMTString();
DIYismus
quelle
7

Hier ist ein weiterer Ansatz, der dem DateObjekt eine Methode hinzufügt

Verwendung: var d = (new Date()).parseISO8601("1971-12-15");

    / **
     * Analysiert das nach ISO 8601 formatierte Datum in ein Datumsobjekt. ISO 8601 lautet JJJJ-MM-TT
     * * 
     * @param {String} datiert das Datum als String, zB 1971-12-15
     * @returns {Date} Datumsobjekt, das das Datum der angegebenen Zeichenfolge darstellt
     * /
    Date.prototype.parseISO8601 = Funktion (Datum) {
        var match = date.match (/ ^ \ s * (\ d {4}) - (\ d {2}) - (\ d {2}) \ s * $ /);

        if (entspricht) {
            this.setFullYear (parseInt (entspricht [1]));    
            this.setMonth (parseInt (entspricht [2]) - 1);    
            this.setDate (parseInt (entspricht [3]));    
        }}

        gib das zurück;
    };
magikMaker
quelle
2

Ich speichere mein Datum immer in UTC-Zeit.

Dies ist meine eigene Funktion, die aus den verschiedenen Funktionen besteht, die ich auf dieser Seite gefunden habe.

Es wird ein STRING als MySQL-DATETIME-Format verwendet (Beispiel: 2013-06-15 15:21:41). Die Überprüfung mit dem regulären Ausdruck ist optional. Sie können diesen Teil löschen, um die Leistung zu verbessern.

Diese Funktion gibt einen Zeitstempel zurück.

Die DATETIME wird als UTC-Datum betrachtet . Seien Sie vorsichtig: Wenn Sie eine lokale Datums- / Uhrzeitangabe erwarten, ist diese Funktion nicht für Sie geeignet.

    function datetimeToTimestamp(datetime)
    {
        var regDatetime = /^[0-9]{4}-(?:[0]?[0-9]{1}|10|11|12)-(?:[012]?[0-9]{1}|30|31)(?: (?:[01]?[0-9]{1}|20|21|22|23)(?::[0-5]?[0-9]{1})?(?::[0-5]?[0-9]{1})?)?$/;
        if(regDatetime.test(datetime) === false)
            throw("Wrong format for the param. `Y-m-d H:i:s` expected.");

        var a=datetime.split(" ");
        var d=a[0].split("-");
        var t=a[1].split(":");

        var date = new Date();
        date.setUTCFullYear(d[0],(d[1]-1),d[2]);
        date.setUTCHours(t[0],t[1],t[2], 0);

        return date.getTime();
    }
Gabriel
quelle
2

Hier ist ein Code-Snippet, das das Verhalten des IE behebt (v ['Datum'] ist eine durch Kommas getrennte Datumszeichenfolge, z. B. "2010,4,1"):

if($.browser.msie){
    $.lst = v['date'].split(',');
    $.tmp = new Date(parseInt($.lst[0]),parseInt($.lst[1])-1,parseInt($.lst[2]));
} else {
    $.tmp = new Date(v['date']);
}

Der vorherige Ansatz berücksichtigte nicht, dass der JS-Datumsmonat NULL-basiert ist ...

Es tut mir leid, dass ich nicht zu viel erklärt habe. Ich bin auf der Arbeit und dachte nur, das könnte helfen.

Martin Zeitler
quelle
1

Hier ist mein Ansatz:

var parseDate = function(dateArg) {
    var dateValues = dateArg.split('-');
    var date = new Date(dateValues[0],dateValues[1],dateValues[2]);
    return date.format("m/d/Y");
}

Ersetzen Sie ihn ('-')durch das von Ihnen verwendete Delimeter.

xin
quelle
1

Senden Sie den Datumstext und das Format, in dem Sie den Datentext senden, wie folgt. Es wird analysiert und als Datum zurückgegeben, und dies ist unabhängig vom Browser.

function cal_parse_internal(val, format) {
val = val + "";
format = format + "";
var i_val = 0;
var i_format = 0;
var x, y;
var now = new Date(dbSysCurrentDate);
var year = now.getYear();
var month = now.getMonth() + 1;
var date = now.getDate();

while (i_format < format.length) {
    // Get next token from format string
    var c = format.charAt(i_format);
    var token = "";
    while ((format.charAt(i_format) == c) && (i_format < format.length)) {
        token += format.charAt(i_format++);
    }
    // Extract contents of value based on format token
    if (token == "yyyy" || token == "yy" || token == "y") {
        if (token == "yyyy") { x = 4; y = 4; }
        if (token == "yy")   { x = 2; y = 2; }
        if (token == "y")    { x = 2; y = 4; }
        year = _getInt(val, i_val, x, y);
        if (year == null) { return 0; }
        i_val += year.length;
        if (year.length == 2) {
            if (year > 70) {
                year = 1900 + (year - 0);
            } else {
                year = 2000 + (year - 0);
            }
        }
    } else if (token == "MMMM") {
        month = 0;
        for (var i = 0; i < MONTHS_LONG.length; i++) {
            var month_name = MONTHS_LONG[i];
            if (val.substring(i_val, i_val + month_name.length) == month_name) {
                month = i + 1;
                i_val += month_name.length;
                break;
            }
        }
        if (month < 1 || month > 12) { return 0; }
    } else if (token == "MMM") {
        month = 0;
        for (var i = 0; i < MONTHS_SHORT.length; i++) {
            var month_name = MONTHS_SHORT[i];
            if (val.substring(i_val, i_val + month_name.length) == month_name) {
                month = i + 1;
                i_val += month_name.length;
                break;
            }
        }
        if (month < 1 || month > 12) { return 0; }
    } else if (token == "MM" || token == "M") {     
        month = _getInt(val, i_val, token.length, 2);
        if (month == null || month < 1 || month > 12) { return 0; }
        i_val += month.length;
    } else if (token == "dd" || token == "d") {
        date = _getInt(val, i_val, token.length, 2);
        if (date == null || date < 1 || date > 31) { return 0; }
        i_val += date.length;
    } else {
        if (val.substring(i_val, i_val+token.length) != token) {return 0;}
        else {i_val += token.length;}
    }
}

// If there are any trailing characters left in the value, it doesn't match
if (i_val != val.length) { return 0; }

// Is date valid for month?
if (month == 2) {
    // Check for leap year
    if ((year%4 == 0 && year%100 != 0) || (year%400 == 0)) { // leap year
        if (date > 29) { return false; }
    } else {
        if (date > 28) { return false; }
    }
}
if (month == 4 || month == 6 || month == 9 || month == 11) {
    if (date > 30) { return false; }
}
return new Date(year, month - 1, date);
}
valli
quelle
Danke Valli. Ich ging mit Garretts Antwort unten, da die Funktion, mit der er verknüpft war, kleiner war, und arbeitete mit dem Datumsformat, das ich regelmäßig verwende.
Pedalpete
0

Der Datumskonstruktor in JavaScript benötigt eine Zeichenfolge in einem der von der parse () -Methode unterstützten Datumsformate.

Anscheinend wird das von Ihnen angegebene Format im IE nicht unterstützt, daher müssen Sie entweder den PHP-Code ändern oder die Zeichenfolge manuell in JavaScript analysieren.

richardtallent
quelle
4
Das ist ziemlich offensichtlich, aber es wäre gut zu wissen, welche unterstützten Formate sein könnten ...
StaxMan
0

Sie können den folgenden Code verwenden, um die ISO8601-Datumszeichenfolge zu analysieren:

function parseISO8601(d) {
    var timestamp = d;
    if (typeof (d) !== 'number') {
        timestamp = Date.parse(d);
    }
    return new Date(timestamp);
};
isaranchuk
quelle
0

Probieren Sie die getDateFunktion von aus datepicker.

$.datepicker.formatDate('yy-mm-dd',new Date(pField.datepicker("getDate")));
Devika Anup
quelle
0

Ich habe alle oben genannten Lösungen ausprobiert, aber nichts hat bei mir funktioniert. Ich habe ein Brainstorming durchgeführt und dies gefunden und auch in IE11 gut funktioniert.

value="2020-08-10 05:22:44.0";
var date=new Date(value.replace(" ","T")).$format("d/m/yy h:i:s");
console.log(date);

Wenn das $ -Format für Sie nicht funktioniert, verwenden Sie nur das Format.

PRAFUL KUMAR
quelle