önceki ayın python tarihi


132

Python ile önceki ayın tarihini almaya çalışıyorum. İşte denediğim şey:

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

Ancak, bu yol 2 nedenden dolayı kötüdür: İlk olarak 2012 Şubat'ı için 20122'yi döndürür (201202 yerine) ve ikinci olarak Ocak'ta 12 yerine 0 döndürür.

Bu sorunu bash ile çözdüm

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

Bence bash'ın bu amaç için yerleşik bir yolu varsa, o zaman çok daha donanımlı olan python, bu hedefe ulaşmak için kendi komut dosyasını yazmaya zorlamaktan daha iyi bir şey sağlamalıdır. Elbette şöyle bir şey yapabilirim:

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)

Bu kodu test etmedim ve yine de kullanmak istemiyorum (başka bir yol bulamazsam: /)

Yardımınız için teşekkürler!


Yanıtlar:


301

datetime ve datetime.timedelta sınıfları arkadaşınızdır.

  1. bugün bul.
  2. bunu bu ayın ilk gününü bulmak için kullanın.
  3. tek bir günü önceki ayın son gününe yedeklemek için timedelta kullanın.
  4. Aradığınız YYYYMM dizesini yazdırın.

Bunun gibi:

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

201202 basılmıştır.


31
.replace()yöntemi kullanabilirsiniz :datetime.utcnow().replace(day=1) - timedelta(days=1)
jfs

1
Güzel! Değiştirme yöntemini kaçırdım.
bgporter

Ayrıca .replace()işlevi zincirleyebilirsiniz . Geçen ayı almak için bir kez yapın, ardından istediğiniz günü elde etmek için tekrar yapın. Önce: d = date.today() sonraone_month_ago = (d.replace(day=1) - timedelta(days=1)).replace(day=d.day)
Thane Plummer

@JFSebastian Doğru söylüyorsunuz - bunu belirttiğiniz için teşekkürler. "Ay" sabit bir zaman periyodu olmadığından, bunun için zarif bir tek satırlık yok gibi görünüyor. 2. işlevdeki bir işlevi içe aktararak calendarve kullanarak calendar.mdays[d.month-1]ve daha fazla çirkinlik yaparak çirkin bir şey yapabilirsiniz , ancak bu Pythonic gibi görünmüyor ve köşe durumlarını hesaba katmıyor. Aşağıdaki cevabımı , tüm durumlar için hangi hesapları kullanarak güncelledim , ancak bir algoritmanın parçası olarak istisnaları kullanmaktan nefret ediyorum. min()replacetry - except
Thane Plummer

Ivan'ın cevabına bakın ve şunu ekleyin: min (date.today (). day, last_day_of_previous_month.day)
michel.iamit

70

Dateutil kullanmalısınız . Bununla relativedelta'yı kullanabilirsiniz, bu timedelta'nın geliştirilmiş bir sürümüdür.

>>> 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

Yılın ilk ayı için çalışmıyor: >>> IllegalMonthError: hatalı -1 ay; 1-12 olmalıdır
mtoloo

@mtoloo dateutil'in hangi sürümü? Bu sorunu yaşamıyorum, ancak bazı alternatif sözdizimi ekleyeceğim
Dave Butler

1
Bunu tercih ediyorum çünkü @bgporter'ın çok güzel bir çözümü varken, onun çözümü gelecek aya bakmak kadar iyi çalışmıyor.
Daniel F

3
@mtoloo Muhtemelen ayları / ayları yanlış
yazmışsınızdır

2
@r_black Evet Haklısın. Bu benim hatamdı. Burada verilen çözüm doğrudur ve yılın ilk ayı için başka bir kontrole gerek yoktur.
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

Veya:

from datetime import date, timedelta

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

çözümün bir parçası ... geçen ayın gününü bulmak için şöyle bir şey ekleyin: gün sayısının aşılmasını önlemek için day_previous_month = min (today.day, last_day_of_previous_month.day).
michel.iamit

9

Bina bgporter cevabı .

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

Çok kolay ve basit. Bunu yap

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()

İşte çıktı: $ 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

Buraya gelen ve önceki ayın hem ilk hem de son gününü öğrenmek isteyen biri için:

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)

Çıktı:

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

Bir ayın (ve daha fazlasının) başlangıcını ve sonunu almak istiyorsanız, Calendarmodüle bir göz atın : stackabuse.com/introduction-to-the-python-calendar-module
toast38coza

Önceki 2. ayın başlamasını ve bitmesini istiyorsak?
oyuncu

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))

31 Mart'ta molalar
Mike

1

Sadece eğlence için, divmod kullanarak saf matematik cevabı. Çarpma nedeniyle oldukça yetersiz, ay sayısı üzerinde basit bir kontrol de yapabilir (12'ye eşitse, yılı artır, vb.)

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


1

dateparserDoğal dilde verilen geçmiş tarihi belirleyebilen ve karşılık gelen Python datetimenesnesini döndürebilen yüksek seviyeli bir kütüphane var

from dateparser import parse
parse('4 months ago')

0

@JF Sebastian'ın yorumundan yola çıkarak, replace()işlevi bir "ay" geriye gitmek için zincirleyebilirsiniz . Bir ay sabit bir zaman periyodu olmadığı için, bu çözüm önceki ayla aynı tarihe gitmeye çalışıyor ki bu tabii ki tüm aylar için çalışmıyor. Böyle bir durumda, bu algoritma varsayılan olarak önceki ayın son gününe döner.

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))

Çıktı:

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

0

LINUX / UNIX Ortamında EXE tipi bir dosyadaki ASCII harflerine bakmak istiyorsanız, "od -c 'dosyaadı' | daha fazla" deneyin.

Muhtemelen tanınmayan birçok öğe alacaksınız, ancak hepsi sunulacak ve HEX gösterimleri görüntülenecek ve ASCII eşdeğer karakterleri (uygunsa) onaltılık kodlar satırını izleyecektir. Bunu bildiğiniz derlenmiş bir kod parçası üzerinde deneyin. İçinde tanıdığın şeyler görebilirsin.


Soruyu nasıl yanıtladığını açıklamak için lütfen bunu düzenleyebilir misiniz?
AdrianHHH
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.