Herramienta / biblioteca para calcular intervalos como “último jueves del mes”

Estoy buscando una herramienta de línea de comandos o algún tipo de biblioteca de Python (que luego pueda ajustar), para poder calcular las fechas que se especifican como “último jueves del mes”.

es decir, quiero permitir que la gente ingrese textos amigables con los humanos como el anterior y debería poder calcular todas las fechas para cualquier mes / año / lo que sea que cumpla con eso.

¿Alguna sugerencia?

No estoy completamente seguro, pero puedes mirar el módulo Datethtil de Python.

Ni mxDateTime ni Datejs ni ese servicio web son compatibles con “el último jueves del mes”. El OP quiere saber todos los últimos jueves del mes para, digamos, un año completo.

mxDateTime es compatible con las operaciones, pero la pregunta debe plantearse en código Python, no como una cadena.

Lo mejor que pude calcular es parsedatetime , pero eso no es compatible con “el último jueves del mes”. Soporta:

>>> c.parseDateText("last thursday of april 2001") (2001, 4, 20, 13, 55, 58, 3, 64, 0) >>> c.parseDateText("last thursday of may 2001") (2001, 5, 20, 13, 56, 3, 3, 64, 0) >>> c.parseDateText("last thursday of may 2010") (2010, 5, 20, 13, 56, 7, 3, 64, 0) >>> 

(Tenga en cuenta que ni DateJS ni ese servicio web admiten esta syntax).

EDIT : Umm, está bien, pero mientras el año y el mes son correctos, el día no lo es. El pasado jueves de abril de 2001 fue el 27. Creo que vas a tener que lanzar tu propia solución aquí.

No soporta:

 >>> c.parseDateText("last thursday of 2010") Traceback (most recent call last): File "", line 1, in  File "parsedatetime/parsedatetime.py", line 411, in parseDateText mth = self.ptc.MonthOffsets[mth] KeyError >>> 

Entonces, una posibilidad es la sustitución de texto: normalice la cadena a minúsculas, espacios simples, etc., luego haga una sustitución de cadena del “mes” para cada uno de los meses que le interesen. Es probable que tenga que modificar cualquier solución que encuentre. . Por ejemplo, en un código antiguo de Skip Montanaro que escribió para un sistema de calandrado de música en línea:

  # someone keeps submitting dates with september spelled wrong... 'septmber':9, 

O bien, escribe tu propio analizador en la parte superior de mxDateTime, utilizando todos los enlaces anteriores como referencias.

Creo que puedes llegar bastante lejos con solo el módulo de calendario estándar de Python, tal vez agregando algunos métodos “amigables con los humanos” además de esos métodos. El módulo le da iteradores para las fechas, teniendo en cuenta las semanas, y así sucesivamente.

Primero, supongo que debe responder a la pregunta “¿Cuáles son algunas maneras amigables para los humanos de hablar de citas?”, Que supongo que es más de la mitad de la dificultad de este problema.

Los algoritmos no son difíciles. Se proporcionan en el siguiente libro, que vale cada centavo.

http://emr.cs.iit.edu/home/reingold/calendar-book/third-edition/

El enfoque general es encontrar los primeros días de un mes requerido. Luego puede restar un día para encontrar el último día de un mes requerido. Luego, calcula un desplazamiento para el día de la semana que desea en relación con el día de la semana que encontró.

Supongamos que tiene un datetime.dat e, d . Puede calcular el fin de mes calculando el inicio del mes siguiente menos un día.

 monIx= d.year*12 + (d.month-1) + 1 endOfMonth= datetime.date( monIx//12, monIx%12+1, 1 ) - datetime.timedelta( days=1 ) 

En este punto, está buscando una compensación para el día requerido de la semana. En este caso, el día deseado de la semana es el jueves, que es 3 .

 dayOffset = ((3 - endOfMonth.weekday()) -7 ) % -7 lastDay = endOfMonth + datetime.timedelta( days=dayOffset ) 

El enfoque general de obtener la compensación del día de la semana requiere un poco de reflexión, pero solo hay unas pocas combinaciones de casos para experimentar.

Bueno, no sé si existe tal biblioteca, pero la date de GNU coreutils tiene algo como eso:

 $ date -d "last monday" Mon Mar 2 00:00:00 RST 2009 

Si esto es para una aplicación web, eche un vistazo a Datejs , puede ser más fácil usarlo en su formulario y luego pasar el valor del objeto date a Python.

Si terminas escribiendo uno mismo, la fuente también puede ser útil.