2010-02-02 10 views
70

Estoy intentando crear un pequeño calendario en JavaScript. Tengo mis fechas funcionando bien en Firefox y Chrome, pero en IE las funciones de fecha devuelven NaN.El constructor de fecha devuelve NaN en IE, pero funciona en Firefox y Chrome

Aquí es la función:

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>'); 
} 

dateText es el lunes de la semana en curso que está en realidad situado en php en el formato de 'm, d, Y', por ejemplo, "02, 01, 2010".

+2

usted tiene algunos errores de copiar y pegar en su ejemplo de código, mira a la instrucción for: 'for (var d = 0; d ';' que levantará un 'SyntaxError' ... – CMS

Respuesta

62

El constructor de fecha acepta cualquier valor. Si el [[valor] primitivo] del argumento es número, entonces la Fecha que se crea tiene ese valor. Si [[valor]] primitivo es Cadena, entonces la especificación solo garantiza que el constructor Fecha y el método de análisis sean capaces de analizar el resultado de Date.prototype.toString y Date.prototype.toUTCString()

Una manera confiable establecer una fecha es construir una y usar los métodos setFullYear y setTime.

Un ejemplo de ello aparece aquí: http://jibbering.com/faq/#parseDate

ECMA-262 R3 no define ningún formatos de fecha. Al pasar valores de cadena al constructor Fecha o Date.parse tiene un resultado dependiente de la implementación. Lo mejor es evitarlo.


Editar: La entrada de Preguntas comp.lang.javascript es: Un ISO 8601 extendido formato de fecha local YYYY-MM-DD se puede analizar como un Date con lo siguiente: -

/**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; 
    } 
+0

Gracias Garret. Esa función que proporcionó en el enlace es la mejor mucho más concisa que cualquier otra cosa que he podido encontrar, y funciona con el formato de fecha que uso a través del otro 99% de la aplicación. Mucho más consistente de lo que Yo estaba usando. – pedalpete

+0

Esto es, por desgracia, no es bueno, ya que muchos formatos estructurados simplemente usan W3C fecha/hora forma ts (ISO-8601 con especificaciones completas o más). Por lo tanto, aunque las marcas de tiempo son mejores en muchos aspectos (más simples, más eficientes, funcionan con todos los navegadores), a menudo se requiere que los datos de fecha/hora estándar sean analizadores de javascript. Me pregunto si jQuery u otros tendrían mejores métodos de análisis. – StaxMan

+3

gracias por señalar, volverse loco por qué Chrome funciona bien las fechas de análisis, mientras que ie7 dice NAN, lo bueno $ .datepicker.parseDate de jquery es capaz de analizar las fechas –

0

El constructor de fecha en JavaScript necesita una cadena en uno de los formatos de fecha admitidos por el método parse().

Aparentemente, el formato que está especificando no es compatible con IE, por lo que deberá cambiar el código PHP o analizar la cadena manualmente en JavaScript.

+4

Eso está bastante obvio, pero sería bueno saber qué formatos soportados podrían ser ... – StaxMan

1

Envíe el texto de la fecha y el formato en el que está enviando el texto de la fecha en el siguiente método. Analizará y devolverá como fecha y esto es independiente del navegador.

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); 
} 
+0

Gracias Valli. Fui con la respuesta de Garrett a continuación, ya que la función a la que se vinculaba era más pequeña, y funcionaba con el formato de fecha que utilizo regularmente. – pedalpete

15

Don' t uso "new Date()", ya que lleva la cadena de fecha de entrada como la hora local:

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 

debemos utilizar "NewDate() ", Se necesita la entrada como hora GMT:

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(); 
1

Aquí es mi enfoque:

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

reemplazar ('-') con el delimitador que está utilizando.

2

Aquí hay un fragmento de código que corrige ese comportamiento de IE (v ['fecha'] es una fecha separada por comas, por ej."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']); 
} 

El enfoque anterior no consideró que JS Fecha meses se basa CERO ...

Lo siento por no explicar demasiado, estoy en el trabajo y Solo pensé que esto podría ayudar.

81

De un formato de fecha y hora/fecha y hora mysql:

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]); 

que espero es útil para alguien. Obras en IE FF Chrome

+1

¡Agradable! Gracias por compartir +1 –

+2

Gracias, justo lo que necesitaba. – Pascal

+1

funciona con Internet Explorer 8 – max4ever

7

Aquí hay otro enfoque que añade un método para el objeto Date

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

 
    /** 
    * Parses the ISO 8601 formated date into a date object, ISO 8601 is YYYY-MM-DD 
    * 
    * @param {String} date the date as a string eg 1971-12-15 
    * @returns {Date} Date object representing the date of the supplied string 
    */ 
    Date.prototype.parseISO8601 = function(date){ 
     var matches = date.match(/^\s*(\d{4})-(\d{2})-(\d{2})\s*$/); 

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

     return this; 
    }; 
+0

http://stackoverflow.com/review/suggested-edits/3261141 – Stano

2

siempre guardar mi fecha en hora UTC.

Esta es mi propia función hecha a partir de las diferentes funciones que encontré en esta página.

Se necesita STRING como formato de DATETIME de mysql (ejemplo: 2013-06-15 15:21:41). La verificación con la expresión regular es opcional. Puede eliminar esta parte para mejorar el rendimiento.

Esta función devuelve una marca de tiempo.

DATETIME se considera una fecha UTC. Tenga cuidado: si espera una hora local, esta función no es para usted.

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(); 
    } 
0

Usted puede utilizar el código siguiente para analizar la cadena de fecha ISO8601:

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

probar usando getDate función de datepicker.

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

Por favor, elabore su respuesta lo que quiere explicar. –

Cuestiones relacionadas