data pitone del mese precedente


132

Sto cercando di ottenere la data del mese precedente con Python. Ecco cosa ho provato:

str( time.strftime('%Y') ) + str( int(time.strftime('%m'))-1 )

Tuttavia, in questo modo è negativo per 2 motivi: in primo luogo restituisce 20122 per il febbraio 2012 (anziché 201202) e in secondo luogo restituirà 0 anziché 12 in gennaio.

Ho risolto questo problema con bash

echo $(date -d"3 month ago" "+%G%m%d")

Penso che se bash ha un modo integrato per questo scopo, allora Python, molto più attrezzato, dovrebbe fornire qualcosa di meglio che forzare la scrittura della propria sceneggiatura per raggiungere questo obiettivo. Ovviamente potrei fare qualcosa del tipo:

if int(time.strftime('%m')) == 1:
    return '12'
else:
    if int(time.strftime('%m')) < 10:
        return '0'+str(time.strftime('%m')-1)
    else:
        return str(time.strftime('%m') -1)

Non ho testato questo codice e non voglio usarlo comunque (a meno che non riesca a trovare nessun altro modo: /)

Grazie per l'aiuto!


Risposte:


300

Le classi datetime e datetime.timedelta sono tue amiche.

  1. trova oggi.
  2. usalo per trovare il primo giorno di questo mese.
  3. usa timedelta per eseguire il backup di un solo giorno, fino all'ultimo giorno del mese precedente.
  4. stampa la stringa AAAAMM che stai cercando.

Come questo:

 import datetime
 today = datetime.date.today()
 first = today.replace(day=1)
 lastMonth = first - datetime.timedelta(days=1)
 print(lastMonth.strftime("%Y%m"))

201202 è stampato.


31
potresti usare il .replace()metodo:datetime.utcnow().replace(day=1) - timedelta(days=1)
jfs

1
Freddo! Ho perso il metodo di sostituzione.
BG

Puoi anche concatenare la .replace()funzione. Fallo una volta per ottenere l'ultimo mese, quindi fallo di nuovo per ottenere il giorno desiderato. Primo: d = date.today() poione_month_ago = (d.replace(day=1) - timedelta(days=1)).replace(day=d.day)
Thane Plummer il

@JFSebastian Hai ragione, grazie per averlo sottolineato. Non sembra esserci un elegante one-liner per questo in quanto un "mese" non è un periodo di tempo costante. Puoi fare qualcosa di brutto importando calendare usando calendar.mdays[d.month-1]e più bruttezza in una min()funzione nel 2 ° replace, ma sembra non-Pythonic e non tiene conto dei casi angolari. Ho aggiornato la mia risposta di seguito usando try - exceptquali account per tutti i casi, anche se odio usare le eccezioni come parte di un algoritmo.
Thane Plummer,

vedere la risposta di Ivan, e aggiungere: min (. date.today () al giorno, last_day_of_previous_month.day)
michel.iamit

70

Dovresti usare dateutil . Con ciò, puoi usare relativedelta, è una versione migliorata di timedelta.

>>> import datetime 
>>> import dateutil.relativedelta
>>> now = datetime.datetime.now()
>>> print now
2012-03-15 12:33:04.281248
>>> print now + dateutil.relativedelta.relativedelta(months=-1)
2012-02-15 12:33:04.281248

Non funziona per il primo mese dell'anno: >>> IllegalMonthError: mese errato numero -1; deve essere 1-12
mtoloo

@mtoloo Quale versione di dateutil? Non ho questo problema, ma aggiungerò una sintassi alternativa
Dave Butler,

1
Preferisco questo perché mentre @bgporter ha una soluzione molto bella, la sua non funziona altrettanto bene per cercare il mese successivo.
Daniel F,

3
@mtoloo Probabilmente hai sbagliato a scrivere mesi / mese
r_black

2
@r_black Sì Hai ragione. È stata colpa mia. La soluzione fornita qui è corretta e non sono necessari ulteriori controlli per il primo mese dell'anno.
mtoloo,

45
from datetime import date, timedelta

first_day_of_current_month = date.today().replace(day=1)
last_day_of_previous_month = first_day_of_current_month - timedelta(days=1)

print "Previous month:", last_day_of_previous_month.month

O:

from datetime import date, timedelta

prev = date.today().replace(day=1) - timedelta(days=1)
print prev.month

parte della soluzione ... per trovare il giorno del mese scorso, aggiungere qualcosa del genere: day_previous_month = min (oggi.giorno, last_day_of_previous_month.day) per evitare di superare il numero di giorni.
michel.iamit,

9

Basandosi sulla risposta di bgporter .

def prev_month_range(when = None): 
    """Return (previous month's start date, previous month's end date)."""
    if not when:
        # Default to today.
        when = datetime.datetime.today()
    # Find previous month: https://stackoverflow.com/a/9725093/564514
    # Find today.
    first = datetime.date(day=1, month=when.month, year=when.year)
    # Use that to find the first day of this month.
    prev_month_end = first - datetime.timedelta(days=1)
    prev_month_start = datetime.date(day=1, month= prev_month_end.month, year= prev_month_end.year)
    # Return previous month's start and end dates in YY-MM-DD format.
    return (prev_month_start.strftime('%Y-%m-%d'), prev_month_end.strftime('%Y-%m-%d'))

5

È molto facile e semplice. Fai questo

from dateutil.relativedelta import relativedelta
from datetime import datetime

today_date = datetime.today()
print "todays date time: %s" %today_date

one_month_ago = today_date - relativedelta(months=1)
print "one month ago date time: %s" % one_month_ago
print "one month ago date: %s" % one_month_ago.date()

Ecco l'output: $ python2.7 main.py

todays date time: 2016-09-06 02:13:01.937121
one month ago date time: 2016-08-06 02:13:01.937121
one month ago date: 2016-08-06

4

Per qualcuno che è arrivato qui e cerca di ottenere sia il primo che l'ultimo giorno del mese precedente:

from datetime import date, timedelta

last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1)

start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day)

# For printing results
print("First day of prev month:", start_day_of_prev_month)
print("Last day of prev month:", last_day_of_prev_month)

Produzione:

First day of prev month: 2019-02-01
Last day of prev month: 2019-02-28

Se vuoi iniziare e finire un mese (e altro), dai un'occhiata al Calendarmodulo: stackabuse.com/introduction-to-python-calendar-module
toast38coza,

Se vogliamo l'inizio e la fine del 2 ° mese precedente?
giocatore

3
def prev_month(date=datetime.datetime.today()):
    if date.month == 1:
        return date.replace(month=12,year=date.year-1)
    else:
        try:
            return date.replace(month=date.month-1)
        except ValueError:
            return prev_month(date=date.replace(day=date.day-1))

Pause il 31 marzo
Mike

1

Solo per divertimento, una pura risposta matematica usando divmod. Abbastanza carente a causa della moltiplicazione, potrebbe anche fare un semplice controllo del numero del mese (se uguale a 12, aumento dell'anno, ecc.)

year = today.year
month = today.month

nm = list(divmod(year * 12 + month + 1, 12))
if nm[1] == 0:
    nm[1] = 12
    nm[0] -= 1
pm = list(divmod(year * 12 + month - 1, 12))
if pm[1] == 0:
    pm[1] = 12
    pm[0] -= 1

next_month = nm
previous_month = pm


0

Sulla base del commento di @JF Sebastian, è possibile concatenare la replace()funzione per tornare indietro di un "mese". Poiché un mese non è un periodo di tempo costante, questa soluzione tenta di tornare alla stessa data del mese precedente, che ovviamente non funziona per tutti i mesi. In tal caso, questo algoritmo viene impostato automaticamente sull'ultimo giorno del mese precedente.

from datetime import datetime, timedelta

d = datetime(2012, 3, 31) # A problem date as an example

# last day of last month
one_month_ago = (d.replace(day=1) - timedelta(days=1))
try:
    # try to go back to same day last month
    one_month_ago = one_month_ago.replace(day=d.day)
except ValueError:
    pass
print("one_month_ago: {0}".format(one_month_ago))

Produzione:

one_month_ago: 2012-02-29 00:00:00

0

Se vuoi guardare le lettere ASCII in un file di tipo EXE in un ambiente LINUX / UNIX, prova "od -c 'nomefile' | altro"

Probabilmente otterrai molti oggetti irriconoscibili, ma saranno tutti presentati e verranno visualizzate le rappresentazioni HEX e i caratteri equivalenti ASCII (se appropriato) seguiranno la linea di codici esadecimali. Provalo su un pezzo di codice compilato che conosci. Potresti vedere cose che riconosci.


Potete per favore modificarlo per spiegare come risponde alla domanda.
AdrianHHH,

0

Esiste una libreria di alto livello in dateparsergrado di determinare la data passata data in linguaggio naturale e restituire l' datetimeoggetto Python corrispondente

from dateparser import parse
parse('4 months ago')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.