Meses entre dos fechas


#1

Buenas.

existe algun helper o funcion que me imprima o devuelva en un hash o en
cualquier otra estructura, los nombres de los meses comprendidos entre
dos fechas?

ej: 2009-01-01 y 2009-05-01

me deberia devolver “Enero”, “Febrero”, “Marzo”, “Abril”, “Mayo”

Mientras estoy haciendo esto:

en el modelo

def meses_pago
ms = [“Enero”, “Febrero”, “Marzo”, …“Diciembre”]
mi = fecini.mon
mf = fecfin.mon
for i in mi…mf
meses = []
# aca voy
end
return meses
end

mil gracias por la ayuda.


#2

Tal vez esto te pueda ser util:

def get_months_in_dates(d1, d2)
return [I18n.l(d1, :format => ‘%B’)] if d1.strftime(’%m-%Y’)==
d2.strftime(’%m-%y’)

recent_date, paste_date = d1 < d2 ? [d2, d1] : [d1, d2]

c=0
months = []

loop do
past_date = past_date.months_since©
months << I18n.l(past_date, :format => ‘%B’)
break if past_date.strftime(’%m-%Y’) ==
recent_date.strftime(’%m-%Y’)
c += 1
end
months
end

Primero compruebo si las 2 fechas se encuentran en el mismo mes, si es
asi
entonces retorno rapido el nombre del mes, en caso contrario se sigue
procesando el metodo obteniendo la fecha reciente y la antigua, luego
entra
en un loop que acabara cuando el año y mes de ambas fechas sean el
mismo.

Saludos.


#3

Gracias Ruben

lo voy a incorporar a mi aplicacion pues la funcion que hic me quedo con
mucho codigo.

gracias y saludos


#4

Ruben, creo que me toca montar algo mas referente a internacionaizacion.

gracias


#5

2009/4/26 Aprendiz_ror Ruby on rails removed_email_address@domain.invalid

Buenas.

existe algun helper o funcion que me imprima o devuelva en un hash o en
cualquier otra estructura, los nombres de los meses comprendidos entre
dos fechas?

Que yo sepa no. Pero tienes DateTime ranges

def month_names_between(d1,d2)
(d1…d2).map{|d| I18n.l(d, :format=>’%B’)}.uniq
end

month_names_between( Date.current-3.months, Date.current )
=> [“January”, “February”, “March”, “April”]

No es del todo correcto, ya que interas todos los días, pero el código
queda
más sencillito.


Guillermo Álvarez

Sent from Madrid, Comunidad de Madrid


#6

una posible alternativa (sin internacionalización… si la quieres añadir
es cambiar el array por una llamada a i18n)

def months_in_range(d1,d2)
return nil unless d1 <= d2
year_lap=d2.year - d1.year
m1,m2=d1.month,d2.month

range=if year_lap == 0
(m1…m2).to_a
else
(m1…12).to_a + (1…12).to_a * year_lap + (1…m2).to_a
end

m_names=‘jan’,‘feb’,‘mar’,‘apr’,‘may’,‘jun’,‘jul’,‘aug’,‘sept’,‘oct’,‘nov’,‘dec’
range.map{|m| m_names[m-1]}
end

Si los meses están en el mismo año, con un simple rango nos vale para
saber los números de mes que hay en medio. Si están en diferente
año,tendrás varios rangos de 1…12 y luego dos rangos extras, desde el mes
inicial hasta el final de ese año, y desde el principio del último
añoal mes final.

Cuando ya sepas el rango completo de números de mes que hay en el
intervalo, sólo queda mapear ese array de índices de mes a sus nombres
con el método que prefieras (en el ejemplo un array sencillo y un map
con el índice)

saludos,

j


javier ramírez

…i do ruby on rails development in madrid, spain, at
http://www.aspgems.com
…you can find out more about me on http://formatinternet.wordpress.com
and http://workingwithrails.com/person/5987-javier-ramirez


#7

Gracias por todos sus aportes, la solucion la logre con el post de Ruben
y complemente con este otro post:
http://www.ruby-forum.com/topic/173897#new

gracias a la comunidad de esta lista he logrado avanzar mucho.


#8

por fin termine el codigo, me parece HORRIBLE pero hace lo que necesito.

se que con la ayuda de todos ustedes lo puedo mejorar.

saludos


#9

pero hace falta algo en este caso:

2008-08-01 y 2009-02-01

estoy tratando de solucionarlo.

saludos


#10

jejejej. Tienes Razon Guillermo, quede tan loco que no me fije que lo
puse.

advierto, quedo horrible pero hace lo que quiero.

saludos

def month_names_between
return [I18n.l(fecini, :format => ‘%B’)] if
fecini.strftime(’%m-%Y’)== fecfin.strftime(’%m-%Y’)
ai = fecini.strftime(’%Y’).to_i
af = fecfin.strftime(’%Y’).to_i
mi = fecini.strftime(’%m’).to_i
mf = fecfin.strftime(’%m’).to_i
mes = []
for i in (ai…af)
if ai == af
for m in mi…mf
f = (i.to_s+’-’+l.to_s+’-01’).to_time
mes << I18n.l(f, :format => ‘%B’)+’-’+i.to_s
end
elsif (i < af)
for l in (mi…12)
f = (i.to_s+’-’+l.to_s+’-01’).to_time
mes << I18n.l(f, :format => ‘%B’)+’-’+i.to_s
end
else
for k in 1…mf
f = (i.to_s+’-’+k.to_s+’-01’).to_time
mes << I18n.l(f, :format => ‘%B’)+’-’+i.to_s
end
end
end
mes
end


#11

Que algo como esto…

f1 = Time.now
f2 = 15.months.since

f_start = f1.beginning_of_month
f_end = f2.beginning_of_month

f_iterator = f_start
months = []

begin
months << f_iterator.month
f_iterator = f_iterator.months_since(1)
end while f_iterator < f_end

f1 y f2 serían las dos fechas y se está asumiendo que f1 < f2. Le falta
meterle algunas cosas pero creo que a nivel de algoritmo sería mas
sencillo
e incluso mas eficiente.

Saludos,

2009/4/27 Aprendiz_ror Ruby on rails removed_email_address@domain.invalid


#12

2009/4/27 Aprendiz_ror Ruby on rails removed_email_address@domain.invalid

por fin termine el codigo, me parece HORRIBLE pero hace lo que necesito.

se que con la ayuda de todos ustedes lo puedo mejorar.

Si no pones el código… lo dudo mucho.


Guillermo Álvarez

Sent from Madrid, Comunidad de Madrid


#13

On Mon, Apr 27, 2009 at 21:06, Aprendiz_ror Ruby on rails
removed_email_address@domain.invalid wrote:

jejejej. Â Tienes Razon Guillermo, quede tan loco que no me fije que lo
puse.

advierto, quedo horrible pero hace lo que quiero.

El correo electrónico no es el mejor sitio para comentar código. Me he
decidido por un Gist en Github http://gist.github.com/102704. Allí
están tu versión y mi versión (no me he desviado de tu idea, pero he
realizado muchos pequeños cambios), y creo que si alguién quiere
aportar su versión no tiene más que forkear.


#14

Gracias Luis F.

pero no me arroja los resultados esperados.

def felipe
f1 = fecini
f2 = fecfin
f_start = f1.beginning_of_month
f_end = f2.beginning_of_month
f_iterator = f_start
months = []
begin
months << f_iterator.month
f_iterator = f_iterator.months_since(1)
end while f_iterator < f_end
months
end

saludos


#15

Gracias Daniel, me sale el error:
can’t convert Array into Integer

saludos


#16

2009/4/28 Aprendiz_ror Ruby on rails
removed_email_address@domain.invalid:

saludos y gracias
Tienes razón, ese es un error. Se me pasó, iba probando las cosas una
a una, pero no todo en general.
Y por eso se me pasó también que debería haber utilizado “+=” en vez
de “<<” para añadir nuevos elementos al array de meses.
Ahora, probandolo del todo, a mí me funciona el código. Te queda tu
parte de hacer las pruebas de unidad.
Todo sigue estando en http://gist.github.com/102704.

Suerte.


#17

Excelente Daniel, eso era lo quenecesitaba, ya me funciona maravilloso.

gracias


#18

Daniel aca esta el error, pero no estoy en capacidad de resolverlo:

tenes:
mes.map { |mes, anio| “#{I18n.t(“date.month_names”)[mes]}-#{anio}” }

y debe ser:
meses.map { |mes, anio| “#{I18n.t(“date.month_names”)[mes]}-#{anio}” }

sin embargo sigue el error que te menciono.

saludos y gracias