@@ -35,6 +35,7 @@ from timedeltas import Timedelta
35
35
from timedeltas cimport delta_to_nanoseconds
36
36
from timezones cimport (
37
37
get_timezone, is_utc, maybe_get_tz, treat_tz_as_pytz, tz_compare)
38
+ from pandas.tseries.frequencies import to_offset
38
39
39
40
# ----------------------------------------------------------------------
40
41
# Constants
@@ -59,6 +60,45 @@ cdef inline object create_timestamp_from_ts(int64_t value,
59
60
return ts_base
60
61
61
62
63
+ def round_ns (values , rounder , freq ):
64
+ """
65
+ Applies rounding function at given frequency
66
+
67
+ Parameters
68
+ ----------
69
+ values : int, :obj:`ndarray`
70
+ rounder : function
71
+ freq : str, obj
72
+
73
+ Returns
74
+ -------
75
+ int or :obj:`ndarray`
76
+ """
77
+ unit = to_offset(freq).nanos
78
+ if unit < 1000 :
79
+ # for nano rounding, work with the last 6 digits separately
80
+ # due to float precision
81
+ buff = 1000000
82
+ r = (buff * (values // buff) + unit *
83
+ (rounder((values % buff) * (1 / float (unit)))).astype(' i8' ))
84
+ else :
85
+ if unit % 1000 != 0 :
86
+ msg = ' Precision will be lost using frequency: {}'
87
+ warnings.warn(msg.format(freq))
88
+
89
+ # GH19206
90
+ # to deal with round-off when unit is large
91
+ if unit >= 1e9 :
92
+ divisor = 10 ** int (np.log10(unit / 1e7 ))
93
+ else :
94
+ divisor = 10
95
+
96
+ r = (unit * rounder((values * (divisor / float (unit))) / divisor)
97
+ .astype(' i8' ))
98
+
99
+ return r
100
+
101
+
62
102
# This is PITA. Because we inherit from datetime, which has very specific
63
103
# construction requirements, we need to do object instantiation in python
64
104
# (see Timestamp class above). This will serve as a C extension type that
@@ -591,36 +631,38 @@ class Timestamp(_Timestamp):
591
631
592
632
def _round (self , freq , rounder ):
593
633
594
- cdef:
595
- int64_t unit, r, value, buff = 1000000
596
- object result
634
+ # cdef:
635
+ # int64_t unit, r, value, buff = 1000000
636
+ # object result
597
637
598
- from pandas.tseries.frequencies import to_offset
599
- unit = to_offset(freq).nanos
638
+ # from pandas.tseries.frequencies import to_offset
639
+ # unit = to_offset(freq).nanos
600
640
if self .tz is not None :
601
641
value = self .tz_localize(None ).value
602
642
else :
603
643
value = self .value
604
- if unit < 1000 :
605
- # for nano rounding, work with the last 6 digits separately
606
- # due to float precision
607
- r = (buff * (value // buff) + unit *
608
- (rounder((value % buff) * (1 / float (unit)))).astype(' i8' ))
609
- else :
610
- if unit % 1000 != 0 :
611
- msg = ' Precision will be lost using frequency: {}'
612
- warnings.warn(msg.format(freq))
613
-
614
- # GH19206
615
- # to deal with round-off when unit is large
616
- if unit >= 1e9 :
617
- divisor = 10 ** int (np.log10(unit / 1e7 ))
618
- else :
619
- divisor = 10
620
644
621
- r = (unit * rounder((value * (divisor / float (unit))) / divisor)
622
- .astype(' i8' ))
645
+ # if unit < 1000:
646
+ # # for nano rounding, work with the last 6 digits separately
647
+ # # due to float precision
648
+ # r = (buff * (value // buff) + unit *
649
+ # (rounder((value % buff) * (1 / float(unit)))).astype('i8'))
650
+ # else:
651
+ # if unit % 1000 != 0:
652
+ # msg = 'Precision will be lost using frequency: {}'
653
+ # warnings.warn(msg.format(freq))
654
+ #
655
+ # # GH19206
656
+ # # to deal with round-off when unit is large
657
+ # if unit >= 1e9:
658
+ # divisor = 10 ** int(np.log10(unit / 1e7))
659
+ # else:
660
+ # divisor = 10
661
+ #
662
+ # r = (unit * rounder((value * (divisor / float(unit))) / divisor)
663
+ # .astype('i8'))
623
664
665
+ r = round_ns(value, rounder, freq)
624
666
result = Timestamp(r, unit = ' ns' )
625
667
if self .tz is not None :
626
668
result = result.tz_localize(self .tz)
0 commit comments