Issue 1:
Code Sample

>>> pd.to_datetime('2017-01-01T15:00:00-05:00')
... Timestamp('2017-01-01 20:00:00') # This is a timezone-naive Timestamp, but was converted to UTC

Problem description

Given a timezone-aware string (e.g., in ISO8601 format), pd.to_datetime converts the string to UTC time, but doesn't set the tzinfo to UTC.

This makes it difficult to differentiate between string that are truly timezone-naive strings (e.g., '2017-01-01') and timezone-aware strings (e.g., '2017-01-01T15:00:00-05:00').

Expected Output

Option 1: Convert the string to UTC (current behavior) and also set the timezone to UTC:

>>> pd.to_datetime('2017-01-01T15:00:00-05:00')
... Timestamp('2017-01-01 20:00:00+0000', tz='UTC')

Option 2: Don't convert to UTC and retain timezone. This is the behavior of dateutil.parser.parse:

>>> pd.to_datetime(parser.parse('2017-01-01T15:00:00-0500'))
... Timestamp('2017-01-01 15:00:00-0500', tz='tzoffset(None, -18000)')

Output of pd.show_versions()

INSTALLED VERSIONS
------------------
commit: None
python: 3.5.3.final.0
python-bits: 64
OS: Linux
OS-release: 4.1.35-pv-ts1
machine: x86_64
processor:
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.20.3

pytest: 3.1.2

pip: 9.0.1

setuptools: 27.2.0

Cython: 0.25.2

numpy: 1.12.1

scipy: 0.19.1

xarray: None

IPython: 6.1.0

sphinx: 1.6.2

patsy: 0.4.1

dateutil: 2.6.0

pytz: 2017.2

blosc: None

bottleneck: 1.2.1

tables: 3.3.0

numexpr: 2.6.2

feather: None

matplotlib: 2.0.2

openpyxl: 2.4.7

xlrd: 1.0.0

xlwt: None

xlsxwriter: 0.9.6

lxml: None

bs4: 4.6.0

html5lib: 0.999

sqlalchemy: 1.1.11

pymysql: None

psycopg2: None

jinja2: 2.9.6

s3fs: None

pandas_gbq: None

pandas_datareader: None

Issue 2:
Suppose you have an existing SQL table called person_age, where id is the primary key:

age
id
1	18
2	42

and you also have new data in a DataFrame called extra_data

age
id
2	44
3	95

then it would be useful to have an option on extra_data.to_sql() that allows to pass the DataFrame to SQL with an INSERT or UPDATE option on the rows, based on the primary key.

In this case, the id=2 row would get updated to age=44 and the id=3 row would get added

Expected Output

age
id
1	18
2	44
3	95

(Maybe) helpful code references

Use merge from SQLAlchemy?

The query: '''INSERT or REPLACE into person_age (id, age) values (?,?,?) ''' in this question

I looked at pandas sql.py sourcecode to come up with a solution, but I couldn't follow.

Code to replicate the example above

(Apologies for mixing sqlalchemy and sqlite

import pandas as pd
from sqlalchemy import create_engine
import sqlite3
conn = sqlite3.connect('example.db')

c = conn.cursor()
c.execute('''DROP TABLE IF EXISTS person_age;''')
c.execute('''
CREATE TABLE person_age
(id INTEGER PRIMARY KEY ASC, age INTEGER NOT NULL)
''')
conn.commit()
conn.close()

##### Create original table

engine = create_engine("sqlite:///example.db")
sql_df = pd.DataFrame({'id' : [1, 2], 'age' : [18, 42]})

sql_df.to_sql('person_age', engine, if_exists='append', index=False)

#### Extra data to insert/update

extra_data = pd.DataFrame({'id' : [2, 3], 'age' : [44, 95]})
extra_data.set_index('id', inplace=True)

#### extra_data.to_sql() with row update or insert option

expected_df = pd.DataFrame({'id': [1, 2, 3], 'age': [18, 44, 95]})
expected_df.set_index('id', inplace=True)