2015-04-30 3 views
37

Я хочу создать объект Date в javascript, который представляет год 0001, 2014 года назад.Javascript date 01/01/0001

Я попытался с

d = new Date(); d.setYear(1); 
console.log(d); 

, но это дает 1901

год с

d = new Date(1,1,1) 
console.log(d); 

нет пути.

Как я могу создать эту дату?

ответ

35

Прежде всего, это не Y2K проблема вообще! (UPDATE: в некоторых случаях - это связано с Y2K проблем, но это не проблема здесь)

Правильный ответ в том, что вы не можете сделать это надежно. Является ли летнее время применимым к году 1? Сколько високосных лет было? Были ли они? И т. Д. Но ответ от @ Даниэль будет использовать его!

ОБНОВЛЕНИЕ: не говоря уже о сообщении @MattJohnson о DST. DST in year 1, actually JS (ES5 anyway) will lie and use the current DST rule for all years

Поэтому, пожалуйста, не обманывайте себя с идеей, что вы можете надежно работать с датами ниже 1970. (У вас будет много проблем и сюрпризов даже в этом диапазоне времени.)

Но если вы на самом деле, действительно нужно вы можете использовать new Date('0001-01-01') (формат ISO 8601) или @ метод Даниила:

var d = new Date(); d.setFullYear(1); 

Но прежде чем использовать его прочитать ...


Есть 4 способа создания даты в JS:

new Date() 
new Date(milliseconds) 
new Date(dateString) 
new Date(year, month, day, hours, minutes, seconds, milliseconds) 

1) новая Дата() создает текущую дату (в локальном часовом поясе), поэтому мы не заинтересованы в нем сейчас.


2) новая дата (число) создает новый объект даты, как нулевое время плюс число. Нулевое время 01 января 1970 00:00:00 UTC.

Так что в этом случае время в JS рассчитывается с 1970 года.

(new Date(0)).toUTCString() 
"Thu, 01 Jan 1970 00:00:00 GMT 

Если вы используете отрицательное число вы можете перейти «назад» это время до 1970

(new Date(-62167219200000)).toUTCString() 
"Sat, 01 Jan 0 00:00:00 GMT" 
-62167219200000    <- milliseconds 
-62167219200000/1000 
-62167219200    <- seconds 
-62167219200/60 
-1036120320    <- minutes 
-1036120320/60 
-17268672    <- hours 
-17268672/24 
-719528    <- days 
-719528/365 
-1971.309589041096 <- years (this is roughly calculated value) 

Проблема заключается в том, что это не является надежным. Сколько високосных лет было? Были ли они? Летнее время? И т.д. И мне не нравится это из-за этого магического числа -62167219200000


3) новые Дата (DateString) Это наиболее «надежный» способ. DateString - строка, представляющая дату RFC2822 или ISO 8601.

RFC2822/Синтаксис даты IETF (RFC2822, раздел 3.3), например. «Пн, 25 декабря 1995 13:30:00 GMT»

Проблема с ним в том, что если вы используете отрицательное число вы получите неверную Свидание с NaN в результате всех методов

(new Date('01 January -1 00:00:00 UTC')).getFullYear() 
NaN 

Если вы используете год более высокий или равный 0 и ниже 50, затем 2000 будет добавлен автоматически.

(new Date('01 January 0 00:00:00 UTC')).getFullYear() 
2000 
(new Date('01 January 1 00:00:00 UTC')).getFullYear() 
2001 
(new Date('01 January 10 00:00:00 UTC')).getFullYear() 
2010 
(new Date('01 January 01 00:00:00 UTC')).getFullYear() 
2001 
(new Date('01 January 30 00:00:00 UTC')).getFullYear() 
2030 
(new Date('01 January 49 00:00:00 UTC')).getFullYear() 
2049 

И если вы используете год выше или равный 50 и ниже 100, тогда будет добавлено 1900 единиц.

(new Date('01 January 50 00:00:00 UTC')).getFullYear() 
1950 
(new Date('01 January 51 00:00:00 UTC')).getFullYear() 
1951 
(new Date('01 January 90 00:00:00 UTC')).getFullYear() 
1990 
(new Date('01 January 99 00:00:00 UTC')).getFullYear() 
1999 

лет равны 100 или выше, получит правильный год число

(new Date('01 January 100 00:00:00 UTC')).getFullYear() 
100 
(new Date('01 January 101 00:00:00 UTC')).getFullYear() 
101 
(new Date('01 January 999 00:00:00 UTC')).getFullYear() 
999 
(new Date('01 January 9999 00:00:00 UTC')).getFullYear() 
9999 

Таким образом, мы не можем создать 1 год, используя RFC2822/IETF синтаксис даты

О ISO 8601:

http://www.w3.org/TR/NOTE-datetime

Фактические форматы

Year: 
     YYYY (eg 1997) 
Year and month: 
     YYYY-MM (eg 1997-07) 
Complete date: 
     YYYY-MM-DD (eg 1997-07-16) 
Complete date plus hours and minutes: 
     YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00) 
Complete date plus hours, minutes and seconds: 
     YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00) 
Complete date plus hours, minutes, seconds and a decimal fraction of a second 
     YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00) 

Мы очень заинтересованы в 'Полная дата'

(new Date('0001-01-01')).toUTCString() 
"Mon, 01 Jan 1 00:00:00 GMT" 

Yahoo !!! (или лучше сказать Google! :)), мы можем использовать ISO 8601 для создания даты с годом 1

Но будьте осторожны и не пытайтесь использовать отрицательные числа или короткие цифры года, так как синтаксический анализ этих будет может варьироваться в зависимости от локализации или просто маразм :)

(new Date('-0001-01-01')).toUTCString() 
"Sun, 31 Dec 2000 21:00:00 GMT" 
(new Date('01-01-01')).toUTCString() 
"Sun, 31 Dec 2000 21:00:00 GMT" 
(new Date('02-01-01')).toUTCString() 
"Wed, 31 Jan 2001 21:00:00 GMT" 
(new Date('02-01-05')).toUTCString() 
"Mon, 31 Jan 2005 21:00:00 GMT" 

4) новые Дата (год, месяц, день, часы, минуты, секунды, миллисекунды)

Чтобы использовать это у вас есть для передачи двух параметров (год и месяц), все остальные будут необязательными. Будьте осторожны, потому что здесь месяц начнется с 0 до 11, а не везде. WAT? o_O

ВНИМАНИЕ! Эта дата будет создана в вашем текущем часовом поясе !!! Поэтому будьте осторожны!

UPD: Разъяснение @ матово-Джонсон

... на самом деле объект Даты всегда отражает местный часовой пояс. Вы не можете поместить его в другой часовой пояс, и даже если вы инициализируете его временной меткой UTC, он по-прежнему будет отражать местный часовой пояс в большинстве функций. Внутри он отслеживает UTC числовой меткой времени, и есть функции, которые явно отображают значения UTC, но все остальное является локальным.

отрицательные числа будут интерпретироваться как отрицательные лет

(new Date(-1, 0)).toString() 
"Fri Jan 01 -1 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 
(new Date(-234, 0)).toString() 
"Wed Jan 01 -234 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 

числа от 0 до 99 будет увеличен на 1900 автоматически

(new Date(0, 0)).toString() 
"Mon Jan 01 1900 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 
(new Date(1, 0)).toString() 
"Tue Jan 01 1901 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 
(new Date(11, 0)).toString() 
"Sun Jan 01 1911 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 
(new Date(50, 0)).toString() 
"Sun Jan 01 1950 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 
(new Date(99, 0)).toString() 
"Fri Jan 01 1999 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 

Числа от 100 до 275760 будет интерпретироваться в качестве цифр года

(new Date(100, 0)).toString() 
"Fri Jan 01 100 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 
(new Date(102, 0)).toString() 
"Sun Jan 01 102 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 
(new Date(2002, 0)).toString() 
"Tue Jan 01 2002 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 

И цифры выше, то 275760 будет Неверная дата

(new Date(275760, 0)).toString() 
"Tue Jan 01 275760 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)" 
(new Date(275761, 0)).toString() 
"Invalid Date" 

UPD:

новые Дата (Date.UTC (1,1,1)) будет безопаснее от тех же симптомов, как новый Дата (год, месяц, день, часы, минуты, секунды, миллисекунды). Из-за функции Date.UTC.

+0

Когда я пытаюсь получить даты UTC, я склонен использовать новую Date (Date.UTC (1,1,1)) в отличие от синтаксического анализа строк. Имейте в виду, я никогда не пробовал это с ранней даты раньше. –

+1

новая дата (Date.UTC (1,1,1)) будет более безопасной от тех же симптомов, что и новая дата (год, месяц, день, часы, минуты, секунды, миллисекунды). Функция Date.UTC ... –

+0

Это связано с y2k, потому что функции setYear и constructor были изначально предназначены для принятия двузначного (или однозначного для 0-9) года и все еще делают это с годами в диапазон 0-99 для обратной совместимости. – Random832

36

Использование setFullYear - это проблема Y2K с JavaScript.

var d = new Date(); d.setFullYear(1); 
 
document.write(d);

+9

Как ретро :) Создал «document.write» для ностальгических целей! – CodingIntrigue

+0

@RGramham im просто делает это для снайперов. –

+1

Я знаю, просто подумал, что это подходит для * вопроса Y2K * – CodingIntrigue

1

при работе с объектами JavaScript даты вы должны указать полный год для бывшего, 1950, а не 50. Это упоминается в док. Таким образом, код должен быть Даниил сказал также,

d = new Date(); d.setFullYear(1); 
console.log(d); 
+3

um числовой литерал '0001' является восьмеричным для' 1' –

+6

Значения '1' и' 0001' ** идентичны **. – Pointy

+0

А, должно быть, это я отредактировал. – javabot

1

The (устаревшее) Date.setYear метод устанавливает год для определенной даты, но учтите, что:

Если yearValue это число от 0 до 99 (включительно), то год для dateObj установлен в 1900 + год. В противном случае, год для dateObj установлен на yearValue.

var theBigDay = new Date(); 

theBigDay.setYear(96); // sets year to 1996 
theBigDay.setYear(1996); // sets year to 1996 
theBigDay.setYear(2000); // sets year to 2000 

Вы должны использовать Date.setFullYear метод тем не менее. Другой метод устарел.