Javascript – Último dia do mês
by Luiz Paulo | novembro 14, 2008 | 15 Comments »Essa semana, eu precisei de uma solução em Javascript para encontrar o "último dia do mês" ou "quantidade de dias do mês" como preferir. Consultei o Google e encontrei algumas soluções, algumas delas mais simples e outras bem criativas.
Achei o assunto interessante e resolvi divulgar aqui para quem precisar utilizar.
Primeiro vou postar as soluções sérias para o pessoal que está pesquisando e precisa utilizar em seu código
Soluções simples
Exemplo longo (função):
function daysInMonth(month,year) { var m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (month != 2) return m[month - 1]; if (year % 4 != 0) return m[1]; if (year % 100 == 0 && year%400 != 0) return m[1]; return m[1] + 1; }
Exemplo curto (função):
Aqui está a grande sacada do javaScript, que interpreta o 0(zero) como "o dia antes do dia primeiro" que obviamente é o último dia do mês anterior.
function daysInMonth(month,year) { var dd = new Date(year, month, 0); return dd.getDate(); }
Exemplo curto (inline):
var lastDay = (new Date(year, month, 0)).getDate();
Soluções criativas
Não se assustem, mas as soluções citadas abaixo funcionam!
Solução utilizando Switch:
function getLastDayOfMonth(month,year) { var day; switch(month) { case 1 : case 3 : case 5 : case 7 : case 8 : case 10: case 12: day = 31; break; case 4 : case 6 : case 9 : case 11: day = 30; break; case 2 : if( ( (year % 4 == 0) && ( year % 100 != 0) ) || (year % 400 == 0) ) day = 29; else day = 28; break; } return day; }
Essa é legal
function anoBissexto(anoCompleto) { if(!(anoCompleto%4) && (anoCompleto%100 || !(anoCompleto%400))) return true; return false; } function diasNoMes(mes,ano) { var var_type=typeof mes; if(var_type != "number" && var_type != "string") return false; if(var_type == "number" && (mes > 11 || mes < 0) && !isInt(mes)) return false; var eng_args_allowed = "january-february-march-april-may-june-july-august-september-october-november-december"; var bra_args_allowed = "janeiro-fevereiro-marçomarco-abril-maio-junho-julho-agosto-setembro-outubro-novembro-dezembro"; var vet_eng_args_allowed = eng_args_allowed.split("-"); var vet_bra_args_allowed = bra_args_allowed.split("-"); var datahj = new Date(); var anohj = datahj.getFullYear(); var dias = [31,anoBissexto(ano)?29:28,31,30,31,30,31,31,30,31,30,31]; if(var_type == "string") { indice_eng = keyPosMatch(vet_eng_args_allowed,mes); indice_bra = keyPosMatch(vet_bra_args_allowed,mes); if(indice_eng>=0) return dias[indice_eng]; if(indice_bra>=0) return dias[indice_bra]; return false; } else return dias[mes]; }
Façam bom proveito!
Posts Relacionados
Categorias: Desenvolvimento web, JavaScript, Linguagens
Tags: , calendar, code, date, example, javascript








15 Comentários
Eu acho simplesmente incrível a capacidade que as pessoas têm de complicar o que é simples. =)
Muito bom artigo!
[]'s
Cacilhas
É verdade, a mente humana é muito criativa... Muito bom o post LP!
Estava eu pensando, será que isso rola em Java?
Então temos:
>> System.out.println(new SimpleDateFormat("dd").format(new Date(2008,2,0)));
ou ainda uma mais fácil:
>> System.out.println(new GregorianCalendar(2008,2,0).get(Calendar.DAY_OF_MONTH));
Infelizmente a versão intuitiva não funciona e já é 'deprecated' a muito tempo...
>> System.out.println(new Date(2008,2,0).getDay()); //Não funciona!
Valeu,
Zappala.
Boooa Zappala, ótimo exemplo!
Falando em código compacto, nesse caso, JAVA não fica atrás.
Agora, como se faz isso em C, Ruby, Pyton, Lua, etc?
Você sabe alguma solução compacta para alguma dessas liguagens? Posta pra gente conhecer
[]'s
Em Python temos a função
monthrange()do módulo calendar:Em Lua é preciso usar o módulo
ospara calcular. Então podemos criar uma função para calcular isso:Em C++, a Boost oferece a função
end_of_month()no cabeçalho:date_time/gregorian/greg_date.hppEm Objective-C deve haver alguma forma mais simples, mas uma forma é usando a classe
NSDate.Criei uma função para resolver isso:
Em C e em Ruby vou ficar devendo.
[]'s
Cacilhas, La Batalema
Ai Luiz em rails como se trabalha com data:
Ja me deu Dia mes Ano
Agora mais umas brincadeirinhas
Tem umas paradas que acho muito maneiras tipo
Tem muitas coisas prontas mas tudo isso em Rails em Ruby não parei para ver como é não, mas não deve ser dificil. Ruim de trabalhar com data é no Python, eu não gosto como ele trabalha acho complicado.
Cada linguagem e FrameWork tem suas vantagens e suas desvantagens as vezes vale dar uma olhada no codigo de outra linguagem e adpatar. (marreta)
Abraços
Ah! Esqueci de Smalltalk!
A ideia aqui é similar à de Lua: primeiro agente pega o primeiro dia do próximo mês (
mé o mês,yé o ano):Então calcula a data e volta um dia:
O último dia do mês desejado então pode ser obtido com:
[]'s
Cacilhas, La Batalema
Muito bom!
@valdineisantos Boas respostas
Gostei da forma com que o Ruby trara data. Bem simples essas propriedades de número "3.day | 3.month".
@cacilhas Cara você é foda! Pessoal postando suas humildes opiniões e vc vem com SmallTalk.
"Só para tirar onda, heheheh"
[]'s
O que acho complicado de se lidar em Python com data é ter muitos módulos para essa finalidade.
Módulos diferentes fazendo coisas diferentes e também coisas iguais.
Mas no mais, não vejo complicação. Talvez não seja tão simples quanto Ruby, mas a implementação interna é mais bem acabada.
Deixe-me reproduzir os exemplos de Ruby em Python:
Primeiro importe o seguinte:
Último dia do mês:
Convertido em string:
Amanhã:
Ontem:
Para o formato Unix realmente não sei como converter um
date, porque estou enferrujado em Python. Vou substituir pelo formato C, depois quando eu encontrar como converter para o formato Unix eu comento aqui:Para as brincadeira com data, é preciso um
datetime:Ou seja, apesar das diferenças, lidar com data em Python não é tão complicado quanto parece à primeira vista.
Para terminar, o L.P. achou que ficou confuso em Smalltalk, então vou escrever aqui tudo em uma tacada só:
[]'s
Cacilhas, La Batalema
Muito bom os exemplos @cacilhas tive que fazer a adição de dias em datas com python usei o timedelta e funcionou perfeitamente (embora eu continue não gostando).
Cada linguagem com suas bizarrices. Achei os exemplos maneiros e bem instrutivos, pode contar que terá muitos acessos quando o google indexar pois data geralmente é uma questão muito procurada e com esse vasto numero de exemplo o visitantes vão chegar ao montes
Vou tentar fazer em Shell Script para praticar.
Alguém poderia fazer em Windows linha de comando, VB, ASP.NET e afins (post infinito a vista).
Duas coisinhas:
1) Acho que errei no Smalltalk: não lembro bem, mas acho que
!!é usado para encerrar classe. Para encerrar método então é!.2) Faltou Common Lisp!
[]'s
Cacilhas, La Batalema
Na verdade é possível fazer sem o form
let:O form
multiple-value-bindjá resolve o que oletpretendia.Nisso que dá ficar enferrujado!
[]'s
Cacilhas. La Batalema
em fortran possuem algumas funcoes Intrinsicas
program Hora_e_data
interger ,parameter:: n = 3
interger :: data(n),horaSys(n)
call idate(data)
! data(1)=dia, data(2)=mes data(3)=ano
call itime(horaSys)
! horaSys(1)=hora, horaSys(2)=minute,horaSys(3)=second
write(*,'('Date ', i2.2, '/', i2.2, '/', i4.4, '; time ',i2.2, ':', i2.2, ':', i2.2)')data(2), data(1), data(3), now
endprogram
Ola amigos!
@Valdinei, você falou sobre algumas linguagens para MS. Tanto o ASP.NET quanto o VB usam os recursos de data direto do sistema, e caso você saber de alguma data é feito com calculo. Da uma olhada em um codigo para calcular quando será o proximo carnaval.
###############
Public Function pascoa(pano As String)
Dim x As Integer, y As Integer, a As Integer, b As Integer, c As Integer, d As Integer, e As Integer, dia As Integer
Dim mes As String
mes = vazio
dia = 0
ano = Val(pano)
x = 24
y = 5
a = ano Mod 19
b = ano Mod 4
c = ano Mod 7
d = (19 * a + x) Mod 30
e = (2 * b + 4 * c + 6 * d + y) Mod 7
If (d + e) > 9 Then
dia = (d + e - 9)
mes = "04"
Else
dia = (d + e + 22)
mes = "03"
End If
pascoa = Format(CDate(LTrim(Str(dia)) & "/" & mes & "/" & LTrim(pano)), "dd/mm/yyyy")
End Function
Bom neste exemplo ja da para ver que VB assusta tanto quanto Smalltalk
Esqueci de colocar o restante do codigo para calcular o carnaval
Public Function carnaval(pano As String)
Dim x As Integer, y As Integer, a As Integer, b As Integer, c As Integer, d As Integer, e As Integer, dia As Integer
Dim mes As String
Dim vpascoa As Date
mes = vazio
dia = 0
ano = Val(pano)
x = 24
y = 5
a = ano Mod 19
b = ano Mod 4
c = ano Mod 7
d = (19 * a + x) Mod 30
e = (2 * b + 4 * c + 6 * d + y) Mod 7
If (d + e) > 9 Then
dia = (d + e - 9)
mes = "04"
Else
dia = (d + e + 22)
mes = "03"
End If
vpascoa = Format(CDate(LTrim(Str(dia)) & "/" & mes & "/" & LTrim(pano)), "dd/mm/yyyy")
carnaval = Format(CDate(vpascoa) - 47, "dd/mm/yyyy")
End Function
Bem em C# as coisas são bem simples
Pronto assim a variável 'daysInMonth' vai retornar a quantidade de dias de um determinado mês em um determinado assim.
Mas para quem é curioso como eu, segue o Disassemble dessa função: