title: How to convert this time series to UTC?
body: <p>My first time here : )</p>
  
  <p>I have following Pandas DataFrame</p>
  
  <pre class="lang-py prettyprint-override"><code>    date            time
  0   2018-03-24      23
  1   2018-03-24      24
  2   2018-03-25      1
  3   2018-03-25      2
  4   2018-03-25      3
  5   2018-03-25      4
  6   2018-03-25      5
  7   2018-03-25      6
  8   2018-03-25      7
  9   2018-03-25      8
  10  2018-03-25      9
  11  2018-03-25      10
  12  2018-03-25      11
  13  2018-03-25      12
  14  2018-03-25      13
  15  2018-03-25      14
  16  2018-03-25      15
  17  2018-03-25      16
  18  2018-03-25      17
  19  2018-03-25      18
  20  2018-03-25      19
  21  2018-03-25      20
  22  2018-03-25      21
  23  2018-03-25      22
  24  2018-03-25      23
  25  2018-03-26      1
  26  2018-03-26      2
  27  2018-03-26      3
  28  2018-03-26      4
  29  2018-03-26      5
  30  2018-03-26      6
  31  2018-10-27      23
  32  2018-10-27      24
  33  2018-10-28      1
  34  2018-10-28      2
  35  2018-10-28      3
  36  2018-10-28      4
  37  2018-10-28      5
  38  2018-10-28      6
  39  2018-10-28      7
  40  2018-10-28      8
  41  2018-10-28      9
  42  2018-10-28      10
  43  2018-10-28      11
  44  2018-10-28      12
  45  2018-10-28      13
  46  2018-10-28      14
  47  2018-10-28      15
  48  2018-10-28      16
  49  2018-10-28      17
  50  2018-10-28      18
  51  2018-10-28      19
  52  2018-10-28      20
  53  2018-10-28      21
  54  2018-10-28      22
  55  2018-10-28      23
  56  2018-10-28      24
  57  2018-10-28      25
  58  2018-10-29      1
  59  2018-10-29      2
  </code></pre>
  
  <p>Column <code>time</code> is supposed to represent hour of the day minus one, e.g. </p>
  
  <pre><code>    date            time
  2   2018-03-25      1 
  </code></pre>
  
  <p>is equal to <code>2018-03-25 00:00</code> Europe/London time.</p>
  
  <p>Device, which generates this time series data, is set to work according to <code>'Europe/London'</code> timezone, that's why 25th of March 2018 ends on 23rd hour (records <code>[2:25]</code>), and 28th of October 2018 ends of 25th hour (records <code>[33:58]</code>) (DST switch).</p>
  
  <p>Here is stuff I already tried:</p>
  
  <pre class="lang-py prettyprint-override"><code>from pytz import timezone
  tz = timezone("Europe/London")
  dst_switch = [dt for dt in tz._utc_transition_times if dt.year == 2018]
  dst_switch_date_range = pd.date_range(dst_switch[0],dst_switch[1], freq='h', tz='utc')
  
  df['datetime'] = pd.to_datetime(df.date) + pd.to_timedelta(df.time - 1, unit='h') 
  
  df['dt_utc']     = df['datetime'].dt.tz_localize('UTC')
  df['dst_switch'] = df['datetime'].map(lambda dt: 1 if dt in dst_switch_date_range else -1)
  df['dt_p']     = df['datetime'] + pd.to_timedelta(df['dst_switch'], unit='h')
  df['dt_utc_p'] = df['dt_p'].dt.tz_localize('Europe/London', ambiguous='NaT', nonexistent='NaT').dt.tz_convert('UTC')
  
  df[['date', 'time', 'dt', 'dt_utc', 'map','dt_p', 'dt_utc_p']]
  </code></pre>
  
  <p>which results in:</p>
  
  <pre><code>       date           time   dt                      dt_utc                       dst_switch     dt_p                    dt_utc_p
  0      2018-03-24     23     2018-03-24 23:00:00     2018-03-24 22:00:00+00:00     -1            2018-03-24 21:00:00     2018-03-24 21:00:00+00:00
  1      2018-03-24     24     2018-03-25 00:00:00     2018-03-24 23:00:00+00:00     -1            2018-03-24 22:00:00     2018-03-24 22:00:00+00:00
  2      2018-03-25     1      2018-03-25 01:00:00     2018-03-25 00:00:00+00:00     -1            2018-03-24 23:00:00     2018-03-24 23:00:00+00:00
  3      2018-03-25     2      2018-03-25 02:00:00     2018-03-25 01:00:00+00:00     1             2018-03-25 02:00:00     2018-03-25 01:00:00+00:00
  4      2018-03-25     3      2018-03-25 03:00:00     2018-03-25 02:00:00+00:00     1             2018-03-25 03:00:00     2018-03-25 02:00:00+00:00
  5      2018-03-25     4      2018-03-25 04:00:00     2018-03-25 03:00:00+00:00     1             2018-03-25 04:00:00     2018-03-25 03:00:00+00:00
  6      2018-03-25     5      2018-03-25 05:00:00     2018-03-25 04:00:00+00:00     1             2018-03-25 05:00:00     2018-03-25 04:00:00+00:00
  7      2018-03-25     6      2018-03-25 06:00:00     2018-03-25 05:00:00+00:00     1             2018-03-25 06:00:00     2018-03-25 05:00:00+00:00
  8      2018-03-25     7      2018-03-25 07:00:00     2018-03-25 06:00:00+00:00     1             2018-03-25 07:00:00     2018-03-25 06:00:00+00:00
  9      2018-03-25     8      2018-03-25 08:00:00     2018-03-25 07:00:00+00:00     1             2018-03-25 08:00:00     2018-03-25 07:00:00+00:00
  10     2018-03-25     9      2018-03-25 09:00:00     2018-03-25 08:00:00+00:00     1             2018-03-25 09:00:00     2018-03-25 08:00:00+00:00
  11     2018-03-25     10     2018-03-25 10:00:00     2018-03-25 09:00:00+00:00     1             2018-03-25 10:00:00     2018-03-25 09:00:00+00:00
  12     2018-03-25     11     2018-03-25 11:00:00     2018-03-25 10:00:00+00:00     1             2018-03-25 11:00:00     2018-03-25 10:00:00+00:00
  13     2018-03-25     12     2018-03-25 12:00:00     2018-03-25 11:00:00+00:00     1             2018-03-25 12:00:00     2018-03-25 11:00:00+00:00
  14     2018-03-25     13     2018-03-25 13:00:00     2018-03-25 12:00:00+00:00     1             2018-03-25 13:00:00     2018-03-25 12:00:00+00:00
  15     2018-03-25     14     2018-03-25 14:00:00     2018-03-25 13:00:00+00:00     1             2018-03-25 14:00:00     2018-03-25 13:00:00+00:00
  16     2018-03-25     15     2018-03-25 15:00:00     2018-03-25 14:00:00+00:00     1             2018-03-25 15:00:00     2018-03-25 14:00:00+00:00
  17     2018-03-25     16     2018-03-25 16:00:00     2018-03-25 15:00:00+00:00     1             2018-03-25 16:00:00     2018-03-25 15:00:00+00:00
  18     2018-03-25     17     2018-03-25 17:00:00     2018-03-25 16:00:00+00:00     1             2018-03-25 17:00:00     2018-03-25 16:00:00+00:00
  19     2018-03-25     18     2018-03-25 18:00:00     2018-03-25 17:00:00+00:00     1             2018-03-25 18:00:00     2018-03-25 17:00:00+00:00
  20     2018-03-25     19     2018-03-25 19:00:00     2018-03-25 18:00:00+00:00     1             2018-03-25 19:00:00     2018-03-25 18:00:00+00:00
  21     2018-03-25     20     2018-03-25 20:00:00     2018-03-25 19:00:00+00:00     1             2018-03-25 20:00:00     2018-03-25 19:00:00+00:00
  22     2018-03-25     21     2018-03-25 21:00:00     2018-03-25 20:00:00+00:00     1             2018-03-25 21:00:00     2018-03-25 20:00:00+00:00
  23     2018-03-25     22     2018-03-25 22:00:00     2018-03-25 21:00:00+00:00     1             2018-03-25 22:00:00     2018-03-25 21:00:00+00:00
  24     2018-03-25     23     2018-03-25 23:00:00     2018-03-25 22:00:00+00:00     1             2018-03-25 23:00:00     2018-03-25 22:00:00+00:00
  25     2018-03-26     1      2018-03-26 01:00:00     2018-03-26 00:00:00+00:00     1             2018-03-26 01:00:00     2018-03-26 00:00:00+00:00
  26     2018-03-26     2      2018-03-26 02:00:00     2018-03-26 01:00:00+00:00     1             2018-03-26 02:00:00     2018-03-26 01:00:00+00:00
  27     2018-03-26     3      2018-03-26 03:00:00     2018-03-26 02:00:00+00:00     1             2018-03-26 03:00:00     2018-03-26 02:00:00+00:00
  28     2018-03-26     4      2018-03-26 04:00:00     2018-03-26 03:00:00+00:00     1             2018-03-26 04:00:00     2018-03-26 03:00:00+00:00
  29     2018-03-26     5      2018-03-26 05:00:00     2018-03-26 04:00:00+00:00     1             2018-03-26 05:00:00     2018-03-26 04:00:00+00:00
  30     2018-03-26     6      2018-03-26 06:00:00     2018-03-26 05:00:00+00:00     1             2018-03-26 06:00:00     2018-03-26 05:00:00+00:00
  31     2018-10-27     23     2018-10-27 23:00:00     2018-10-27 22:00:00+00:00     1             2018-10-27 23:00:00     2018-10-27 22:00:00+00:00
  32     2018-10-27     24     2018-10-28 00:00:00     2018-10-27 23:00:00+00:00     1             2018-10-28 00:00:00     2018-10-27 23:00:00+00:00
  33     2018-10-28     1      2018-10-28 01:00:00     2018-10-28 00:00:00+00:00     1             2018-10-28 01:00:00     NaT
  34     2018-10-28     2      2018-10-28 02:00:00     2018-10-28 01:00:00+00:00     1             2018-10-28 02:00:00     2018-10-28 02:00:00+00:00
  35     2018-10-28     3      2018-10-28 03:00:00     2018-10-28 02:00:00+00:00     -1            2018-10-28 01:00:00     NaT
  36     2018-10-28     4      2018-10-28 04:00:00     2018-10-28 03:00:00+00:00     -1            2018-10-28 02:00:00     2018-10-28 02:00:00+00:00
  37     2018-10-28     5      2018-10-28 05:00:00     2018-10-28 04:00:00+00:00     -1            2018-10-28 03:00:00     2018-10-28 03:00:00+00:00
  38     2018-10-28     6      2018-10-28 06:00:00     2018-10-28 05:00:00+00:00     -1            2018-10-28 04:00:00     2018-10-28 04:00:00+00:00
  39     2018-10-28     7      2018-10-28 07:00:00     2018-10-28 06:00:00+00:00     -1            2018-10-28 05:00:00     2018-10-28 05:00:00+00:00
  40     2018-10-28     8      2018-10-28 08:00:00     2018-10-28 07:00:00+00:00     -1            2018-10-28 06:00:00     2018-10-28 06:00:00+00:00
  41     2018-10-28     9      2018-10-28 09:00:00     2018-10-28 08:00:00+00:00     -1            2018-10-28 07:00:00     2018-10-28 07:00:00+00:00
  42     2018-10-28     10     2018-10-28 10:00:00     2018-10-28 09:00:00+00:00     -1            2018-10-28 08:00:00     2018-10-28 08:00:00+00:00
  43     2018-10-28     11     2018-10-28 11:00:00     2018-10-28 10:00:00+00:00     -1            2018-10-28 09:00:00     2018-10-28 09:00:00+00:00
  44     2018-10-28     12     2018-10-28 12:00:00     2018-10-28 11:00:00+00:00     -1            2018-10-28 10:00:00     2018-10-28 10:00:00+00:00
  45     2018-10-28     13     2018-10-28 13:00:00     2018-10-28 12:00:00+00:00     -1            2018-10-28 11:00:00     2018-10-28 11:00:00+00:00
  46     2018-10-28     14     2018-10-28 14:00:00     2018-10-28 13:00:00+00:00     -1            2018-10-28 12:00:00     2018-10-28 12:00:00+00:00
  47     2018-10-28     15     2018-10-28 15:00:00     2018-10-28 14:00:00+00:00     -1            2018-10-28 13:00:00     2018-10-28 13:00:00+00:00
  48     2018-10-28     16     2018-10-28 16:00:00     2018-10-28 15:00:00+00:00     -1            2018-10-28 14:00:00     2018-10-28 14:00:00+00:00
  49     2018-10-28     17     2018-10-28 17:00:00     2018-10-28 16:00:00+00:00     -1            2018-10-28 15:00:00     2018-10-28 15:00:00+00:00
  50     2018-10-28     18     2018-10-28 18:00:00     2018-10-28 17:00:00+00:00     -1            2018-10-28 16:00:00     2018-10-28 16:00:00+00:00
  51     2018-10-28     19     2018-10-28 19:00:00     2018-10-28 18:00:00+00:00     -1            2018-10-28 17:00:00     2018-10-28 17:00:00+00:00
  52     2018-10-28     20     2018-10-28 20:00:00     2018-10-28 19:00:00+00:00     -1            2018-10-28 18:00:00     2018-10-28 18:00:00+00:00
  53     2018-10-28     21     2018-10-28 21:00:00     2018-10-28 20:00:00+00:00     -1            2018-10-28 19:00:00     2018-10-28 19:00:00+00:00
  54     2018-10-28     22     2018-10-28 22:00:00     2018-10-28 21:00:00+00:00     -1            2018-10-28 20:00:00     2018-10-28 20:00:00+00:00
  55     2018-10-28     23     2018-10-28 23:00:00     2018-10-28 22:00:00+00:00     -1            2018-10-28 21:00:00     2018-10-28 21:00:00+00:00
  56     2018-10-28     24     2018-10-29 00:00:00     2018-10-28 23:00:00+00:00     -1            2018-10-28 22:00:00     2018-10-28 22:00:00+00:00
  57     2018-10-28     25     2018-10-29 01:00:00     2018-10-29 00:00:00+00:00     -1            2018-10-28 23:00:00     2018-10-28 23:00:00+00:00
  58     2018-10-29     1      2018-10-29 01:00:00     2018-10-29 00:00:00+00:00     -1            2018-10-28 23:00:00     2018-10-28 23:00:00+00:00
  59     2018-10-29     2      2018-10-29 02:00:00     2018-10-29 01:00:00+00:00     -1            2018-10-29 00:00:00     2018-10-29 00:00:00+00:00
  </code></pre>
  
  <p><strong>What I need</strong>: I need to combine these two columns into datetime column, and then convert timezone from <code>'Europe/London'</code> to <code>'UTC'</code> (or other way around: adjust values in <code>time</code> column to fit <code>'UTC'</code> and then combine with <code>date</code> column)</p>
  
  <p><strong>My line of logic</strong>: 1 year has 24h*365days = 8760 hours. If I take above timeseries data for whole year, I should get 363 days with 24 records each, 1 day with 23 records, and 1 day with 25 records, total of 8712 + 23 + 25 = 8760 records, ergo, one record for each hour of time during the year.</p>
  
  <p><strong>Where I fail</strong>: translating my logic to code :P. I have no good idea on how to offset these dates so everything will make sense, meaning smooth transitions between DST switch dates, and no duplicate timeseries values, nor missing values (holes) in timeseries.</p>
  
  <p><strong>Expected result</strong>:</p>
  
  <pre><code>    date           time   dt_utc                   
  0   2018-03-24     23     2018-03-24 22:00:00+00:00
  1   2018-03-24     24     2018-03-24 23:00:00+00:00
  2   2018-03-25     1      2018-03-25 00:00:00+00:00
  3   2018-03-25     2      2018-03-25 01:00:00+00:00
  4   2018-03-25     3      2018-03-25 02:00:00+00:00
  5   2018-03-25     4      2018-03-25 03:00:00+00:00
  6   2018-03-25     5      2018-03-25 04:00:00+00:00
  7   2018-03-25     6      2018-03-25 05:00:00+00:00
  8   2018-03-25     7      2018-03-25 06:00:00+00:00
  9   2018-03-25     8      2018-03-25 07:00:00+00:00
  10  2018-03-25     9      2018-03-25 08:00:00+00:00
  11  2018-03-25     10     2018-03-25 09:00:00+00:00
  12  2018-03-25     11     2018-03-25 10:00:00+00:00
  13  2018-03-25     12     2018-03-25 11:00:00+00:00
  14  2018-03-25     13     2018-03-25 12:00:00+00:00
  15  2018-03-25     14     2018-03-25 13:00:00+00:00
  16  2018-03-25     15     2018-03-25 14:00:00+00:00
  17  2018-03-25     16     2018-03-25 15:00:00+00:00
  18  2018-03-25     17     2018-03-25 16:00:00+00:00
  19  2018-03-25     18     2018-03-25 17:00:00+00:00
  20  2018-03-25     19     2018-03-25 18:00:00+00:00
  21  2018-03-25     20     2018-03-25 19:00:00+00:00
  22  2018-03-25     21     2018-03-25 20:00:00+00:00
  23  2018-03-25     22     2018-03-25 21:00:00+00:00
  24  2018-03-25     23     2018-03-25 22:00:00+00:00
  25  2018-03-26     1      2018-03-25 23:00:00+00:00
  26  2018-03-26     2      2018-03-26 00:00:00+00:00
  27  2018-03-26     3      2018-03-26 01:00:00+00:00
  28  2018-03-26     4      2018-03-26 02:00:00+00:00
  29  2018-03-26     5      2018-03-26 03:00:00+00:00
  30  2018-03-26     6      2018-03-26 04:00:00+00:00
  31  2018-10-27     23     2018-10-27 21:00:00+00:00
  32  2018-10-27     24     2018-10-27 22:00:00+00:00
  33  2018-10-28     1      2018-10-27 23:00:00+00:00
  34  2018-10-28     2      2018-10-28 00:00:00+00:00
  35  2018-10-28     3      2018-10-28 01:00:00+00:00
  36  2018-10-28     4      2018-10-28 02:00:00+00:00
  37  2018-10-28     5      2018-10-28 03:00:00+00:00
  38  2018-10-28     6      2018-10-28 04:00:00+00:00
  39  2018-10-28     7      2018-10-28 05:00:00+00:00
  40  2018-10-28     8      2018-10-28 06:00:00+00:00
  41  2018-10-28     9      2018-10-28 07:00:00+00:00
  42  2018-10-28     10     2018-10-28 08:00:00+00:00
  43  2018-10-28     11     2018-10-28 09:00:00+00:00
  44  2018-10-28     12     2018-10-28 10:00:00+00:00
  45  2018-10-28     13     2018-10-28 11:00:00+00:00
  46  2018-10-28     14     2018-10-28 12:00:00+00:00
  47  2018-10-28     15     2018-10-28 13:00:00+00:00
  48  2018-10-28     16     2018-10-28 14:00:00+00:00
  49  2018-10-28     17     2018-10-28 15:00:00+00:00
  50  2018-10-28     18     2018-10-28 16:00:00+00:00
  51  2018-10-28     19     2018-10-28 17:00:00+00:00
  52  2018-10-28     20     2018-10-28 18:00:00+00:00
  53  2018-10-28     21     2018-10-28 19:00:00+00:00
  54  2018-10-28     22     2018-10-28 20:00:00+00:00
  55  2018-10-28     23     2018-10-28 21:00:00+00:00
  56  2018-10-28     24     2018-10-28 22:00:00+00:00
  57  2018-10-28     25     2018-10-28 23:00:00+00:00
  58  2018-10-29     1      2018-10-29 00:00:00+00:00
  59  2018-10-29     2      2018-10-29 01:00:00+00:00
  </code></pre>
  
  <p>Please help :)</p>