|
| 1 | +.. _timetimezones: |
| 2 | + |
| 3 | +Time and time zones |
| 4 | +=================== |
| 5 | + |
| 6 | +Dealing with time and time zones can be a frustrating experience in any |
| 7 | +programming language and for any application. pvlib relies on :py:mod:`pandas` |
| 8 | +and |
| 9 | +pytz to handle time and time zones. Therefore, the vast majority of the |
| 10 | +information in this document applies to any time series analysis using |
| 11 | +pandas and is not specific to pvlib-python. |
| 12 | + |
| 13 | +pvlib makes extensive use of pandas due to its excellent time series |
| 14 | +functionality. Take the time to become familiar with pandas' `Time |
| 15 | +Series / Date functionality page |
| 16 | +<http://pandas.pydata.org/pandas-docs/version/0.18.0/timeseries.html>`_. |
| 17 | +It is also worthwhile to become familiar with pure Python's |
| 18 | +:py:mod:`python:datetime` module, although we typically recommend |
| 19 | +using the corresponding pandas functionality where it exists. |
| 20 | + |
| 21 | +.. ipython:: python |
| 22 | +
|
| 23 | + import datetime |
| 24 | + import numpy as np |
| 25 | + import pandas as pd |
| 26 | + import pytz |
| 27 | +
|
| 28 | +You can obtain a list of all valid time zone strings with |
| 29 | +pytz.all_timezones. Here, we print only every 20th time zone. |
| 30 | + |
| 31 | +.. ipython:: python |
| 32 | +
|
| 33 | + len(pytz.all_timezones) |
| 34 | + pytz.all_timezones[::20] |
| 35 | +
|
| 36 | +:py:class:`pandas.Timestamp`'s and :py:class:`pandas.DatetimeIndex`'s |
| 37 | +can be created in many ways. Here |
| 38 | +we focus on the time zone issues surrounding them; see the pandas |
| 39 | +documentation for more information. |
| 40 | + |
| 41 | +First, create a time zone naive pandas.Timestamp. |
| 42 | + |
| 43 | +.. ipython:: python |
| 44 | +
|
| 45 | + pd.Timestamp('2015-1-1 00:00') |
| 46 | +
|
| 47 | +You can specify the time zone using the tz keyword argument or |
| 48 | +the tz_localize method of Timestamp |
| 49 | +and DatetimeIndex objects. |
| 50 | + |
| 51 | +.. ipython:: python |
| 52 | +
|
| 53 | + pd.Timestamp('2015-1-1 00:00', tz='America/Denver') |
| 54 | + pd.Timestamp('2015-1-1 00:00').tz_localize('America/Denver') |
| 55 | +
|
| 56 | +Some time zones are aware of daylight savings time and some are not. For |
| 57 | +example the winter time results are the same for US/Mountain and MST, |
| 58 | +but the summer time results are not. |
| 59 | + |
| 60 | +Note the UTC offset in winter... |
| 61 | + |
| 62 | +.. ipython:: python |
| 63 | +
|
| 64 | + pd.Timestamp('2015-1-1 00:00').tz_localize('US/Mountain') |
| 65 | + pd.Timestamp('2015-1-1 00:00').tz_localize('MST') |
| 66 | +
|
| 67 | +vs. the UTC offset in summer... |
| 68 | + |
| 69 | +.. ipython:: python |
| 70 | +
|
| 71 | + pd.Timestamp('2015-6-1 00:00').tz_localize('US/Mountain') |
| 72 | + pd.Timestamp('2015-6-1 00:00').tz_localize('MST') |
| 73 | +
|
| 74 | +pandas and pytz make this time zone handling possible because pandas |
| 75 | +stores all times as integer nanoseconds since January 1, 1970. |
| 76 | +Here is the pandas time representation of the integer 1. |
| 77 | + |
| 78 | +.. ipython:: python |
| 79 | +
|
| 80 | + pd.Timestamp(1) |
| 81 | +
|
| 82 | +So if we specify times consistent with the specified time zone, pandas |
| 83 | +will use the same integer to represent them. |
| 84 | + |
| 85 | + |
| 86 | +.. ipython:: python |
| 87 | +
|
| 88 | + # US/Mountain |
| 89 | + pd.Timestamp('2015-6-1 01:00').tz_localize('US/Mountain').value |
| 90 | +
|
| 91 | + # MST |
| 92 | + pd.Timestamp('2015-6-1 00:00').tz_localize('MST').value |
| 93 | +
|
| 94 | + # UTC |
| 95 | + pd.Timestamp('2015-6-1 07:00').tz_localize('UTC').value |
| 96 | +
|
| 97 | + # UTC |
| 98 | + pd.Timestamp('2015-6-1 07:00').value |
| 99 | +
|
| 100 | +As stated above, pandas will assume UTC if you do not specify a time |
| 101 | +zone. This is dangerous, and we always recommend using using localized |
| 102 | +timeseries, even if it is UTC. |
| 103 | + |
| 104 | +Timezones can also be specified with a fixed offset in minutes from UTC. |
| 105 | + |
| 106 | +.. ipython:: python |
| 107 | +
|
| 108 | + pd.Timestamp('2015-1-1 00:00').tz_localize(pytz.FixedOffset(120)) |
| 109 | +
|
| 110 | +You can also specify the fixed offset directly in the tz_localize |
| 111 | +method, however, be aware that this is not documented and that the |
| 112 | +offset must be in seconds, not minutes. |
| 113 | + |
| 114 | +.. ipython:: python |
| 115 | +
|
| 116 | + pd.Timestamp('2015-1-1 00:00').tz_localize(7200) |
| 117 | +
|
| 118 | +Yet another way to specify a time zone with a fixed offset is by using |
| 119 | +the string formulation. |
| 120 | + |
| 121 | +.. ipython:: python |
| 122 | +
|
| 123 | + pd.Timestamp('2015-1-1 00:00+0200') |
| 124 | +
|
| 125 | +pandas time objects can also be created from time zone aware or naive |
| 126 | +datetime.date or datetime.datetime objects. The behavior is generally as |
| 127 | +expected. |
| 128 | + |
| 129 | +.. ipython:: python |
| 130 | +
|
| 131 | + # tz naive |
| 132 | + pd.Timestamp(datetime.datetime(2015,6,1,0)) |
| 133 | +
|
| 134 | + # start is tz aware python datetime object |
| 135 | + start = pytz.timezone('US/Mountain').localize(datetime.datetime(2015, 6, 1, 0)) |
| 136 | + pd.Timestamp(start) |
| 137 | +
|
0 commit comments