Jimmy Lin
Jimmy Lin

Reputation: 1501

How to get the first and last second using datetime module in python?

How to get the first and last second in python using the DateTime module which means 00:00:01 and 23:59:59.

I want to get the six DateTime before today.

So, for example:

today is 12/10, and I want to get

12/9 00:00:01 and 23:59:59

...

12/4 00:00:01 and 23:59:59

Thank you very much.

Upvotes: 9

Views: 8362

Answers (2)

Bradleo
Bradleo

Reputation: 178

I had problems with the accepted answer not working with timezones (You can see my train of thought in the comments.

Here's what I came up with for use with pytz.

# utc_date_time should already be localized to UTC
# it should NOT be a naive date-time
def get_last_second_of_day_in_timezone(utc_date_time, local_timezone: str):
    local_timezone = pytz.timezone(local_timezone)
    due_date_in_timezone = utc_date_time.astimezone(local_timezone)
    last_second_of_due_day_naive = datetime.combine(due_date_in_timezone, time.max)
    last_second_of_due_day = local_timezone.localize(last_second_of_due_day_naive)
    return last_second_of_due_day

And a unit test for it

def test_get_last_second_of_day_in_timezone__previous_day_utc(self):
  utc_tz = pytz.timezone("UTC")
  ten_pm_utc = utc_tz.localize(datetime(2022, 1, 1, hour=22))

  bangladesh_timezone = "Asia/Dhaka"
  # 10pm UTC is the next day in Dhaka, so this should be the second before midnight on the 2nd
  last_second_of_jan_2_bangladesh = get_last_second_of_day_in_timezone(ten_pm_utc, bangladesh_timezone)
  self.assertEqual(last_second_of_jan_2_bangladesh.year, 2022)
  self.assertEqual(last_second_of_jan_2_bangladesh.month, 1)
  self.assertEqual(last_second_of_jan_2_bangladesh.day, 2)
  self.assertEqual(last_second_of_jan_2_bangladesh.hour, 23)
  self.assertEqual(last_second_of_jan_2_bangladesh.minute, 59)
  # This doesn't work on all machines, should find better check
  # This is because pytz.timezone(bangladesh_timezone) is the offset from the late 1800s, which is +6:02 instead of +6:00
  # self.assertEqual(last_second_of_jan_2_bangladesh.tzinfo, pytz.timezone(bangladesh_timezone))

  # Which is (23 - 6 = 17) 17:59 UTC
  last_second_of_jan_2_bangladesh_utc = last_second_of_jan_2_bangladesh.astimezone(utc_tz)
  self.assertEqual(last_second_of_jan_2_bangladesh_utc.year, 2022)
  self.assertEqual(last_second_of_jan_2_bangladesh_utc.month, 1)
  self.assertEqual(last_second_of_jan_2_bangladesh_utc.day, 2)
  self.assertEqual(last_second_of_jan_2_bangladesh_utc.hour, 17)
  self.assertEqual(last_second_of_jan_2_bangladesh_utc.minute, 59)

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1121924

Just use datetime.time.min and datetime.time.max:

>>> import datetime
>>> datetime.time.min
datetime.time(0, 0)
>>> datetime.time.max
datetime.time(23, 59, 59, 999999)

You can combine that with a datetime.date instance to get a full datetime.datetime instance:

>>> datetime.datetime.combine(datetime.date.today(), datetime.time.max)
datetime.datetime(2012, 12, 1, 23, 59, 59, 999999)

To re-use an existing datetime.datetime instance, use the .combine() method together with the .date() method on the datetime.datetime instance to create a new datetime.datetime instance:

>>> datetime.datetime.combine(datetime.datetime.now().date(), datetime.time.min)
datetime.datetime(2012, 12, 1, 0, 0)

To get a series of dates, use datetime.timedelta instances to create offsets. A series of dates relative to today is then easy:

today = datetime.date.today()
lastweek = today - datetime.timedelta(days=7)
for i in range(7):
    aday = lastweek + datetime.timedelta(days=i)
    first = datetime.datetime.combine(aday, datetime.time.min)
    last = datetime.datetime.combine(aday, datetime.time.max)
    print first, last

Upvotes: 31

Related Questions