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

前端 未结 6 1553
无人及你
无人及你 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 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.

提交回复
热议问题