Πάρτε τελευταία ημέρα του μήνα στην Python

ψήφοι
430

Είναι ένας τρόπος για τη χρήση τυποποιημένων βιβλιοθήκη Python για να καθορίσει εύκολα (δηλαδή μια κλήση συνάρτησης) την τελευταία ημέρα του συγκεκριμένου μήνα εκεί;

Εάν η πρότυπη βιβλιοθήκη δεν υποστηρίζει ότι, κάνει το πακέτο dateutil υποστηρίξει αυτό;

Δημοσιεύθηκε 03/09/2008 στις 23:54
πηγή χρήστη
Σε άλλες γλώσσες...                            


31 απαντήσεις

ψήφοι
58

EDIT: Δείτε την απάντηση @Blair Conrad για ένα καθαρότερο λύση


>>> import datetime
>>> datetime.date (2000, 2, 1) - datetime.timedelta (days = 1)
datetime.date(2000, 1, 31)
>>> 
Απαντήθηκε 04/09/2008 στις 00:26
πηγή χρήστη

ψήφοι
36

EDIT: δείτε άλλα απάντησή μου . Έχει μια καλύτερη εφαρμογή από αυτό, το οποίο αφήνω εδώ μόνο σε περίπτωση που κάποιος ενδιαφέρεται να δει πώς θα μπορούσε κανείς να «κατασκευάζουν τα δικά σου» αριθμομηχανή.

@John Millikin δίνει μια καλή απάντηση, με την πρόσθετη περιπλοκή του υπολογισμού της πρώτης ημέρας του επόμενου μήνα.

Το παρακάτω δεν είναι ιδιαίτερα κομψό, αλλά για να καταλάβω την τελευταία ημέρα του μήνα ότι οποιαδήποτε δεδομένη ημερομηνία ζει μέσα, θα μπορούσατε να δοκιμάσετε:

def last_day_of_month(date):
    if date.month == 12:
        return date.replace(day=31)
    return date.replace(month=date.month+1, day=1) - datetime.timedelta(days=1)

>>> last_day_of_month(datetime.date(2002, 1, 17))
datetime.date(2002, 1, 31)
>>> last_day_of_month(datetime.date(2002, 12, 9))
datetime.date(2002, 12, 31)
>>> last_day_of_month(datetime.date(2008, 2, 14))
datetime.date(2008, 2, 29)
Απαντήθηκε 04/09/2008 στις 01:25
πηγή χρήστη

ψήφοι
783

Δεν το είχα προσέξει αυτό νωρίτερα, όταν έψαχνα στο τεκμηρίωση για την ενότητα του ημερολογίου , αλλά μια μέθοδο που ονομάζεται monthrange παρέχει αυτές τις πληροφορίες:

monthrange (έτος, μήνας)
    Επιστρέφει καθημερινές της πρώτης ημέρας του μήνα και ο αριθμός των ημερών στο μήνα, για το συγκεκριμένο έτος και μήνα.

>>> import calendar
>>> calendar.monthrange(2002,1)
(1, 31)
>>> calendar.monthrange(2008,2)
(4, 29)
>>> calendar.monthrange(2100,2)
(0, 28)

Έτσι:

calendar.monthrange(year, month)[1]

Φαίνεται σαν ο απλούστερος τρόπος να πάει.

Ακριβώς για να είναι σαφής, monthrangeυποστηρίζει δίσεκτα έτη, καθώς και:

>>> from calendar import monthrange
>>> monthrange(2012, 2)
(2, 29)

Προηγούμενη απάντησή μου εξακολουθεί να λειτουργεί, αλλά είναι σαφώς κάτω του βέλτιστου.

Απαντήθηκε 04/09/2008 στις 11:44
πηγή χρήστη

ψήφοι
11

Μια άλλη λύση θα ήταν να κάνει κάτι σαν αυτό:

from datetime import datetime

def last_day_of_month(year, month):
    """ Work out the last day of the month """
    last_days = [31, 30, 29, 28, 27]
    for i in last_days:
        try:
            end = datetime(year, month, i)
        except ValueError:
            continue
        else:
            return end.date()
    return None

Και χρησιμοποιήστε τη λειτουργία ως εξής:

>>> 
>>> last_day_of_month(2008, 2)
datetime.date(2008, 2, 29)
>>> last_day_of_month(2009, 2)
datetime.date(2009, 2, 28)
>>> last_day_of_month(2008, 11)
datetime.date(2008, 11, 30)
>>> last_day_of_month(2008, 12)
datetime.date(2008, 12, 31)
Απαντήθηκε 10/12/2008 στις 14:47
πηγή χρήστη

ψήφοι
-6

Έχω μια απλή λύση:

import datetime   
datetime.date(2012,2, 1).replace(day=1,month=datetime.date(2012,2,1).month+1)-timedelta(days=1)
datetime.date(2012, 2, 29)
Απαντήθηκε 21/08/2012 στις 22:09
πηγή χρήστη

ψήφοι
1

Αυτό δεν αντιμετωπίζει το κύριο ζήτημα, αλλά ένα ωραίο κόλπο για να πάρει την τελευταία ημέρα της εβδομάδας σε έναν μήνα είναι η χρήση calendar.monthcalendar, η οποία επιστρέφει έναν πίνακα των ημερομηνιών, που διοργανώθηκε με Δευτέρα ως την πρώτη στήλη έως την Κυριακή ως την τελευταία.

# Some random date.
some_date = datetime.date(2012, 5, 23)

# Get last weekday
last_weekday = np.asarray(calendar.monthcalendar(some_date.year, some_date.month))[:,0:-2].ravel().max()

print last_weekday
31

Το όλο [0:-2]πράγμα είναι να ξυρίσει τις στήλες του Σαββατοκύριακου και να ρίξει τους έξω. Οι ημερομηνίες που πέφτουν έξω από το μήνα που προκύπτει από το 0, έτσι ώστε το μέγιστο τους αγνοεί αποτελεσματικά.

Η χρήση της numpy.ravelδεν είναι απολύτως απαραίτητα, αλλά μου αρέσει να στηρίζεται στην απλή σύμβαση που numpy.ndarray.maxθα ισοπεδώσουν την σειρά, αν δεν πει ποια άξονα για τον υπολογισμό πάνω.

Απαντήθηκε 14/11/2012 στις 18:06
πηγή χρήστη

ψήφοι
88

Εάν δεν θέλετε να εισαγάγετε την calendarενότητα, μια απλή λειτουργία δύο σταδίων μπορεί επίσης να είναι:

import datetime

def last_day_of_month(any_day):
    next_month = any_day.replace(day=28) + datetime.timedelta(days=4)  # this will never fail
    return next_month - datetime.timedelta(days=next_month.day)

έξοδοι:

>>> for month in range(1, 13):
...     print last_day_of_month(datetime.date(2012, month, 1))
...
2012-01-31
2012-02-29
2012-03-31
2012-04-30
2012-05-31
2012-06-30
2012-07-31
2012-08-31
2012-09-30
2012-10-31
2012-11-30
2012-12-31
Απαντήθηκε 26/11/2012 στις 10:48
πηγή χρήστη

ψήφοι
27

Αυτό είναι πραγματικά αρκετά εύκολο με dateutil.relativedelta(πακέτο python-datetutil για pip). day=31θα είναι πάντα επιστρέφουν πάντα την τελευταία ημέρα του μήνα.

Παράδειγμα:

from datetime import datetime
from dateutil.relativedelta import relativedelta

date_in_feb = datetime.datetime(2013, 2, 21)
print datetime.datetime(2013, 2, 21) + relativedelta(day=31)  # End-of-month
>>> datetime.datetime(2013, 2, 28, 0, 0)
Απαντήθηκε 21/02/2013 στις 02:09
πηγή χρήστη

ψήφοι
5
import datetime

now = datetime.datetime.now()
start_month = datetime.datetime(now.year, now.month, 1)
date_on_next_month = start_month + datetime.timedelta(35)
start_next_month = datetime.datetime(date_on_next_month.year, date_on_next_month.month, 1)
last_day_month = start_next_month - datetime.timedelta(1)
Απαντήθηκε 16/06/2013 στις 15:51
πηγή χρήστη

ψήφοι
0

Αν θέλετε να φτιάξετε το δικό σας μικρό λειτουργία, αυτό είναι ένα καλό σημείο εκκίνησης:

def eomday(year, month):
    """returns the number of days in a given month"""
    days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    d = days_per_month[month - 1]
    if month == 2 and (year % 4 == 0 and year % 100 != 0 or year % 400 == 0):
        d = 29
    return d

Για αυτό θα πρέπει να γνωρίζουν τους κανόνες για τα δίσεκτα έτη:

  • κάθε τέταρτο έτος
  • με εξαίρεση κάθε 100 χρόνια
  • αλλά και πάλι κάθε 400 χρόνια
Απαντήθηκε 30/04/2014 στις 07:33
πηγή χρήστη

ψήφοι
9
from datetime import timedelta
(any_day.replace(day=1) + timedelta(days=32)).replace(day=1) - timedelta(days=1)
Απαντήθηκε 03/05/2014 στις 16:16
πηγή χρήστη

ψήφοι
3

Για μένα είναι ο πιο απλός τρόπος:

selected_date = date(some_year, some_month, some_day)

if selected_date.month == 12: # December
     last_day_selected_month = date(selected_date.year, selected_date.month, 31)
else:
     last_day_selected_month = date(selected_date.year, selected_date.month + 1, 1) - timedelta(days=1)
Απαντήθηκε 24/07/2014 στις 08:16
πηγή χρήστη

ψήφοι
12

Χρησιμοποιώντας relativedeltaθα πάρετε την τελευταία ημέρα του μήνα σαν αυτό:

from dateutil.relativedelta import relativedelta
last_date_of_month = datetime(mydate.year,mydate.month,1)+relativedelta(months=1,days=-1)

Η ιδέα είναι να πάρετε τη γροθιά ημέρα του μήνα και να χρησιμοποιήσετε relativedeltaγια να πάει ένα μήνα μπροστά και 1 μέρα πίσω έτσι θα πάρετε την τελευταία ημέρα του μήνα που ήθελε.

Απαντήθηκε 27/12/2014 στις 10:54
πηγή χρήστη

ψήφοι
7
>>> import datetime
>>> import calendar
>>> date  = datetime.datetime.now()

>>> print date
2015-03-06 01:25:14.939574

>>> print date.replace(day = 1)
2015-03-01 01:25:14.939574

>>> print date.replace(day = calendar.monthrange(date.year, date.month)[1])
2015-03-31 01:25:14.939574
Απαντήθηκε 05/03/2015 στις 18:02
πηγή χρήστη

ψήφοι
1

Χρησιμοποιήστε pandas!

def isMonthEnd(date):
    return date + pd.offsets.MonthEnd(0) == date

isMonthEnd(datetime(1999, 12, 31))
True
isMonthEnd(pd.Timestamp('1999-12-31'))
True
isMonthEnd(pd.Timestamp(1965, 1, 10))
False
Απαντήθηκε 24/07/2015 στις 18:59
πηγή χρήστη

ψήφοι
0
import calendar
from time import gmtime, strftime
calendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1]

Παραγωγή:

31



Αυτό θα εκτυπώσετε την τελευταία ημέρα του ό, τι ο τρέχων μήνας είναι. Σε αυτό το παράδειγμα, η 15η Μαΐου 2016. Έτσι έξοδο σας μπορεί να είναι διαφορετική, ωστόσο η έξοδος θα είναι τόσο πολλές ημέρες ότι ο τρέχων μήνας είναι. Μεγάλη αν θέλετε να ελέγξετε την τελευταία ημέρα του μήνα, εκτελώντας καθημερινά περιοδική εργασία.

Ετσι:

import calendar
from time import gmtime, strftime
lastDay = calendar.monthrange(int(strftime("%Y", gmtime())), int(strftime("%m", gmtime())))[1]
today = strftime("%d", gmtime())
lastDay == today

Παραγωγή:

False

Εκτός και αν είναι η τελευταία ημέρα του μήνα.

Απαντήθηκε 16/05/2016 στις 03:22
πηγή χρήστη

ψήφοι
1

Προτιμώ αυτόν τον τρόπο

import datetime
import calendar

date=datetime.datetime.now()
month_end_date=datetime.datetime(date.year,date.month,1) + datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1] - 1)
Απαντήθηκε 25/08/2016 στις 08:48
πηγή χρήστη

ψήφοι
3

Για να πάρετε την τελευταία ημέρα του μήνα κάνουμε κάτι σαν αυτό:

from datetime import date, timedelta
import calendar
last_day = date.today().replace(day=calendar.monthrange(date.today().year, date.today().month)[1])

Τώρα να εξηγήσουμε αυτό που κάνουμε εδώ θα το σπάσει σε δύο μέρη:

το πρώτο είναι να πάρει τον αριθμό των ημερών του τρέχοντος μήνα για τον οποίο χρησιμοποιούμε monthrange που Blair Conrad έχει ήδη αναφερθεί λύση του:

calendar.monthrange(date.today().year, date.today().month)[1]

δεύτερο είναι να πάρει η ίδια η τελευταία ημερομηνία που κάνουμε με τη βοήθεια των αντικαταστήσει π.χ.

>>> date.today()
datetime.date(2017, 1, 3)
>>> date.today().replace(day=31)
datetime.date(2017, 1, 31)

και όταν τα συνδυάσετε όπως αναφέρθηκε στην κορυφή παίρνουμε μια δυναμική λύση.

Απαντήθηκε 30/08/2016 στις 08:14
πηγή χρήστη

ψήφοι
1

Μπορείτε να υπολογίσετε την ημερομηνία λήξης τον εαυτό σας. η απλή λογική είναι να αφαιρέσουμε την ημέρα από την ημερομηνία_έναρξης του επόμενου μήνα. :)

Έτσι γράψετε μια προσαρμοσμένη μέθοδο,

import datetime

def end_date_of_a_month(date):


    start_date_of_this_month = date.replace(day=1)

    month = start_date_of_this_month.month
    year = start_date_of_this_month.year
    if month == 12:
        month = 1
        year += 1
    else:
        month += 1
    next_month_start_date = start_date_of_this_month.replace(month=month, year=year)

    this_month_end_date = next_month_start_date - datetime.timedelta(days=1)
    return this_month_end_date

Κλήση,

end_date_of_a_month(datetime.datetime.now().date())

Θα επιστρέψει την ημερομηνία λήξης του τρέχοντος μηνός. Περάστε οποιαδήποτε ημερομηνία σε αυτή τη λειτουργία. που επιστρέφει την ημερομηνία λήξης του εν λόγω μήνα.

Απαντήθηκε 02/09/2016 στις 07:47
πηγή χρήστη

ψήφοι
5

αν είστε πρόθυμοι να χρησιμοποιήσετε μια εξωτερική βιβλιοθήκη, ελέγξτε http://crsmithdev.com/arrow/

U μπορεί στη συνέχεια να πάρει την τελευταία ημέρα του μήνα με:

import arrow
arrow.utcnow().ceil('month').date()

Αυτό επιστρέφει μια ημερομηνία αντικείμενο το οποίο μπορείτε να κάνετε χειραγώγηση σας.

Απαντήθηκε 27/11/2016 στις 08:01
πηγή χρήστη

ψήφοι
-2

Ελπίζω, Είναι χρήσιμο για πολύ το much..Try σε αυτό το way..we πρέπει να πρέπει εισαγωγής κάποιο πακέτο

import time
from datetime import datetime, date
from datetime import timedelta
from dateutil import relativedelta

  start_date = fields.Date(
        string='Start Date', 
        required=True,
        ) 

    end_date = fields.Date(
        string='End Date', 
        required=True,
        )

    _defaults = {
        'start_date': lambda *a: time.strftime('%Y-%m-01'),
        'end_date': lambda *a: str(datetime.now() + relativedelta.relativedelta(months=+1, day=1, days=-1))[:10],
    }
Απαντήθηκε 27/09/2017 στις 11:23
πηγή χρήστη

ψήφοι
3

Ο πιο εύκολος τρόπος (χωρίς να χρειάζεται να εισάγετε το ημερολόγιο), είναι να πάρει την πρώτη ημέρα του επόμενου μήνα, και στη συνέχεια αφαιρέστε την ημέρα από αυτό.

import datetime as dt
from dateutil.relativedelta import relativedelta

thisDate = dt.datetime(2017, 11, 17)

last_day_of_the_month = dt.datetime(thisDate.year, (thisDate + relativedelta(months=1)).month, 1) - dt.timedelta(days=1)
print last_day_of_the_month

Παραγωγή:

datetime.datetime(2017, 11, 30, 0, 0)

PS: Αυτός ο κωδικός τρέχει πιο γρήγορα σε σύγκριση με την import calendarπροσέγγιση? Δες παρακάτω:

import datetime as dt
import calendar
from dateutil.relativedelta import relativedelta

someDates = [dt.datetime.today() - dt.timedelta(days=x) for x in range(0, 10000)]

start1 = dt.datetime.now()
for thisDate in someDates:
    lastDay = dt.datetime(thisDate.year, (thisDate + relativedelta(months=1)).month, 1) - dt.timedelta(days=1)

print ('Time Spent= ', dt.datetime.now() - start1)


start2 = dt.datetime.now()
for thisDate in someDates:
    lastDay = dt.datetime(thisDate.year, 
                          thisDate.month, 
                          calendar.monthrange(thisDate.year, thisDate.month)[1])

print ('Time Spent= ', dt.datetime.now() - start2)

ΠΑΡΑΓΩΓΗ:

Time Spent=  0:00:00.097814
Time Spent=  0:00:00.109791

Αυτός ο κωδικός υποθέτει ότι θέλετε την ημερομηνία της τελευταίας ημέρας του μήνα (δηλαδή, όχι μόνο από την πλευρά DD, αλλά ολόκληρη η ημερομηνία ΕΕΕΕΜΜΗΗ)

Απαντήθηκε 17/11/2017 στις 17:38
πηγή χρήστη

ψήφοι
0

Αν περνάτε σε ένα εύρος ημερομηνιών, μπορείτε να χρησιμοποιήσετε αυτό:

def last_day_of_month(any_days):
    res = []
    for any_day in any_days:
        nday = any_day.days_in_month -any_day.day
        res.append(any_day + timedelta(days=nday))
    return res
Απαντήθηκε 12/03/2018 στις 13:14
πηγή χρήστη

ψήφοι
0

Εδώ είναι μια λύση που να βασίζεται λάμδα python:

next_month = lambda y, m, d: (y, m + 1, 1) if m + 1 < 13 else ( y+1 , 1, 1)
month_end  = lambda dte: date( *next_month( *dte.timetuple()[:3] ) ) - timedelta(days=1)

Η next_monthλ βρίσκει την εκπροσώπηση πλειάδα από την πρώτη ημέρα του επόμενου μήνα, και κυλά πάνω στο επόμενο έτος. Η month_endλάμδα μετατρέπει μια ημερομηνία ( dte) σε μια πλειάδα, εφαρμόζει next_monthκαι δημιουργεί μια νέα ημερομηνία. Στη συνέχεια, «το τέλος του μήνα» του είναι απλώς πρώτη μέρα μείον του επόμενου μήνα timedelta(days=1).

Απαντήθηκε 07/04/2018 στις 21:52
πηγή χρήστη

ψήφοι
0

Στον παρακάτω κώδικα «get_last_day_of_month (dt)» θα σας δώσει αυτή, με ημερομηνία σε μορφή συμβολοσειράς όπως «ΕΕΕΕ-ΜΜ-ΗΗ».

import datetime

def DateTime( d ):
    return datetime.datetime.strptime( d, '%Y-%m-%d').date()

def RelativeDate( start, num_days ):
    d = DateTime( start )
    return str( d + datetime.timedelta( days = num_days ) )

def get_first_day_of_month( dt ):
    return dt[:-2] + '01'

def get_last_day_of_month( dt ):
    fd = get_first_day_of_month( dt )
    fd_next_month = get_first_day_of_month( RelativeDate( fd, 31 ) )
    return RelativeDate( fd_next_month, -1 )
Απαντήθηκε 14/11/2018 στις 03:12
πηγή χρήστη

ψήφοι
0

Εδώ είναι μια άλλη απάντηση. Δεν απαιτούνται επιπλέον πακέτα.

datetime.date(year + int(month/12), (month+1)%12, 1)-datetime.timdelta(days=1)

Πάρτε την πρώτη ημέρα του επόμενου μήνα και να αφαιρέσετε την ημέρα από αυτό.

Απαντήθηκε 29/11/2018 στις 20:29
πηγή χρήστη

ψήφοι
0

μπορείτε να χρησιμοποιήσετε relativedelta https://dateutil.readthedocs.io/en/stable/relativedelta.html month_end = <your datetime value within the month> + relativedelta(day=31) που θα σας δώσει την τελευταία ημέρα.

Απαντήθηκε 11/12/2018 στις 11:41
πηγή χρήστη

ψήφοι
1

Στην Python 3.7 είναι η χωρίς χαρτιά calendar.monthlen(year, month)λειτουργία :

>>> calendar.monthlen(2002, 1)
31
>>> calendar.monthlen(2008, 2)
29
>>> calendar.monthlen(2100, 2)
28

Είναι ισοδύναμη με την τεκμηριωμένη calendar.monthrange(year, month)[1]κλήση .

Απαντήθηκε 16/02/2019 στις 13:09
πηγή χρήστη

ψήφοι
0

Αυτή είναι η απλούστερη λύση για μένα χρησιμοποιώντας μόνο το πρότυπο βιβλιοθήκης datetime:

import datetime

def get_month_end(dt):
    first_of_month = datetime.datetime(dt.year, dt.month, 1)
    next_month_date = first_of_month + datetime.timedelta(days=32)
    new_dt = datetime.datetime(next_month_date.year, next_month_date.month, 1)
    return new_dt - datetime.timedelta(days=1)
Απαντήθηκε 21/06/2019 στις 17:49
πηγή χρήστη

ψήφοι
0

Για να πάρετε την τελευταία ημέρα του μήνα με μόνο datetimeμπορείτε να χρησιμοποιήσετε αυτήν την απλή λειτουργία:

import datetime

def last_day_of_month(d: datetime.date) -> datetime.date:
    return d.replace(month=d.month % 12 + 1, day=1) - datetime.timedelta(days=1)

Μπορείτε επίσης να χρησιμοποιήσετε calendar.monthrange()για να πάρετε τον αριθμό των ημερών του μήνα και να ενημερώσετε την ημερομηνία αναλόγως, αν και σε δοκιμές μου αυτή φαίνεται να είναι πιο αργή από ό, τι την προηγούμενη έκδοση:

import calendar, datetime

def last_day_of_month(d: datetime.date) -> datetime.date:
    return d.replace(day=calendar.monthrange(d.year, d.month)[1])
Απαντήθηκε 24/06/2019 στις 16:08
πηγή χρήστη

ψήφοι
0

Εδώ είναι μια μακρά (εύκολο να καταλάβει) έκδοση, αλλά φροντίζει για τα δίσεκτα έτη.

ζητωκραυγές, JK

def last_day_month(year, month):
    leap_year_flag = 0
    end_dates = {
        1: 31,
        2: 28,
        3: 31,
        4: 30,
        5: 31,
        6: 30,
        7: 31,
        8: 31,
        9: 30,
        10: 31,
        11: 30,
        12: 31
    }

    # Checking for regular leap year    
    if year % 4 == 0:
        leap_year_flag = 1
    else:
        leap_year_flag = 0

    # Checking for century leap year    
    if year % 100 == 0:
        if year % 400 == 0:
            leap_year_flag = 1
        else:
            leap_year_flag = 0
    else:
        pass

    # return end date of the year-month
    if leap_year_flag == 1 and month == 2:
        return 29
    elif leap_year_flag == 1 and month != 2:
        return end_dates[month]
    else:
        return end_dates[month]
Απαντήθηκε 20/01/2020 στις 01:53
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more