getFullYear regresa el año anterior al primer día del año

Estoy tratando de sacar solo el año de una fecha, pero por alguna razón, el primer día del año está regresando el año anterior.

new Date('2012-01-01').getFullYear() 

devolverá ‘2011’ y

 new Date('2012-01-02').getFullYear() 

volverá ‘2012’

¿Alguna buena idea sobre lo que estoy haciendo mal? o una solución para esto sería útil.

new Date('2012-01-01') analizará la fecha asumiendo que está en UTC. El objeto Date creado incorpora su zona horaria, por lo que lo tendrá en cuenta al imprimir el resultado de getYear() . Si estás en GMT, cualquier cosa, eso significa que volverás al año anterior. Puede ignorar las zonas horarias y tratar solo con UTC llamando a Date.prototype.getUTCFullYear() .

new Date(dateString) devolverá la hora que fue en Greewich England en ese momento. Puedes hacer esto si quieres el año que buscas:

 new Date('2012-01-01T00:00:00').getFullYear(); 

Tal vez te guste esto:

 function dateFromString(dateString){ return new Date(dateString+'T00:00:00'); } console.log(dateFromString('2012-01-01').getFullYear()); 

Como han dicho otros, su problema es que el host está analizando ‘2012-01-01’ como si estuviera en GMT y la hora es 00:00:00. Sin embargo, su sistema está configurado para una zona horaria que se encuentra al oeste de Greenwich y se tiene en cuenta al obtener el año de la fecha, de modo que obtenga una fecha para el 31 de diciembre del año anterior.

Una regla fundamental es nunca analizar cadenas utilizando el constructor Date (o Date.parse, que hace lo mismo), ya que depende en gran medida de la implementación y es inconsistente. Una fecha ISO 8601 sin una zona horaria debe tratarse como local según ISO. Sin embargo, en ECMAScript ed 3 podría tratarse como algo (IE hasta la versión 8 incluida, incluso la versión 8, no la analizó en absoluto). Entonces ES5 dijo que lo trataran como UTC (en conflicto con ISO). Luego, ECMAScript 2015 pareció inferir que lo trataba como local, lo que los navegadores comenzaron a hacer, pero luego TC39 dijo que lo tratara como UTC, que es lo que hacen los navegadores más modernos (pero todavía hay muchos navegadores antiguos que no lo hacen).

Entonces, si desea consistencia, analice las cadenas de fecha manualmente, por ejemplo, para tratar una fecha ISO 8601 como local, use una función como:

 /* Parse ISO 8601 date string without time zone ** as a local date ** @param {string} s - date string to parse in format yyyy-mm-dd ** @returns {Date} - local Date, or invalid date if any value is ** out of range */ function parseISOLocal(s) { var b = s.split(/\D/); var d = new Date(b[0], --b[1], b[2]); return d && d.getMonth() == b[1]? d : new Date(NaN); } var s = '2012-01-01'; document.write(parseISOLocal(s))