test_timestamp.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. """ test the scalar Timestamp """
  2. import calendar
  3. from datetime import datetime, timedelta
  4. import locale
  5. import unicodedata
  6. import dateutil
  7. from dateutil.tz import tzutc
  8. import numpy as np
  9. import pytest
  10. import pytz
  11. from pytz import timezone, utc
  12. from pandas._libs.tslibs import conversion
  13. from pandas._libs.tslibs.timezones import dateutil_gettz as gettz, get_timezone
  14. from pandas.compat import PY2, PY3, long
  15. from pandas.compat.numpy import np_datetime64_compat
  16. from pandas.errors import OutOfBoundsDatetime
  17. import pandas.util._test_decorators as td
  18. from pandas import NaT, Period, Timedelta, Timestamp
  19. import pandas.util.testing as tm
  20. from pandas.tseries import offsets
  21. class TestTimestampProperties(object):
  22. def test_properties_business(self):
  23. ts = Timestamp('2017-10-01', freq='B')
  24. control = Timestamp('2017-10-01')
  25. assert ts.dayofweek == 6
  26. assert not ts.is_month_start # not a weekday
  27. assert not ts.is_quarter_start # not a weekday
  28. # Control case: non-business is month/qtr start
  29. assert control.is_month_start
  30. assert control.is_quarter_start
  31. ts = Timestamp('2017-09-30', freq='B')
  32. control = Timestamp('2017-09-30')
  33. assert ts.dayofweek == 5
  34. assert not ts.is_month_end # not a weekday
  35. assert not ts.is_quarter_end # not a weekday
  36. # Control case: non-business is month/qtr start
  37. assert control.is_month_end
  38. assert control.is_quarter_end
  39. def test_fields(self):
  40. def check(value, equal):
  41. # that we are int/long like
  42. assert isinstance(value, (int, long))
  43. assert value == equal
  44. # GH 10050
  45. ts = Timestamp('2015-05-10 09:06:03.000100001')
  46. check(ts.year, 2015)
  47. check(ts.month, 5)
  48. check(ts.day, 10)
  49. check(ts.hour, 9)
  50. check(ts.minute, 6)
  51. check(ts.second, 3)
  52. pytest.raises(AttributeError, lambda: ts.millisecond)
  53. check(ts.microsecond, 100)
  54. check(ts.nanosecond, 1)
  55. check(ts.dayofweek, 6)
  56. check(ts.quarter, 2)
  57. check(ts.dayofyear, 130)
  58. check(ts.week, 19)
  59. check(ts.daysinmonth, 31)
  60. check(ts.daysinmonth, 31)
  61. # GH 13303
  62. ts = Timestamp('2014-12-31 23:59:00-05:00', tz='US/Eastern')
  63. check(ts.year, 2014)
  64. check(ts.month, 12)
  65. check(ts.day, 31)
  66. check(ts.hour, 23)
  67. check(ts.minute, 59)
  68. check(ts.second, 0)
  69. pytest.raises(AttributeError, lambda: ts.millisecond)
  70. check(ts.microsecond, 0)
  71. check(ts.nanosecond, 0)
  72. check(ts.dayofweek, 2)
  73. check(ts.quarter, 4)
  74. check(ts.dayofyear, 365)
  75. check(ts.week, 1)
  76. check(ts.daysinmonth, 31)
  77. ts = Timestamp('2014-01-01 00:00:00+01:00')
  78. starts = ['is_month_start', 'is_quarter_start', 'is_year_start']
  79. for start in starts:
  80. assert getattr(ts, start)
  81. ts = Timestamp('2014-12-31 23:59:59+01:00')
  82. ends = ['is_month_end', 'is_year_end', 'is_quarter_end']
  83. for end in ends:
  84. assert getattr(ts, end)
  85. # GH 12806
  86. @pytest.mark.parametrize('data',
  87. [Timestamp('2017-08-28 23:00:00'),
  88. Timestamp('2017-08-28 23:00:00', tz='EST')])
  89. @pytest.mark.parametrize('time_locale', [
  90. None] if tm.get_locales() is None else [None] + tm.get_locales())
  91. def test_names(self, data, time_locale):
  92. # GH 17354
  93. # Test .weekday_name, .day_name(), .month_name
  94. with tm.assert_produces_warning(FutureWarning,
  95. check_stacklevel=False):
  96. assert data.weekday_name == 'Monday'
  97. if time_locale is None:
  98. expected_day = 'Monday'
  99. expected_month = 'August'
  100. else:
  101. with tm.set_locale(time_locale, locale.LC_TIME):
  102. expected_day = calendar.day_name[0].capitalize()
  103. expected_month = calendar.month_name[8].capitalize()
  104. result_day = data.day_name(time_locale)
  105. result_month = data.month_name(time_locale)
  106. # Work around https://github.com/pandas-dev/pandas/issues/22342
  107. # different normalizations
  108. if not PY2:
  109. expected_day = unicodedata.normalize("NFD", expected_day)
  110. expected_month = unicodedata.normalize("NFD", expected_month)
  111. result_day = unicodedata.normalize("NFD", result_day,)
  112. result_month = unicodedata.normalize("NFD", result_month)
  113. assert result_day == expected_day
  114. assert result_month == expected_month
  115. # Test NaT
  116. nan_ts = Timestamp(NaT)
  117. assert np.isnan(nan_ts.day_name(time_locale))
  118. assert np.isnan(nan_ts.month_name(time_locale))
  119. def test_is_leap_year(self, tz_naive_fixture):
  120. tz = tz_naive_fixture
  121. # GH 13727
  122. dt = Timestamp('2000-01-01 00:00:00', tz=tz)
  123. assert dt.is_leap_year
  124. assert isinstance(dt.is_leap_year, bool)
  125. dt = Timestamp('1999-01-01 00:00:00', tz=tz)
  126. assert not dt.is_leap_year
  127. dt = Timestamp('2004-01-01 00:00:00', tz=tz)
  128. assert dt.is_leap_year
  129. dt = Timestamp('2100-01-01 00:00:00', tz=tz)
  130. assert not dt.is_leap_year
  131. def test_woy_boundary(self):
  132. # make sure weeks at year boundaries are correct
  133. d = datetime(2013, 12, 31)
  134. result = Timestamp(d).week
  135. expected = 1 # ISO standard
  136. assert result == expected
  137. d = datetime(2008, 12, 28)
  138. result = Timestamp(d).week
  139. expected = 52 # ISO standard
  140. assert result == expected
  141. d = datetime(2009, 12, 31)
  142. result = Timestamp(d).week
  143. expected = 53 # ISO standard
  144. assert result == expected
  145. d = datetime(2010, 1, 1)
  146. result = Timestamp(d).week
  147. expected = 53 # ISO standard
  148. assert result == expected
  149. d = datetime(2010, 1, 3)
  150. result = Timestamp(d).week
  151. expected = 53 # ISO standard
  152. assert result == expected
  153. result = np.array([Timestamp(datetime(*args)).week
  154. for args in [(2000, 1, 1), (2000, 1, 2), (
  155. 2005, 1, 1), (2005, 1, 2)]])
  156. assert (result == [52, 52, 53, 53]).all()
  157. def test_resolution(self):
  158. # GH#21336, GH#21365
  159. dt = Timestamp('2100-01-01 00:00:00')
  160. assert dt.resolution == Timedelta(nanoseconds=1)
  161. class TestTimestampConstructors(object):
  162. def test_constructor(self):
  163. base_str = '2014-07-01 09:00'
  164. base_dt = datetime(2014, 7, 1, 9)
  165. base_expected = 1404205200000000000
  166. # confirm base representation is correct
  167. import calendar
  168. assert (calendar.timegm(base_dt.timetuple()) * 1000000000 ==
  169. base_expected)
  170. tests = [(base_str, base_dt, base_expected),
  171. ('2014-07-01 10:00', datetime(2014, 7, 1, 10),
  172. base_expected + 3600 * 1000000000),
  173. ('2014-07-01 09:00:00.000008000',
  174. datetime(2014, 7, 1, 9, 0, 0, 8),
  175. base_expected + 8000),
  176. ('2014-07-01 09:00:00.000000005',
  177. Timestamp('2014-07-01 09:00:00.000000005'),
  178. base_expected + 5)]
  179. timezones = [(None, 0), ('UTC', 0), (pytz.utc, 0), ('Asia/Tokyo', 9),
  180. ('US/Eastern', -4), ('dateutil/US/Pacific', -7),
  181. (pytz.FixedOffset(-180), -3),
  182. (dateutil.tz.tzoffset(None, 18000), 5)]
  183. for date_str, date, expected in tests:
  184. for result in [Timestamp(date_str), Timestamp(date)]:
  185. # only with timestring
  186. assert result.value == expected
  187. assert conversion.pydt_to_i8(result) == expected
  188. # re-creation shouldn't affect to internal value
  189. result = Timestamp(result)
  190. assert result.value == expected
  191. assert conversion.pydt_to_i8(result) == expected
  192. # with timezone
  193. for tz, offset in timezones:
  194. for result in [Timestamp(date_str, tz=tz), Timestamp(date,
  195. tz=tz)]:
  196. expected_tz = expected - offset * 3600 * 1000000000
  197. assert result.value == expected_tz
  198. assert conversion.pydt_to_i8(result) == expected_tz
  199. # should preserve tz
  200. result = Timestamp(result)
  201. assert result.value == expected_tz
  202. assert conversion.pydt_to_i8(result) == expected_tz
  203. # should convert to UTC
  204. if tz is not None:
  205. result = Timestamp(result).tz_convert('UTC')
  206. else:
  207. result = Timestamp(result, tz='UTC')
  208. expected_utc = expected - offset * 3600 * 1000000000
  209. assert result.value == expected_utc
  210. assert conversion.pydt_to_i8(result) == expected_utc
  211. def test_constructor_with_stringoffset(self):
  212. # GH 7833
  213. base_str = '2014-07-01 11:00:00+02:00'
  214. base_dt = datetime(2014, 7, 1, 9)
  215. base_expected = 1404205200000000000
  216. # confirm base representation is correct
  217. import calendar
  218. assert (calendar.timegm(base_dt.timetuple()) * 1000000000 ==
  219. base_expected)
  220. tests = [(base_str, base_expected),
  221. ('2014-07-01 12:00:00+02:00',
  222. base_expected + 3600 * 1000000000),
  223. ('2014-07-01 11:00:00.000008000+02:00', base_expected + 8000),
  224. ('2014-07-01 11:00:00.000000005+02:00', base_expected + 5)]
  225. timezones = [(None, 0), ('UTC', 0), (pytz.utc, 0), ('Asia/Tokyo', 9),
  226. ('US/Eastern', -4), ('dateutil/US/Pacific', -7),
  227. (pytz.FixedOffset(-180), -3),
  228. (dateutil.tz.tzoffset(None, 18000), 5)]
  229. for date_str, expected in tests:
  230. for result in [Timestamp(date_str)]:
  231. # only with timestring
  232. assert result.value == expected
  233. assert conversion.pydt_to_i8(result) == expected
  234. # re-creation shouldn't affect to internal value
  235. result = Timestamp(result)
  236. assert result.value == expected
  237. assert conversion.pydt_to_i8(result) == expected
  238. # with timezone
  239. for tz, offset in timezones:
  240. result = Timestamp(date_str, tz=tz)
  241. expected_tz = expected
  242. assert result.value == expected_tz
  243. assert conversion.pydt_to_i8(result) == expected_tz
  244. # should preserve tz
  245. result = Timestamp(result)
  246. assert result.value == expected_tz
  247. assert conversion.pydt_to_i8(result) == expected_tz
  248. # should convert to UTC
  249. result = Timestamp(result).tz_convert('UTC')
  250. expected_utc = expected
  251. assert result.value == expected_utc
  252. assert conversion.pydt_to_i8(result) == expected_utc
  253. # This should be 2013-11-01 05:00 in UTC
  254. # converted to Chicago tz
  255. result = Timestamp('2013-11-01 00:00:00-0500', tz='America/Chicago')
  256. assert result.value == Timestamp('2013-11-01 05:00').value
  257. expected = "Timestamp('2013-11-01 00:00:00-0500', tz='America/Chicago')" # noqa
  258. assert repr(result) == expected
  259. assert result == eval(repr(result))
  260. # This should be 2013-11-01 05:00 in UTC
  261. # converted to Tokyo tz (+09:00)
  262. result = Timestamp('2013-11-01 00:00:00-0500', tz='Asia/Tokyo')
  263. assert result.value == Timestamp('2013-11-01 05:00').value
  264. expected = "Timestamp('2013-11-01 14:00:00+0900', tz='Asia/Tokyo')"
  265. assert repr(result) == expected
  266. assert result == eval(repr(result))
  267. # GH11708
  268. # This should be 2015-11-18 10:00 in UTC
  269. # converted to Asia/Katmandu
  270. result = Timestamp("2015-11-18 15:45:00+05:45", tz="Asia/Katmandu")
  271. assert result.value == Timestamp("2015-11-18 10:00").value
  272. expected = "Timestamp('2015-11-18 15:45:00+0545', tz='Asia/Katmandu')"
  273. assert repr(result) == expected
  274. assert result == eval(repr(result))
  275. # This should be 2015-11-18 10:00 in UTC
  276. # converted to Asia/Kolkata
  277. result = Timestamp("2015-11-18 15:30:00+05:30", tz="Asia/Kolkata")
  278. assert result.value == Timestamp("2015-11-18 10:00").value
  279. expected = "Timestamp('2015-11-18 15:30:00+0530', tz='Asia/Kolkata')"
  280. assert repr(result) == expected
  281. assert result == eval(repr(result))
  282. def test_constructor_invalid(self):
  283. with pytest.raises(TypeError, match='Cannot convert input'):
  284. Timestamp(slice(2))
  285. with pytest.raises(ValueError, match='Cannot convert Period'):
  286. Timestamp(Period('1000-01-01'))
  287. def test_constructor_invalid_tz(self):
  288. # GH#17690
  289. with pytest.raises(TypeError, match='must be a datetime.tzinfo'):
  290. Timestamp('2017-10-22', tzinfo='US/Eastern')
  291. with pytest.raises(ValueError, match='at most one of'):
  292. Timestamp('2017-10-22', tzinfo=utc, tz='UTC')
  293. with pytest.raises(ValueError, match="Invalid frequency:"):
  294. # GH#5168
  295. # case where user tries to pass tz as an arg, not kwarg, gets
  296. # interpreted as a `freq`
  297. Timestamp('2012-01-01', 'US/Pacific')
  298. def test_constructor_tz_or_tzinfo(self):
  299. # GH#17943, GH#17690, GH#5168
  300. stamps = [Timestamp(year=2017, month=10, day=22, tz='UTC'),
  301. Timestamp(year=2017, month=10, day=22, tzinfo=utc),
  302. Timestamp(year=2017, month=10, day=22, tz=utc),
  303. Timestamp(datetime(2017, 10, 22), tzinfo=utc),
  304. Timestamp(datetime(2017, 10, 22), tz='UTC'),
  305. Timestamp(datetime(2017, 10, 22), tz=utc)]
  306. assert all(ts == stamps[0] for ts in stamps)
  307. def test_constructor_positional(self):
  308. # see gh-10758
  309. with pytest.raises(TypeError):
  310. Timestamp(2000, 1)
  311. with pytest.raises(ValueError):
  312. Timestamp(2000, 0, 1)
  313. with pytest.raises(ValueError):
  314. Timestamp(2000, 13, 1)
  315. with pytest.raises(ValueError):
  316. Timestamp(2000, 1, 0)
  317. with pytest.raises(ValueError):
  318. Timestamp(2000, 1, 32)
  319. # see gh-11630
  320. assert (repr(Timestamp(2015, 11, 12)) ==
  321. repr(Timestamp('20151112')))
  322. assert (repr(Timestamp(2015, 11, 12, 1, 2, 3, 999999)) ==
  323. repr(Timestamp('2015-11-12 01:02:03.999999')))
  324. def test_constructor_keyword(self):
  325. # GH 10758
  326. with pytest.raises(TypeError):
  327. Timestamp(year=2000, month=1)
  328. with pytest.raises(ValueError):
  329. Timestamp(year=2000, month=0, day=1)
  330. with pytest.raises(ValueError):
  331. Timestamp(year=2000, month=13, day=1)
  332. with pytest.raises(ValueError):
  333. Timestamp(year=2000, month=1, day=0)
  334. with pytest.raises(ValueError):
  335. Timestamp(year=2000, month=1, day=32)
  336. assert (repr(Timestamp(year=2015, month=11, day=12)) ==
  337. repr(Timestamp('20151112')))
  338. assert (repr(Timestamp(year=2015, month=11, day=12, hour=1, minute=2,
  339. second=3, microsecond=999999)) ==
  340. repr(Timestamp('2015-11-12 01:02:03.999999')))
  341. def test_constructor_fromordinal(self):
  342. base = datetime(2000, 1, 1)
  343. ts = Timestamp.fromordinal(base.toordinal(), freq='D')
  344. assert base == ts
  345. assert ts.freq == 'D'
  346. assert base.toordinal() == ts.toordinal()
  347. ts = Timestamp.fromordinal(base.toordinal(), tz='US/Eastern')
  348. assert Timestamp('2000-01-01', tz='US/Eastern') == ts
  349. assert base.toordinal() == ts.toordinal()
  350. # GH#3042
  351. dt = datetime(2011, 4, 16, 0, 0)
  352. ts = Timestamp.fromordinal(dt.toordinal())
  353. assert ts.to_pydatetime() == dt
  354. # with a tzinfo
  355. stamp = Timestamp('2011-4-16', tz='US/Eastern')
  356. dt_tz = stamp.to_pydatetime()
  357. ts = Timestamp.fromordinal(dt_tz.toordinal(), tz='US/Eastern')
  358. assert ts.to_pydatetime() == dt_tz
  359. @pytest.mark.parametrize('result', [
  360. Timestamp(datetime(2000, 1, 2, 3, 4, 5, 6), nanosecond=1),
  361. Timestamp(year=2000, month=1, day=2, hour=3, minute=4, second=5,
  362. microsecond=6, nanosecond=1),
  363. Timestamp(year=2000, month=1, day=2, hour=3, minute=4, second=5,
  364. microsecond=6, nanosecond=1, tz='UTC'),
  365. Timestamp(2000, 1, 2, 3, 4, 5, 6, 1, None),
  366. Timestamp(2000, 1, 2, 3, 4, 5, 6, 1, pytz.UTC)])
  367. def test_constructor_nanosecond(self, result):
  368. # GH 18898
  369. expected = Timestamp(datetime(2000, 1, 2, 3, 4, 5, 6), tz=result.tz)
  370. expected = expected + Timedelta(nanoseconds=1)
  371. assert result == expected
  372. @pytest.mark.parametrize('z', ['Z0', 'Z00'])
  373. def test_constructor_invalid_Z0_isostring(self, z):
  374. # GH 8910
  375. with pytest.raises(ValueError):
  376. Timestamp('2014-11-02 01:00{}'.format(z))
  377. @pytest.mark.parametrize('arg', ['year', 'month', 'day', 'hour', 'minute',
  378. 'second', 'microsecond', 'nanosecond'])
  379. def test_invalid_date_kwarg_with_string_input(self, arg):
  380. kwarg = {arg: 1}
  381. with pytest.raises(ValueError):
  382. Timestamp('2010-10-10 12:59:59.999999999', **kwarg)
  383. def test_out_of_bounds_value(self):
  384. one_us = np.timedelta64(1).astype('timedelta64[us]')
  385. # By definition we can't go out of bounds in [ns], so we
  386. # convert the datetime64s to [us] so we can go out of bounds
  387. min_ts_us = np.datetime64(Timestamp.min).astype('M8[us]')
  388. max_ts_us = np.datetime64(Timestamp.max).astype('M8[us]')
  389. # No error for the min/max datetimes
  390. Timestamp(min_ts_us)
  391. Timestamp(max_ts_us)
  392. # One us less than the minimum is an error
  393. with pytest.raises(ValueError):
  394. Timestamp(min_ts_us - one_us)
  395. # One us more than the maximum is an error
  396. with pytest.raises(ValueError):
  397. Timestamp(max_ts_us + one_us)
  398. def test_out_of_bounds_string(self):
  399. with pytest.raises(ValueError):
  400. Timestamp('1676-01-01')
  401. with pytest.raises(ValueError):
  402. Timestamp('2263-01-01')
  403. def test_barely_out_of_bounds(self):
  404. # GH#19529
  405. # GH#19382 close enough to bounds that dropping nanos would result
  406. # in an in-bounds datetime
  407. with pytest.raises(OutOfBoundsDatetime):
  408. Timestamp('2262-04-11 23:47:16.854775808')
  409. def test_bounds_with_different_units(self):
  410. out_of_bounds_dates = ('1677-09-21', '2262-04-12')
  411. time_units = ('D', 'h', 'm', 's', 'ms', 'us')
  412. for date_string in out_of_bounds_dates:
  413. for unit in time_units:
  414. dt64 = np.datetime64(date_string, dtype='M8[%s]' % unit)
  415. with pytest.raises(ValueError):
  416. Timestamp(dt64)
  417. in_bounds_dates = ('1677-09-23', '2262-04-11')
  418. for date_string in in_bounds_dates:
  419. for unit in time_units:
  420. dt64 = np.datetime64(date_string, dtype='M8[%s]' % unit)
  421. Timestamp(dt64)
  422. def test_min_valid(self):
  423. # Ensure that Timestamp.min is a valid Timestamp
  424. Timestamp(Timestamp.min)
  425. def test_max_valid(self):
  426. # Ensure that Timestamp.max is a valid Timestamp
  427. Timestamp(Timestamp.max)
  428. def test_now(self):
  429. # GH#9000
  430. ts_from_string = Timestamp('now')
  431. ts_from_method = Timestamp.now()
  432. ts_datetime = datetime.now()
  433. ts_from_string_tz = Timestamp('now', tz='US/Eastern')
  434. ts_from_method_tz = Timestamp.now(tz='US/Eastern')
  435. # Check that the delta between the times is less than 1s (arbitrarily
  436. # small)
  437. delta = Timedelta(seconds=1)
  438. assert abs(ts_from_method - ts_from_string) < delta
  439. assert abs(ts_datetime - ts_from_method) < delta
  440. assert abs(ts_from_method_tz - ts_from_string_tz) < delta
  441. assert (abs(ts_from_string_tz.tz_localize(None) -
  442. ts_from_method_tz.tz_localize(None)) < delta)
  443. def test_today(self):
  444. ts_from_string = Timestamp('today')
  445. ts_from_method = Timestamp.today()
  446. ts_datetime = datetime.today()
  447. ts_from_string_tz = Timestamp('today', tz='US/Eastern')
  448. ts_from_method_tz = Timestamp.today(tz='US/Eastern')
  449. # Check that the delta between the times is less than 1s (arbitrarily
  450. # small)
  451. delta = Timedelta(seconds=1)
  452. assert abs(ts_from_method - ts_from_string) < delta
  453. assert abs(ts_datetime - ts_from_method) < delta
  454. assert abs(ts_from_method_tz - ts_from_string_tz) < delta
  455. assert (abs(ts_from_string_tz.tz_localize(None) -
  456. ts_from_method_tz.tz_localize(None)) < delta)
  457. @pytest.mark.parametrize('tz', [None, pytz.timezone('US/Pacific')])
  458. def test_disallow_setting_tz(self, tz):
  459. # GH 3746
  460. ts = Timestamp('2010')
  461. with pytest.raises(AttributeError):
  462. ts.tz = tz
  463. @pytest.mark.parametrize('offset', ['+0300', '+0200'])
  464. def test_construct_timestamp_near_dst(self, offset):
  465. # GH 20854
  466. expected = Timestamp('2016-10-30 03:00:00{}'.format(offset),
  467. tz='Europe/Helsinki')
  468. result = Timestamp(expected).tz_convert('Europe/Helsinki')
  469. assert result == expected
  470. @pytest.mark.parametrize('arg', [
  471. '2013/01/01 00:00:00+09:00', '2013-01-01 00:00:00+09:00'])
  472. def test_construct_with_different_string_format(self, arg):
  473. # GH 12064
  474. result = Timestamp(arg)
  475. expected = Timestamp(datetime(2013, 1, 1), tz=pytz.FixedOffset(540))
  476. assert result == expected
  477. def test_construct_timestamp_preserve_original_frequency(self):
  478. # GH 22311
  479. result = Timestamp(Timestamp('2010-08-08', freq='D')).freq
  480. expected = offsets.Day()
  481. assert result == expected
  482. def test_constructor_invalid_frequency(self):
  483. # GH 22311
  484. with pytest.raises(ValueError, match="Invalid frequency:"):
  485. Timestamp('2012-01-01', freq=[])
  486. @pytest.mark.parametrize('box', [datetime, Timestamp])
  487. def test_depreciate_tz_and_tzinfo_in_datetime_input(self, box):
  488. # GH 23579
  489. kwargs = {'year': 2018, 'month': 1, 'day': 1, 'tzinfo': utc}
  490. with tm.assert_produces_warning(FutureWarning):
  491. Timestamp(box(**kwargs), tz='US/Pacific')
  492. def test_dont_convert_dateutil_utc_to_pytz_utc(self):
  493. result = Timestamp(datetime(2018, 1, 1), tz=tzutc())
  494. expected = Timestamp(datetime(2018, 1, 1)).tz_localize(tzutc())
  495. assert result == expected
  496. class TestTimestamp(object):
  497. def test_tz(self):
  498. tstr = '2014-02-01 09:00'
  499. ts = Timestamp(tstr)
  500. local = ts.tz_localize('Asia/Tokyo')
  501. assert local.hour == 9
  502. assert local == Timestamp(tstr, tz='Asia/Tokyo')
  503. conv = local.tz_convert('US/Eastern')
  504. assert conv == Timestamp('2014-01-31 19:00', tz='US/Eastern')
  505. assert conv.hour == 19
  506. # preserves nanosecond
  507. ts = Timestamp(tstr) + offsets.Nano(5)
  508. local = ts.tz_localize('Asia/Tokyo')
  509. assert local.hour == 9
  510. assert local.nanosecond == 5
  511. conv = local.tz_convert('US/Eastern')
  512. assert conv.nanosecond == 5
  513. assert conv.hour == 19
  514. def test_utc_z_designator(self):
  515. assert get_timezone(Timestamp('2014-11-02 01:00Z').tzinfo) is utc
  516. def test_asm8(self):
  517. np.random.seed(7960929)
  518. ns = [Timestamp.min.value, Timestamp.max.value, 1000]
  519. for n in ns:
  520. assert (Timestamp(n).asm8.view('i8') ==
  521. np.datetime64(n, 'ns').view('i8') == n)
  522. assert (Timestamp('nat').asm8.view('i8') ==
  523. np.datetime64('nat', 'ns').view('i8'))
  524. def test_class_ops_pytz(self):
  525. def compare(x, y):
  526. assert (int(Timestamp(x).value / 1e9) ==
  527. int(Timestamp(y).value / 1e9))
  528. compare(Timestamp.now(), datetime.now())
  529. compare(Timestamp.now('UTC'), datetime.now(timezone('UTC')))
  530. compare(Timestamp.utcnow(), datetime.utcnow())
  531. compare(Timestamp.today(), datetime.today())
  532. current_time = calendar.timegm(datetime.now().utctimetuple())
  533. compare(Timestamp.utcfromtimestamp(current_time),
  534. datetime.utcfromtimestamp(current_time))
  535. compare(Timestamp.fromtimestamp(current_time),
  536. datetime.fromtimestamp(current_time))
  537. date_component = datetime.utcnow()
  538. time_component = (date_component + timedelta(minutes=10)).time()
  539. compare(Timestamp.combine(date_component, time_component),
  540. datetime.combine(date_component, time_component))
  541. def test_class_ops_dateutil(self):
  542. def compare(x, y):
  543. assert (int(np.round(Timestamp(x).value / 1e9)) ==
  544. int(np.round(Timestamp(y).value / 1e9)))
  545. compare(Timestamp.now(), datetime.now())
  546. compare(Timestamp.now('UTC'), datetime.now(tzutc()))
  547. compare(Timestamp.utcnow(), datetime.utcnow())
  548. compare(Timestamp.today(), datetime.today())
  549. current_time = calendar.timegm(datetime.now().utctimetuple())
  550. compare(Timestamp.utcfromtimestamp(current_time),
  551. datetime.utcfromtimestamp(current_time))
  552. compare(Timestamp.fromtimestamp(current_time),
  553. datetime.fromtimestamp(current_time))
  554. date_component = datetime.utcnow()
  555. time_component = (date_component + timedelta(minutes=10)).time()
  556. compare(Timestamp.combine(date_component, time_component),
  557. datetime.combine(date_component, time_component))
  558. def test_basics_nanos(self):
  559. val = np.int64(946684800000000000).view('M8[ns]')
  560. stamp = Timestamp(val.view('i8') + 500)
  561. assert stamp.year == 2000
  562. assert stamp.month == 1
  563. assert stamp.microsecond == 0
  564. assert stamp.nanosecond == 500
  565. # GH 14415
  566. val = np.iinfo(np.int64).min + 80000000000000
  567. stamp = Timestamp(val)
  568. assert stamp.year == 1677
  569. assert stamp.month == 9
  570. assert stamp.day == 21
  571. assert stamp.microsecond == 145224
  572. assert stamp.nanosecond == 192
  573. @pytest.mark.parametrize('value, check_kwargs', [
  574. [946688461000000000, {}],
  575. [946688461000000000 / long(1000), dict(unit='us')],
  576. [946688461000000000 / long(1000000), dict(unit='ms')],
  577. [946688461000000000 / long(1000000000), dict(unit='s')],
  578. [10957, dict(unit='D', h=0)],
  579. pytest.param((946688461000000000 + 500000) / long(1000000000),
  580. dict(unit='s', us=499, ns=964),
  581. marks=pytest.mark.skipif(not PY3,
  582. reason='using truediv, so these'
  583. ' are like floats')),
  584. pytest.param((946688461000000000 + 500000000) / long(1000000000),
  585. dict(unit='s', us=500000),
  586. marks=pytest.mark.skipif(not PY3,
  587. reason='using truediv, so these'
  588. ' are like floats')),
  589. pytest.param((946688461000000000 + 500000) / long(1000000),
  590. dict(unit='ms', us=500),
  591. marks=pytest.mark.skipif(not PY3,
  592. reason='using truediv, so these'
  593. ' are like floats')),
  594. pytest.param((946688461000000000 + 500000) / long(1000000000),
  595. dict(unit='s'),
  596. marks=pytest.mark.skipif(PY3,
  597. reason='get chopped in py2')),
  598. pytest.param((946688461000000000 + 500000000) / long(1000000000),
  599. dict(unit='s'),
  600. marks=pytest.mark.skipif(PY3,
  601. reason='get chopped in py2')),
  602. pytest.param((946688461000000000 + 500000) / long(1000000),
  603. dict(unit='ms'),
  604. marks=pytest.mark.skipif(PY3,
  605. reason='get chopped in py2')),
  606. [(946688461000000000 + 500000) / long(1000), dict(unit='us', us=500)],
  607. [(946688461000000000 + 500000000) / long(1000000),
  608. dict(unit='ms', us=500000)],
  609. [946688461000000000 / 1000.0 + 5, dict(unit='us', us=5)],
  610. [946688461000000000 / 1000.0 + 5000, dict(unit='us', us=5000)],
  611. [946688461000000000 / 1000000.0 + 0.5, dict(unit='ms', us=500)],
  612. [946688461000000000 / 1000000.0 + 0.005, dict(unit='ms', us=5, ns=5)],
  613. [946688461000000000 / 1000000000.0 + 0.5, dict(unit='s', us=500000)],
  614. [10957 + 0.5, dict(unit='D', h=12)]])
  615. def test_unit(self, value, check_kwargs):
  616. def check(value, unit=None, h=1, s=1, us=0, ns=0):
  617. stamp = Timestamp(value, unit=unit)
  618. assert stamp.year == 2000
  619. assert stamp.month == 1
  620. assert stamp.day == 1
  621. assert stamp.hour == h
  622. if unit != 'D':
  623. assert stamp.minute == 1
  624. assert stamp.second == s
  625. assert stamp.microsecond == us
  626. else:
  627. assert stamp.minute == 0
  628. assert stamp.second == 0
  629. assert stamp.microsecond == 0
  630. assert stamp.nanosecond == ns
  631. check(value, **check_kwargs)
  632. def test_roundtrip(self):
  633. # test value to string and back conversions
  634. # further test accessors
  635. base = Timestamp('20140101 00:00:00')
  636. result = Timestamp(base.value + Timedelta('5ms').value)
  637. assert result == Timestamp(str(base) + ".005000")
  638. assert result.microsecond == 5000
  639. result = Timestamp(base.value + Timedelta('5us').value)
  640. assert result == Timestamp(str(base) + ".000005")
  641. assert result.microsecond == 5
  642. result = Timestamp(base.value + Timedelta('5ns').value)
  643. assert result == Timestamp(str(base) + ".000000005")
  644. assert result.nanosecond == 5
  645. assert result.microsecond == 0
  646. result = Timestamp(base.value + Timedelta('6ms 5us').value)
  647. assert result == Timestamp(str(base) + ".006005")
  648. assert result.microsecond == 5 + 6 * 1000
  649. result = Timestamp(base.value + Timedelta('200ms 5us').value)
  650. assert result == Timestamp(str(base) + ".200005")
  651. assert result.microsecond == 5 + 200 * 1000
  652. def test_hash_equivalent(self):
  653. d = {datetime(2011, 1, 1): 5}
  654. stamp = Timestamp(datetime(2011, 1, 1))
  655. assert d[stamp] == 5
  656. class TestTimestampNsOperations(object):
  657. def setup_method(self, method):
  658. self.timestamp = Timestamp(datetime.utcnow())
  659. def assert_ns_timedelta(self, modified_timestamp, expected_value):
  660. value = self.timestamp.value
  661. modified_value = modified_timestamp.value
  662. assert modified_value - value == expected_value
  663. def test_timedelta_ns_arithmetic(self):
  664. self.assert_ns_timedelta(self.timestamp + np.timedelta64(-123, 'ns'),
  665. -123)
  666. def test_timedelta_ns_based_arithmetic(self):
  667. self.assert_ns_timedelta(self.timestamp + np.timedelta64(
  668. 1234567898, 'ns'), 1234567898)
  669. def test_timedelta_us_arithmetic(self):
  670. self.assert_ns_timedelta(self.timestamp + np.timedelta64(-123, 'us'),
  671. -123000)
  672. def test_timedelta_ms_arithmetic(self):
  673. time = self.timestamp + np.timedelta64(-123, 'ms')
  674. self.assert_ns_timedelta(time, -123000000)
  675. def test_nanosecond_string_parsing(self):
  676. ts = Timestamp('2013-05-01 07:15:45.123456789')
  677. # GH 7878
  678. expected_repr = '2013-05-01 07:15:45.123456789'
  679. expected_value = 1367392545123456789
  680. assert ts.value == expected_value
  681. assert expected_repr in repr(ts)
  682. ts = Timestamp('2013-05-01 07:15:45.123456789+09:00', tz='Asia/Tokyo')
  683. assert ts.value == expected_value - 9 * 3600 * 1000000000
  684. assert expected_repr in repr(ts)
  685. ts = Timestamp('2013-05-01 07:15:45.123456789', tz='UTC')
  686. assert ts.value == expected_value
  687. assert expected_repr in repr(ts)
  688. ts = Timestamp('2013-05-01 07:15:45.123456789', tz='US/Eastern')
  689. assert ts.value == expected_value + 4 * 3600 * 1000000000
  690. assert expected_repr in repr(ts)
  691. # GH 10041
  692. ts = Timestamp('20130501T071545.123456789')
  693. assert ts.value == expected_value
  694. assert expected_repr in repr(ts)
  695. def test_nanosecond_timestamp(self):
  696. # GH 7610
  697. expected = 1293840000000000005
  698. t = Timestamp('2011-01-01') + offsets.Nano(5)
  699. assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')"
  700. assert t.value == expected
  701. assert t.nanosecond == 5
  702. t = Timestamp(t)
  703. assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')"
  704. assert t.value == expected
  705. assert t.nanosecond == 5
  706. t = Timestamp(np_datetime64_compat('2011-01-01 00:00:00.000000005Z'))
  707. assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')"
  708. assert t.value == expected
  709. assert t.nanosecond == 5
  710. expected = 1293840000000000010
  711. t = t + offsets.Nano(5)
  712. assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')"
  713. assert t.value == expected
  714. assert t.nanosecond == 10
  715. t = Timestamp(t)
  716. assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')"
  717. assert t.value == expected
  718. assert t.nanosecond == 10
  719. t = Timestamp(np_datetime64_compat('2011-01-01 00:00:00.000000010Z'))
  720. assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')"
  721. assert t.value == expected
  722. assert t.nanosecond == 10
  723. class TestTimestampToJulianDate(object):
  724. def test_compare_1700(self):
  725. r = Timestamp('1700-06-23').to_julian_date()
  726. assert r == 2342145.5
  727. def test_compare_2000(self):
  728. r = Timestamp('2000-04-12').to_julian_date()
  729. assert r == 2451646.5
  730. def test_compare_2100(self):
  731. r = Timestamp('2100-08-12').to_julian_date()
  732. assert r == 2488292.5
  733. def test_compare_hour01(self):
  734. r = Timestamp('2000-08-12T01:00:00').to_julian_date()
  735. assert r == 2451768.5416666666666666
  736. def test_compare_hour13(self):
  737. r = Timestamp('2000-08-12T13:00:00').to_julian_date()
  738. assert r == 2451769.0416666666666666
  739. class TestTimestampConversion(object):
  740. def test_conversion(self):
  741. # GH#9255
  742. ts = Timestamp('2000-01-01')
  743. result = ts.to_pydatetime()
  744. expected = datetime(2000, 1, 1)
  745. assert result == expected
  746. assert type(result) == type(expected)
  747. result = ts.to_datetime64()
  748. expected = np.datetime64(ts.value, 'ns')
  749. assert result == expected
  750. assert type(result) == type(expected)
  751. assert result.dtype == expected.dtype
  752. def test_to_pydatetime_nonzero_nano(self):
  753. ts = Timestamp('2011-01-01 9:00:00.123456789')
  754. # Warn the user of data loss (nanoseconds).
  755. with tm.assert_produces_warning(UserWarning,
  756. check_stacklevel=False):
  757. expected = datetime(2011, 1, 1, 9, 0, 0, 123456)
  758. result = ts.to_pydatetime()
  759. assert result == expected
  760. def test_timestamp_to_datetime(self):
  761. stamp = Timestamp('20090415', tz='US/Eastern', freq='D')
  762. dtval = stamp.to_pydatetime()
  763. assert stamp == dtval
  764. assert stamp.tzinfo == dtval.tzinfo
  765. def test_timestamp_to_datetime_dateutil(self):
  766. stamp = Timestamp('20090415', tz='dateutil/US/Eastern', freq='D')
  767. dtval = stamp.to_pydatetime()
  768. assert stamp == dtval
  769. assert stamp.tzinfo == dtval.tzinfo
  770. def test_timestamp_to_datetime_explicit_pytz(self):
  771. stamp = Timestamp('20090415', tz=pytz.timezone('US/Eastern'), freq='D')
  772. dtval = stamp.to_pydatetime()
  773. assert stamp == dtval
  774. assert stamp.tzinfo == dtval.tzinfo
  775. @td.skip_if_windows_python_3
  776. def test_timestamp_to_datetime_explicit_dateutil(self):
  777. stamp = Timestamp('20090415', tz=gettz('US/Eastern'), freq='D')
  778. dtval = stamp.to_pydatetime()
  779. assert stamp == dtval
  780. assert stamp.tzinfo == dtval.tzinfo
  781. def test_to_datetime_bijective(self):
  782. # Ensure that converting to datetime and back only loses precision
  783. # by going from nanoseconds to microseconds.
  784. exp_warning = None if Timestamp.max.nanosecond == 0 else UserWarning
  785. with tm.assert_produces_warning(exp_warning, check_stacklevel=False):
  786. assert (Timestamp(Timestamp.max.to_pydatetime()).value / 1000 ==
  787. Timestamp.max.value / 1000)
  788. exp_warning = None if Timestamp.min.nanosecond == 0 else UserWarning
  789. with tm.assert_produces_warning(exp_warning, check_stacklevel=False):
  790. assert (Timestamp(Timestamp.min.to_pydatetime()).value / 1000 ==
  791. Timestamp.min.value / 1000)
  792. def test_to_period_tz_warning(self):
  793. # GH#21333 make sure a warning is issued when timezone
  794. # info is lost
  795. ts = Timestamp('2009-04-15 16:17:18', tz='US/Eastern')
  796. with tm.assert_produces_warning(UserWarning):
  797. # warning that timezone info will be lost
  798. ts.to_period('D')