What's the most elegant way to get the end of the day (datetime)?

前端 未结 6 1534
无人及你
无人及你 2021-02-14 10:16

I\'m currently writing some reporting code that allows users to optionally specify a date range. The way it works (simplified), is:

  • A user (optionally) specifies a
相关标签:
6条回答
  • 2021-02-14 10:57
    from datetime import datetime, date, timedelta
    
    def get_current_timestamp():
        return int(datetime.now().timestamp())
    
    def get_end_today_timestamp():
        # get 23:59:59
        result = datetime.combine(date.today() + timedelta(days=1), datetime.min.time())
        return int(result.timestamp()) - 1
    
    def get_datetime_from_timestamp(timestamp):
        return datetime.fromtimestamp(timestamp)
    
    end_today = get_datetime_from_timestamp(get_end_today_timestamp())
    
    0 讨论(0)
  • 2021-02-14 10:58

    To set the stop_time, advance start_time one year, month or day as appropriate, then subtract one timedelta(microseconds=1)

    if options['year']:
        start_time = start_time.replace(year=options['year'], month=1, day=1)
        stop_time = stop_time.replace(year=options['year']+1)-timedelta(microseconds=1)
    
    elif options['month']:
        start_time = start_time.replace(month=options['month'], day=1)
        months=options['month']%12+1
        stop_time = stop_time.replace(month=months,day=1)-timedelta(microseconds=1)
    
    else:
        start_time = start_time.replace(day=options['day'])
        stop_time = stop_time.replace(day=options['day'])+timedelta(days=1,microseconds=-1)
    
    0 讨论(0)
  • 2021-02-14 11:07

    After looking at some of the answers here, and not really finding anything extremely elegant, I did some poking around the standard library and found my current solution (which I like quite well): dateutil.

    Here's how I implemented it:

    from datetime import date
    from dateutil.relativedelta import relativedelta
    
    now = date.today()
    stop_time = now + relativedelta(days=1)
    start_time = date(
        # NOTE: I'm not doing dict.get() since in my implementation, these dict
        # keys are guaranteed to exist.
        year = options['year'] or now.year,
        month = options['month'] or now.month,
        day = options['day'] or now.day
    )
    
    if options['year']:
        start_time = date(year=options['year'] or now.year, month=1, day=1)
        stop_time = start_time + relativedelta(years=1)
    
    if options['month']:
        start_time = date(
            year = options['year'] or now.year,
            month = options['month'] or now.month,
            day = 1
        )
        stop_time = start_time + relativedelta(months=1)
    
    if options['day']:
        start_time = date(
            year = options['year'] or now.year,
            month = options['month'] or now.month,
            day = options['day'] or now.day,
        )
        stop_time = start_time + relativedelta(days=1)
    
    # ... do stuff with start_time and stop_time here ...
    

    What I like about this implementation, is that python's dateutil.relativedata.relativedata works really well on edge cases. It gets the days/months/years correct. If I have month=12, and do relativedata(months=1), it'll increment the year and set the month to 1 (works nicely).

    Also: in the above implementation, if the user specifies none of the optional dates (year, month, or day)--we'll fallback to a nice default (start_time = this morning, stop_time = tonight), that way we'll default to doing stuff for the current day only.

    Thanks to everyone for their answers--they were helpful in my research.

    0 讨论(0)
  • 2021-02-14 11:19

    Using dict.get can simplify your code. It is a bit cleaner than using datetime.replace and timedelta objects.

    Here's something to get you started:

    from datetime import datetime
    
    options = dict(month=5, day=20)
    now = datetime.now()
    start_time = datetime(year=options.get('year', now.year), 
                          month=options.get('month', 1),
                          day=options.get('day', 1)
                          hour=0,
                          minute=0,
                          second=0)
    stop_time =  datetime(year=options.get('year', now.year), 
                          month=options.get('month', now.month),
                          day=options.get('day', now.day),
                          hour=now.hour,
                          minute=now.minute,
                          second=now.second)
    
    0 讨论(0)
  • 2021-02-14 11:19
        today = datetime.date.today()
        begintime = today.strftime("%Y-%m-%d 00:00:00")
        endtime = today.strftime("%Y-%m-%d 23:59:59")
    
    0 讨论(0)
  • 2021-02-14 11:22
    date = datetime.strftime('<input date str>')
    
    date.replace(hour=0, minute=0, second=0, microsecond=0)  # now we get begin of the day
    date += timedelta(days=1, microseconds=-1)  # now end of the day
    
    0 讨论(0)
提交回复
热议问题