简体   繁体   中英

How can I get the timezone-aware year, month, day, hour etc. from a Python datetime?

I have been using datetimes from the datetime library in Python, and making them timezone aware with pytz. I have then been using them as dates in Pandas DataFrames and trying to use Pandas's apply function and the ".day", ".hour", ".minute" etc. methods of the datetimes to create columns with just the day, hour, or minute. Surprisingly, it gives the UTC values. Is there a way to return the local day, hour, or minute? Simply adding the offset is not good enough, because the offset to UTC changes with daylight savings time.

Many thanks!

Here is an example of what I am talking about:

import pandas as pd
import datetime as dt
import pytz

# Simply return the hour of a date
def get_hour(dt1): 
    return dt1.hour

# Create a date column to segment by month
# Create the date list
PST = pytz.timezone('US/Pacific')
start = PST.localize(dt.datetime(2016, 1, 1))
actuals_dates = [start + dt.timedelta(hours=x) for x in range(8760)]

# Outside of this context, you can get the hour
print ''
print 'Hour at the start date:'
print get_hour(start)
print ''

#add it to a pandas DataFrame as a column
shapes = pd.DataFrame()
shapes['actuals dates'] = actuals_dates

# create a column for the hour
shapes['actuals hour'] = shapes['actuals dates'].apply(get_hour)

# Print the first 24 hours
print shapes.head(24)

Will return:

Hour at the start date:
0

               actuals dates  actuals hour
0  2016-01-01 00:00:00-08:00             8
1  2016-01-01 01:00:00-08:00             9
2  2016-01-01 02:00:00-08:00            10
3  2016-01-01 03:00:00-08:00            11
4  2016-01-01 04:00:00-08:00            12
5  2016-01-01 05:00:00-08:00            13
6  2016-01-01 06:00:00-08:00            14
7  2016-01-01 07:00:00-08:00            15
8  2016-01-01 08:00:00-08:00            16
9  2016-01-01 09:00:00-08:00            17
10 2016-01-01 10:00:00-08:00            18
11 2016-01-01 11:00:00-08:00            19
12 2016-01-01 12:00:00-08:00            20
13 2016-01-01 13:00:00-08:00            21
14 2016-01-01 14:00:00-08:00            22
15 2016-01-01 15:00:00-08:00            23
16 2016-01-01 16:00:00-08:00             0
17 2016-01-01 17:00:00-08:00             1
18 2016-01-01 18:00:00-08:00             2
19 2016-01-01 19:00:00-08:00             3
20 2016-01-01 20:00:00-08:00             4
21 2016-01-01 21:00:00-08:00             5
22 2016-01-01 22:00:00-08:00             6
23 2016-01-01 23:00:00-08:00             7

Using a list comprehension seems to do the trick:

shapes['hour'] = [ts.hour for ts in shapes['actuals dates']]

shapes.head()
              actuals dates  actuals hour  hour
0 2016-01-01 00:00:00-08:00             8     0
1 2016-01-01 01:00:00-08:00             9     1
2 2016-01-01 02:00:00-08:00            10     2
3 2016-01-01 03:00:00-08:00            11     3
4 2016-01-01 04:00:00-08:00            12     4

Per the reminder from @Jeff, you can also use the dt accessor functions, eg:

>>> shapes['actuals dates'].dt.hour.head()
0    0
1    1
2    2
3    3
4    4
Name: actuals dates, dtype: int64

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM