Skip to content

add try / except to address issue #10154 to_datetime, Inconsistent be… #10216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion pandas/tests/test_tseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import nose
from numpy import nan
import numpy as np
from pandas import Index, isnull, Timestamp
from pandas import Index, isnull, Timestamp, to_datetime, NaT
from pandas.util.testing import assert_almost_equal
import pandas.util.testing as tm
from pandas.compat import range, lrange, zip
Expand Down Expand Up @@ -737,6 +737,17 @@ def test_get_period_field_raises_on_out_of_range(self):
def test_get_period_field_array_raises_on_out_of_range(self):
self.assertRaises(ValueError, period.get_period_field_arr, -1, np.empty(1), 0)

class TestDaysInMonth(tm.TestCase):
def test_day_not_in_month_coerce_true(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls add the issue number as a comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I did, not sure what went wrong.

self.assertTrue(isnull(to_datetime('2015-02-29', coerce=True)))
self.assertTrue(isnull(to_datetime('2015-02-29', format="%Y-%m-%d", coerce=True)))
self.assertTrue(isnull(to_datetime('2015-02-32', format="%Y-%m-%d", coerce=True)))
self.assertTrue(isnull(to_datetime('2015-04-31', format="%Y-%m-%d", coerce=True)))
def test_day_not_in_month_coerce_false(self):
self.assertRaises(ValueError, to_datetime, '2015-02-29', format="%Y-%m-%d", coerce=False)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeh, test both errors='ignore' and errors='raise' here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks correct

In [10]: pd.to_datetime('2015-02-29', errors='ignore',  coerce=False)
Out[10]: '2015-02-29'

I would expect the same from this but get a ValueError.

In [12]: pd.to_datetime('2015-02-29', errors='ignore', format="%Y-%m-%d", coerce=False)
....
ValueError: day is out of range for month

adding format="%Y-%m-%d" should not change the output.
Is this correct and also needs to be fixed?

self.assertRaises(ValueError, to_datetime, '2015-02-32', format="%Y-%m-%d", coerce=False)
self.assertRaises(ValueError, to_datetime, '2015-04-31', format="%Y-%m-%d", coerce=False)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add off these cases again, but with coerce=False (and assert that they raise ValueError)

if __name__ == '__main__':
import nose
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
Expand Down
29 changes: 18 additions & 11 deletions pandas/tslib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2483,17 +2483,24 @@ def array_strptime(ndarray[object] values, object fmt, bint exact=True, bint coe
# Cannot pre-calculate datetime_date() since can change in Julian
# calculation and thus could have different value for the day of the wk
# calculation.
if julian == -1:
# Need to add 1 to result since first day of the year is 1, not 0.
julian = datetime_date(year, month, day).toordinal() - \
datetime_date(year, 1, 1).toordinal() + 1
else: # Assume that if they bothered to include Julian day it will
# be accurate.
datetime_result = datetime_date.fromordinal(
(julian - 1) + datetime_date(year, 1, 1).toordinal())
year = datetime_result.year
month = datetime_result.month
day = datetime_result.day
try:
if julian == -1:
# Need to add 1 to result since first day of the year is 1, not 0.
julian = datetime_date(year, month, day).toordinal() - \
datetime_date(year, 1, 1).toordinal() + 1

else: # Assume that if they bothered to include Julian day it will
# be accurate.
datetime_result = datetime_date.fromordinal(
(julian - 1) + datetime_date(year, 1, 1).toordinal())
year = datetime_result.year
month = datetime_result.month
day = datetime_result.day
except ValueError:
if coerce:
iresult[i] = iNaT
continue
raise
if weekday == -1:
weekday = datetime_date(year, month, day).weekday()

Expand Down