10

Is there a simple way to obtain the hour of the year from a datetime?

dt = datetime(2019, 1, 3, 00, 00, 00) # 03/01/2019 00:00
dt_hour = dt.hour_of_year() # should be something like that

Expected output: dt_hour = 48

It would be nice as well to obtain minutes_of_year and seconds_of_year

ironzionlion
  • 832
  • 1
  • 7
  • 28
  • 3
    you could get the seconds like this `dt.timestamp() - datetime(dt.year,1,1).timestamp()` and simply divide it by 60 to get minutes and divide again by 60 to get hours – luigigi Aug 25 '20 at 11:03
  • The following shows how to obtain minutes: https://stackoverflow.com/questions/12155908/convert-datetime-since-a-given-date-to-minutes – Ruthger Righart Aug 25 '20 at 11:03

5 Answers5

3

One way of implementing this yourself is this:

def hour_of_year(dt): 
    beginning_of_year = datetime.datetime(dt.year, 1, 1, tzinfo=dt.tzinfo)
    return (dt - beginning_of_year).total_seconds() // 3600

This first creates a new datetime object representing the beginning of the year. We then compute the time since the beginning of the year in seconds, divide by 3600 and take the integer part to get the full hours that have passed since the beginning of the year.

Note that using the days attribute of the timedelta object will only return the number of full days since the beginning of the year.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 1
    This works regardless of where `tzinfo` comes from – it simply passes the same timezone on to the `beginning_of_year` object. – Sven Marnach Aug 25 '20 at 11:38
  • Answer accepted. I am however surprised no built-in method exists – ironzionlion Aug 28 '20 at 13:24
  • @ironzionlion Is there _any_ programming languange whith this function in the standard library? It doesn't seem particularly common to ask for the number of hours that have passed since the beginning of the year. – Sven Marnach Aug 28 '20 at 14:51
  • I am using a simulation program based in C and it has it. I find it extremely helpful while working with datetime values – ironzionlion Sep 01 '20 at 06:11
2

You can use timedelta:

import datetime
dt = datetime.datetime(2019, 1, 3, 00, 00, 00)
dt2 = datetime.datetime(2019, 1, 1, 00, 00, 00)
print((dt-dt2).days*24)

output:

48
Mehdi Mostafavi
  • 880
  • 1
  • 12
  • 25
  • 1
    This only takes into account full days, and throws away the time of day. Moreover, it doesn't work correctly for `datetime` objects with a timezone attached. – Sven Marnach Aug 25 '20 at 11:39
1

All three functions, reusing their code.

import datetime

def minutes_of_year(dt):
    return seconds_of_year(dt) // 60

def hours_of_year(dt):
    return minutes_of_year(dt) // 60

def seconds_of_year(dt):
    dt0 = datetime.datetime(dt.year, 1, 1, tzinfo=dt.tzinfo)
    delta = dt-dt0
    return int(delta.total_seconds())

Edited to take possible time zone info into account.

Or: subclass datetime, for easier reuse in later projects:

import datetime

class MyDateTime(datetime.datetime):
    def __new__(cls, *args, **kwargs):
        return datetime.datetime.__new__(cls, *args, **kwargs)

    def minutes_of_year(self):
        return self.seconds_of_year() // 60

    def hours_of_year(self):
        return self.minutes_of_year() // 60

    def seconds_of_year(self):
        dt0 = datetime.datetime(self.year, 1, 1, tzinfo=self.tzinfo)
        delta = self-dt0
        return int(delta.total_seconds())

# create and use like a normal datetime object
dt = MyDateTime.now()
# properties and functions of datetime still available, of course.
print(dt.day)
# ... and new methods:
print(dt.hours_of_year())
Wups
  • 2,489
  • 1
  • 6
  • 17
0

You can write a custom function

def get_time_of_year(dt, type = 'hours_of_year'):
  intitial_date = datetime(dt.year, 1,1, 00, 00, 00) 
  duration = dt - intitial_date

  days, seconds = duration.days, duration.seconds
  hours = days * 24 + seconds // 3600
  minutes = (seconds % 3600) // 60

  if type == 'hours_of_year':
    return hours
  if type == 'days_of_year':
    return days
  if type == 'seconds_of_year':
    return seconds
  if type == 'minuts_of_year':
    return minutes

test function

get_time_of_year(dt, 'hours_of_year')
#>>48
Suryaveer Singh
  • 577
  • 2
  • 13
0

I have the dataframe DF that has the column 'Timestamp' with type datetime64[ns].
The column timestamp looks like this:

DF['Timestamp']:
0      2022-01-01 00:00:00
1      2022-01-01 01:00:00
2      2022-01-01 02:00:00
3      2022-01-01 03:00:00
4      2022-01-01 04:00:00
...       
8755   2022-12-31 19:00:00
8756   2022-12-31 20:00:00
8757   2022-12-31 21:00:00
8758   2022-12-31 22:00:00
8759   2022-12-31 23:00:00
Name: Timestamp, Length: 8760, dtype: datetime64[ns]

I extract 'Hour of Year' in this way:

DF['Year']       = DF['Timestamp'].astype('M8[Y]')
DF['DayOfYear']  = (DF['Timestamp'] - DF['Year']).astype('timedelta64[D]')
DF['Hour']       = DF['Timestamp'].dt.hour + 1 
DF['HourOfYear'] = DF['DayOfYear'] * 24 + DF['Hour']

First it extracts the year from the Timestamp.
Next it creates a time delta from beginning of the year to that Timestamp based on days (in other words, day of year).
Then it extracts the hour from the timestamp.
Finally it calculates the hour of the year with that formula.

And it looks like this in the end:

DF:
               Timestamp  ...  HourOfYear
0    2022-01-01 00:00:00  ...  1.0
1    2022-01-01 01:00:00  ...  2.0
2    2022-01-01 02:00:00  ...  3.0
3    2022-01-01 03:00:00  ...  4.0
4    2022-01-01 04:00:00  ...  5.0
...      
8755 2022-12-31 19:00:00  ...  8756.0
8756 2022-12-31 20:00:00  ...  8757.0
8757 2022-12-31 21:00:00  ...  8758.0
8758 2022-12-31 22:00:00  ...  8759.0
8759 2022-12-31 23:00:00  ...  8760.0
[8760 rows x 6columns]
PM0087
  • 123
  • 1
  • 9