Como faço para usar javascript para calcular o dia do ano, de 1 a 366? Por exemplo:
- 3 de janeiro deve ser 3 .
- 1º de fevereiro deve ser 32 .
Como faço para usar javascript para calcular o dia do ano, de 1 a 366? Por exemplo:
Respostas:
Após a edição do OP:
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = now - start;
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
console.log('Day of year: ' + day);
Editar: O código acima falhará quando nowfor uma data entre 26 de março e 29 de outubro e nowa hora for anterior à 1h (por exemplo, 00:59:59). Isso ocorre porque o código não leva em consideração o horário de verão. Você deve compensar por isso:
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
console.log('Day of year: ' + day);
Math.floorconsistentemente me deu um resultado de 1 dia a menos do que o esperado após um determinado dia de abril. Math.ceilfuncionou conforme o esperado, mas vi que é aconselhável que você use em Math.roundvez de qualquer um.
new Date(2014, 0, 1), e não new Date(2014, 0, 0)como aqui. Isso é intencional? Talvez seja isso o que explica estar um dia fora, pois new Date(2014, 0, 0)vai voltar 12/31/2013.
.setUTCHourse Date.UTC()para uma solução mais confiável.
ceilvez de floor, isso lhe dará um sistema de numeração onde 1º de janeiro = 1. Se você quiser 1º de janeiro = 0 (como floorlhe daria), apenas subtraia 1 de seu resultado final.
var diff = now - start + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
Isso funciona em todas as mudanças do horário de verão em todos os países (o "meio-dia" acima não funciona na Austrália):
Date.prototype.isLeapYear = function() {
var year = this.getFullYear();
if((year & 3) != 0) return false;
return ((year % 100) != 0 || (year % 400) == 0);
};
// Get Day of Year
Date.prototype.getDOY = function() {
var dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var mn = this.getMonth();
var dn = this.getDate();
var dayOfYear = dayCount[mn] + dn;
if(mn > 1 && this.isLeapYear()) dayOfYear++;
return dayOfYear;
};
getDay()precisa ser alterado para getDate(). O primeiro retorna o dia da semana (0 = domingo..6 = sábado), não o dia.
Acho muito interessante que ninguém pensou em usar UTC, uma vez que não está sujeito ao DST. Portanto, proponho o seguinte:
function daysIntoYear(date){
return (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) - Date.UTC(date.getFullYear(), 0, 0)) / 24 / 60 / 60 / 1000;
}
Você pode testá-lo com o seguinte:
[new Date(2016,0,1), new Date(2016,1,1), new Date(2016,2,1), new Date(2016,5,1), new Date(2016,11,31)]
.forEach(d =>
console.log(`${d.toLocaleDateString()} is ${daysIntoYear(d)} days into the year`));
Quais resultados para o ano bissexto de 2016 (verificado usando http://www.epochconverter.com/days/2016 ):
1/1/2016 is 1 days into the year
2/1/2016 is 32 days into the year
3/1/2016 is 61 days into the year
6/1/2016 is 153 days into the year
12/31/2016 is 366 days into the year
function doyToDate(doy, year) { return new Date(year, 0, doy); }
new Date(8640000000000000), que ainda é menor que Number.MAX_SAFE_INTEGER. veja esta resposta: stackoverflow.com/a/11526569/18511
Date.prototype.dayOfYear= function(){
var j1= new Date(this);
j1.setMonth(0, 0);
return Math.round((this-j1)/8.64e7);
}
alert(new Date().dayOfYear())
Felizmente esta questão não especifica se o número do dia atual é obrigatório, deixando espaço para esta resposta.
Além disso, algumas respostas (também sobre outras questões) tiveram problemas de ano bissexto ou usaram o objeto Data. Embora o javascript Date objectcubra aproximadamente 285616 anos (100 milhões de dias) em ambos os lados de 1º de janeiro de 1970, eu estava farto de todos os tipos de inconsistências de data inesperadas em navegadores diferentes (principalmente do ano 0 a 99). Eu também estava curioso para saber como calculá-lo.
Então eu escrevi um algoritmo simples e, acima de tudo, pequeno para calcular o dia do ano correto ( Proléptico Gregoriano / Astronômico / ISO 8601: 2004 (cláusula 4.3.2.1), então ano0 existe e é um ano bissexto e anos negativos são suportados ) com base no ano , mês e dia .
Observe que, em AD/BCnotação, o ano 0 AD / BC não existe: em vez disso, o ano 1 BCé o ano bissexto! SE você precisar contabilizar a notação BC, simplesmente subtraia um ano do valor do ano (caso contrário positivo) primeiro !!
Modifiquei (para javascript) o algoritmo bitmask-módulo leapYear de curto-circuito e criei um número mágico para fazer uma pesquisa bit a bit de offsets (que exclui jan e feb, portanto, precisando de 10 * 3 bits (30 bits é menor que 31 bits, para que possamos salvar com segurança outro caractere no bitshift em vez de >>>)).
Observe que nem o mês nem o dia podem ser 0. Isso significa que se você precisa dessa equação apenas para o dia atual (alimentando-a usando .getMonth()), você só precisa remover o --de --m.
Observe que isso pressupõe uma data válida (embora a verificação de erros seja apenas mais alguns caracteres).
function dayNo(y,m,d){
return --m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+d;
}
<!-- some examples for the snippet -->
<input type=text value="(-)Y-M-D" onblur="
var d=this.value.match(/(-?\d+)[^\d]+(\d\d?)[^\d]+(\d\d?)/)||[];
this.nextSibling.innerHTML=' Day: ' + dayNo(+d[1], +d[2], +d[3]);
" /><span></span>
<br><hr><br>
<button onclick="
var d=new Date();
this.nextSibling.innerHTML=dayNo(d.getFullYear(), d.getMonth()+1, d.getDate()) + ' Day(s)';
">get current dayno:</button><span></span>
Aqui está a versão com validação de intervalo correta .
function dayNo(y,m,d){
return --m>=0 && m<12 && d>0 && d<29+(
4*(y=y&3||!(y%25)&&y&15?0:1)+15662003>>m*2&3
) && m*31-(m>1?(1054267675>>m*3-6&7)-y:0)+d;
}
<!-- some examples for the snippet -->
<input type=text value="(-)Y-M-D" onblur="
var d=this.value.match(/(-?\d+)[^\d]+(\d\d?)[^\d]+(\d\d?)/)||[];
this.nextSibling.innerHTML=' Day: ' + dayNo(+d[1], +d[2], +d[3]);
" /><span></span>
Novamente, uma linha, mas eu dividi em 3 linhas para facilitar a leitura (e a explicação seguinte).
A última linha é idêntica à função acima, no entanto, o algoritmo leapYear (idêntico) é movido para uma seção de curto-circuito anterior (antes do cálculo do número do dia), porque também é necessário saber quantos dias um mês tem em um dado ano (bissexto).
A linha do meio calcula o número de deslocamento correto (para o número máximo de dias) para um determinado mês em um determinado ano (bissexto) usando outro número mágico: como 31-28=3e 3tem apenas 2 bits, então 12*2=24bits, podemos armazenar todos os 12 meses. Como a adição pode ser mais rápida do que a subtração, adicionamos o deslocamento (em vez de subtraí-lo 31). Para evitar um ramo de decisão de ano bissexto para fevereiro, modificamos esse número de pesquisa mágico instantaneamente.
Isso nos deixa com a (bastante óbvia) primeira linha: ela verifica se o mês e a data estão dentro dos limites válidos e nos garante um falsevalor de retorno no erro de intervalo (observe que esta função também não deve ser capaz de retornar 0, porque 1 jan 0000 ainda é dia 1.), proporcionando fácil verificação de erros: if(r=dayNo(/*y, m, d*/)){}.
Se usado desta forma (onde mês e dia podem não ser 0), então um pode mudar --m>=0 && m<12para m>0 && --m<12(salvando outro caractere).
O motivo pelo qual digitei o snippet em sua forma atual é que para valores de mês baseados em 0, basta remover o --de --m.
Extra:
Nota, não use este algoritmo de dias por mês se você precisa apenas de no máximo dias por mês. Nesse caso existe um algoritmo mais eficiente (porque só precisamos do leepYear quando o mês é fevereiro). Postei como resposta a esta pergunta: Qual é a melhor forma de determinar o número de dias de um mês com javascript? .
Date.prototype.dayNo = function(){ var y = this.getFullYear(); var m = this.getMonth()+1; var d = this.getDate(); return --m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+d; };
+1de this.getMonth()+1se remover a --partir --m. EDITAR Então, eu faria (para uma biblioteca):Date.prototype.dayNo = function(){ var y=this.getFullYear(), m=this.getMonth(); return m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+this.getDate(); };
2^31 - 2016anos, o js provavelmente estará um pouco desatualizado.
:)Mas até então, pelo menos dará resultados previsíveis e consistentes haha. EDITAR , apenas por uma questão de teoria, usando o algoritmo de módulo convencional mais lento para ano bissexto, o intervalo pode ser estendido para 2 ^ 53. O algoritmo de pesquisa de mês não é o fator limitante.
Se não quiser reinventar a roda, você pode usar a excelente biblioteca date-fns (node.js):
var getDayOfYear = require('date-fns/get_day_of_year')
var dayOfYear = getDayOfYear(new Date(2017, 1, 1)) // 1st february => 32
Bem, se bem entendi, você quer 366 em um ano bissexto, 365 caso contrário, certo? Um ano é um ano bissexto se for igualmente divisível por 4, mas não por 100, a menos que também seja divisível por 400:
function daysInYear(year) {
if(year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
// Leap year
return 366;
} else {
// Not a leap year
return 365;
}
}
Nesse caso, não acho que haja um método embutido; você precisará fazer isso:
function daysInFebruary(year) {
if(year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
// Leap year
return 29;
} else {
// Not a leap year
return 28;
}
}
function dateToDay(date) {
var feb = daysInFebruary(date.getFullYear());
var aggregateMonths = [0, // January
31, // February
31 + feb, // March
31 + feb + 31, // April
31 + feb + 31 + 30, // May
31 + feb + 31 + 30 + 31, // June
31 + feb + 31 + 30 + 31 + 30, // July
31 + feb + 31 + 30 + 31 + 30 + 31, // August
31 + feb + 31 + 30 + 31 + 30 + 31 + 31, // September
31 + feb + 31 + 30 + 31 + 30 + 31 + 31 + 30, // October
31 + feb + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, // November
31 + feb + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, // December
];
return aggregateMonths[date.getMonth()] + date.getDate();
}
(Sim, na verdade fiz isso sem copiar ou colar. Se houver uma maneira fácil, ficarei bravo)
:)
Esta é uma maneira simples de encontrar o dia atual do ano e deve representar os anos bissextos sem problemas:
Javascript:
Math.round((new Date().setHours(23) - new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0))/1000/60/60/24);
Javascript no Google Apps Script:
Math.round((new Date().setHours(23) - new Date(new Date().getYear(), 0, 1, 0, 0, 0))/1000/60/60/24);
A principal ação desse código é encontrar o número de milissegundos decorridos no ano atual e, em seguida, converter esse número em dias. O número de milissegundos decorridos no ano atual pode ser encontrado subtraindo o número de milissegundos do primeiro segundo do primeiro dia do ano atual, que é obtido com new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0)(Javascript) ounew Date(new Date().getYear(), 0, 1, 0, 0, 0) (Google Apps Script), dos milissegundos da 23ª hora do dia atual, que foi encontrado com new Date().setHours(23). O objetivo de definir a data atual para a 23ª hora é garantir que o dia do ano seja arredondado corretamente por Math.round().
Assim que tiver o número de milissegundos do ano atual, você pode converter esse tempo em dias dividindo por 1000 para converter milissegundos em segundos, depois dividindo por 60 para converter segundos em minutos e dividindo por 60 para converter minutos em horas, e finalmente dividindo por 24 para converter horas em dias.
Observação: esta postagem foi editada para explicar as diferenças entre JavaScript e JavaScript implementado no Google Apps Script. Além disso, mais contexto foi adicionado para a resposta.
.setHoursmétodo no primeiro objeto de data e especifiquei a hora do dia com o segundo objeto de data, uma alteração de 1 hora do horário de verão não afetará os horários dos objetos Date usados neste cálculo.
Acho que é mais simples:
var date365 = 0;
var currentDate = new Date();
var currentYear = currentDate.getFullYear();
var currentMonth = currentDate.getMonth();
var currentDay = currentDate.getDate();
var monthLength = [31,28,31,30,31,30,31,31,30,31,30,31];
var leapYear = new Date(currentYear, 1, 29);
if (leapYear.getDate() == 29) { // If it's a leap year, changes 28 to 29
monthLength[1] = 29;
}
for ( i=0; i < currentMonth; i++ ) {
date365 = date365 + monthLength[i];
}
date365 = date365 + currentDay; // Done!
Este método leva em consideração a questão do fuso horário e o horário de verão
function dayofyear(d) { // d is a Date object
var yn = d.getFullYear();
var mn = d.getMonth();
var dn = d.getDate();
var d1 = new Date(yn,0,1,12,0,0); // noon on Jan. 1
var d2 = new Date(yn,mn,dn,12,0,0); // noon on input date
var ddiff = Math.round((d2-d1)/864e5);
return ddiff+1;
}
(tirado daqui )
Veja também este violino
Math.round ((new Date (). SetHours (23) - new Date (new Date (). GetFullYear (), 0, 1, 0, 0, 0)) / 1000/86400);
otimiza ainda mais a resposta.
Além disso, alterando setHours (23) ou o last-but-two zero posteriormente para outro valor pode fornecer o dia do ano relacionado a outro fuso horário. Por exemplo, para recuperar da Europa um recurso localizado na América.
Math.floor((Date.now() - Date.parse(new Date().getFullYear(), 0, 0)) / 86400000)
esta é a minha solução
Fiz um que é legível e fará o truque muito rapidamente, além de lidar com objetos JS Date com fusos horários diferentes.
Incluí alguns casos de teste para fusos horários, DST, segundos bissextos e anos bissextos.
PS ECMA-262 ignora segundos bissextos, ao contrário do UTC. Se você converter isso para uma linguagem que usa UTC real, poderá apenas adicionar 1 a oneDay.
// returns 1 - 366
findDayOfYear = function (date) {
var oneDay = 1000 * 60 * 60 * 24; // A day in milliseconds
var og = { // Saving original data
ts: date.getTime(),
dom: date.getDate(), // We don't need to save hours/minutes because DST is never at 12am.
month: date.getMonth()
}
date.setDate(1); // Sets Date of the Month to the 1st.
date.setMonth(0); // Months are zero based in JS's Date object
var start_ts = date.getTime(); // New Year's Midnight JS Timestamp
var diff = og.ts - start_ts;
date.setDate(og.dom); // Revert back to original date object
date.setMonth(og.month); // This method does preserve timezone
return Math.round(diff / oneDay) + 1; // Deals with DST globally. Ceil fails in Australia. Floor Fails in US.
}
// Tests
var pre_start_dst = new Date(2016, 2, 12);
var on_start_dst = new Date(2016, 2, 13);
var post_start_dst = new Date(2016, 2, 14);
var pre_end_dst_date = new Date(2016, 10, 5);
var on_end_dst_date = new Date(2016, 10, 6);
var post_end_dst_date = new Date(2016, 10, 7);
var pre_leap_second = new Date(2015, 5, 29);
var on_leap_second = new Date(2015, 5, 30);
var post_leap_second = new Date(2015, 6, 1);
// 2012 was a leap year with a leap second in june 30th
var leap_second_december31_premidnight = new Date(2012, 11, 31, 23, 59, 59, 999);
var january1 = new Date(2016, 0, 1);
var january31 = new Date(2016, 0, 31);
var december31 = new Date(2015, 11, 31);
var leap_december31 = new Date(2016, 11, 31);
alert( ""
+ "\nPre Start DST: " + findDayOfYear(pre_start_dst) + " === 72"
+ "\nOn Start DST: " + findDayOfYear(on_start_dst) + " === 73"
+ "\nPost Start DST: " + findDayOfYear(post_start_dst) + " === 74"
+ "\nPre Leap Second: " + findDayOfYear(pre_leap_second) + " === 180"
+ "\nOn Leap Second: " + findDayOfYear(on_leap_second) + " === 181"
+ "\nPost Leap Second: " + findDayOfYear(post_leap_second) + " === 182"
+ "\nPre End DST: " + findDayOfYear(pre_end_dst_date) + " === 310"
+ "\nOn End DST: " + findDayOfYear(on_end_dst_date) + " === 311"
+ "\nPost End DST: " + findDayOfYear(post_end_dst_date) + " === 312"
+ "\nJanuary 1st: " + findDayOfYear(january1) + " === 1"
+ "\nJanuary 31st: " + findDayOfYear(january31) + " === 31"
+ "\nNormal December 31st: " + findDayOfYear(december31) + " === 365"
+ "\nLeap December 31st: " + findDayOfYear(leap_december31) + " === 366"
+ "\nLast Second of Double Leap: " + findDayOfYear(leap_second_december31_premidnight) + " === 366"
);
Gostaria de fornecer uma solução que faça cálculos somando os dias de cada mês anterior:
function getDayOfYear(date) {
var month = date.getMonth();
var year = date.getFullYear();
var days = date.getDate();
for (var i = 0; i < month; i++) {
days += new Date(year, i+1, 0).getDate();
}
return days;
}
var input = new Date(2017, 7, 5);
console.log(input);
console.log(getDayOfYear(input));
Dessa forma, você não precisa gerenciar os detalhes dos anos bissextos e do horário de verão.
Uma alternativa usando carimbos de data / hora UTC. Além disso, como outros observaram, o dia que indica o primeiro do mês é 1 em vez de 0. No entanto, o mês começa em 0.
var now = Date.now();
var year = new Date().getUTCFullYear();
var year_start = Date.UTC(year, 0, 1);
var day_length_in_ms = 1000*60*60*24;
var day_number = Math.floor((now - year_start)/day_length_in_ms)
console.log("Day of year " + day_number);
Você pode passar o parâmetro como número de data na setDatefunção:
var targetDate = new Date();
targetDate.setDate(1);
// Now we can see the expected date as: Mon Jan 01 2018 01:43:24
console.log(targetDate);
targetDate.setDate(365);
// You can see: Mon Dec 31 2018 01:44:47
console.log(targetDate)
Isso pode ser útil para aqueles que precisam do dia do ano como uma string e têm o jQuery UI disponível.
Você pode usar o jQuery UI Datepicker:
day_of_year_string = $.datepicker.formatDate("o", new Date())
Embaixo funciona da mesma forma que algumas das respostas já mencionadas ( (date_ms - first_date_of_year_ms) / ms_per_day):
function getDayOfTheYearFromDate(d) {
return Math.round((new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime()
- new Date(d.getFullYear(), 0, 0).getTime()) / 86400000);
}
day_of_year_int = getDayOfTheYearFromDate(new Date())
Para aqueles entre nós que desejam uma solução alternativa rápida.
(function(){"use strict";
function daysIntoTheYear(dateInput){
var fullYear = dateInput.getFullYear()|0;
// "Leap Years are any year that can be exactly divided by 4 (2012, 2016, etc)
// except if it can be exactly divided by 100, then it isn't (2100, 2200, etc)
// except if it can be exactly divided by 400, then it is (2000, 2400)"
// (https://www.mathsisfun.com/leap-years.html).
var isLeapYear = ((fullYear & 3) | (fullYear/100 & 3)) === 0 ? 1 : 0;
// (fullYear & 3) = (fullYear % 4), but faster
//Alternative:var isLeapYear=(new Date(currentYear,1,29,12)).getDate()===29?1:0
var fullMonth = dateInput.getMonth()|0;
return ((
// Calculate the day of the year in the Gregorian calendar
// The code below works based upon the facts of signed right shifts
// • (x) >> n: shifts n and fills in the n highest bits with 0s
// • (-x) >> n: shifts n and fills in the n highest bits with 1s
// (This assumes that x is a positive integer)
(31 & ((-fullMonth) >> 4)) + // January // (-11)>>4 = -1
((28 + isLeapYear) & ((1-fullMonth) >> 4)) + // February
(31 & ((2-fullMonth) >> 4)) + // March
(30 & ((3-fullMonth) >> 4)) + // April
(31 & ((4-fullMonth) >> 4)) + // May
(30 & ((5-fullMonth) >> 4)) + // June
(31 & ((6-fullMonth) >> 4)) + // July
(31 & ((7-fullMonth) >> 4)) + // August
(30 & ((8-fullMonth) >> 4)) + // September
(31 & ((9-fullMonth) >> 4)) + // October
(30 & ((10-fullMonth) >> 4)) + // November
// There are no months past December: the year rolls into the next.
// Thus, fullMonth is 0-based, so it will never be 12 in Javascript
(dateInput.getDate()|0) // get day of the month
)&0xffff);
}
// Demonstration:
var date = new Date(2100, 0, 1)
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
console.log(date.getMonth()+":\tday "+daysIntoTheYear(date)+"\t"+date);
date = new Date(1900, 0, 1);
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
console.log(date.getMonth()+":\tday "+daysIntoTheYear(date)+"\t"+date);
// Performance Benchmark:
console.time("Speed of processing 65536 dates");
for (var i=0,month=date.getMonth()|0; i<65536; i=i+1|0)
date.setMonth(month=month+1+(daysIntoTheYear(date)|0)|0);
console.timeEnd("Speed of processing 65536 dates");
})();
O tamanho dos meses do ano e a maneira como os anos bissextos funcionam se encaixam perfeitamente em manter nosso tempo no caminho com o sol. Caramba, funciona tão perfeitamente que tudo o que fazemos é apenas ajustar meros segundos aqui e ali . Nosso sistema atual de anos bissextos está em vigor desde 24 de fevereiro de 1582 e provavelmente permanecerá em vigor no futuro próximo.
O DST, no entanto, está muito sujeito a alterações. Pode ser que, daqui a 20 anos, algum país possa compensar o tempo em um dia inteiro ou algum outro extremo para o DST. Um dia inteiro de horário de verão quase certamente nunca acontecerá, mas o horário de verão ainda está muito no ar e indeciso. Portanto, a solução acima é à prova de futuro, além de ser muito rápida.
O trecho de código acima é executado muito rápido. Meu computador pode processar 65536 datas em ~ 52ms no Chrome.
const dayOfYear = date => {
const myDate = new Date(date);
const year = myDate.getFullYear();
const firstJan = new Date(year, 0, 1);
const differenceInMillieSeconds = myDate - firstJan;
return (differenceInMillieSeconds / (1000 * 60 * 60 * 24) + 1);
};
const result = dayOfYear("2019-2-01");
console.log(result);
Esta é uma solução que evita os problemas de objeto Date e fuso horário, requer que a data de entrada esteja no formato "aaaa-dd-mm". Se você quiser alterar o formato, modifique a função date_str_to_parts:
function get_day_of_year(str_date){
var date_parts = date_str_to_parts(str_date);
var is_leap = (date_parts.year%4)==0;
var acct_for_leap = (is_leap && date_parts.month>2);
var day_of_year = 0;
var ary_months = [
0,
31, //jan
28, //feb(non leap)
31, //march
30, //april
31, //may
30, //june
31, //july
31, //aug
30, //sep
31, //oct
30, //nov
31 //dec
];
for(var i=1; i < date_parts.month; i++){
day_of_year += ary_months[i];
}
day_of_year += date_parts.date;
if( acct_for_leap ) day_of_year+=1;
return day_of_year;
}
function date_str_to_parts(str_date){
return {
"year":parseInt(str_date.substr(0,4),10),
"month":parseInt(str_date.substr(5,2),10),
"date":parseInt(str_date.substr(8,2),10)
}
}
Sempre fico preocupado quando misturo matemática com funções de data (é tão fácil perder algum outro detalhe do ano bissexto). Diga que você tem:
var d = new Date();
Eu sugeriria usar o seguinte, os dias serão salvos em day:
for(var day = d.getDate(); d.getMonth(); day += d.getDate())
d.setDate(0);
Não consigo ver nenhuma razão para que isso não funcione bem (e eu não ficaria tão preocupado com as poucas iterações, já que isso não será usado tão intensamente).
/ * USE ESTE SCRIPT * /
var today = new Date();
var first = new Date(today.getFullYear(), 0, 1);
var theDay = Math.round(((today - first) / 1000 / 60 / 60 / 24) + .5, 0);
alert("Today is the " + theDay + (theDay == 1 ? "st" : (theDay == 2 ? "nd" : (theDay == 3 ? "rd" : "th"))) + " day of the year");
var days = new Date().getFullYear() % 4 == 0 ? 366 : 365;