Repository: pandas-dev/pandas
Pull request: API: Timestamp and Timedelta .value changing in 2.0
- [ ] closes #49076 (Replace xxxx with the GitHub issue number)
- [ ] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [ ] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [ ] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
- [ ] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.


Problem statement:
API: Timestamp and Timedelta .value changing in 2.0
```python
import pandas as pd
import numpy as np

dt = np.datetime64("2016-01-01", "ms")
ts = pd.Timestamp(dt)

>>> ts.value
1451606400000        # <- 2.0/main
1451606400000000000  # <- 1.x
```

In previous versions .value has always been in nanoseconds.  By changing the reso we get with some Timestamp/Timedelta inputs, we change the .value, which is technically public API.

One option would be just to document the change in .value behavior along with the other breaking changes docs.

Another would be to use e.g. `._value` internally and keep `.value` as representing nanos.

Hints from issue discussion:
Probably least disruptive to have `.value` continue to represent nanos.

Personally, I was never fond of the vague meaning of `.value` and could use this as an opportunity to deprecate in favor of `Timestamp.to_epoch` #14772 and `Timedelta.to_something`
The Arrow CI was failing because of this (in combination with the changes parsing of strings in `Timestamp(..)`, https://github.com/pandas-dev/pandas/issues/50704). Now, the failure was only because of using `.value` in a test to construct the expected result, and that is something easy to update. 
However, I also looked into our actual conversion code, and it seems we _do_ use `.value` to access the integer value, and we do assume that this is always nanoseconds at the moment (https://github.com/apache/arrow/blob/2b50694c10e09e4a1343b62c6b5f44ad4403d0e1/python/pyarrow/src/arrow/python/python_to_arrow.cc#L360-L365)

It's a bit of a corner case (and so apparently also not covered by a test, since we didn't get a failure for this), but can be triggered by converting a list of Timestamp objects (or object dtype array), and explicitly passing a nanoseconds timestamp type:

```
# using current pandas main branch
>>> pa.array([pd.Timestamp("2012-01-01 09:01:02")], type=pa.timestamp("ns"))
<pyarrow.lib.TimestampArray object at 0x7f46ce55ec80>
[
  1970-01-01 00:00:01.325408462
]

# triggering the pd.Timestamp to be nanosecond resolution -> correct result
>>> pa.array([pd.Timestamp("2012-01-01 09:01:02.000000000")], type=pa.timestamp("ns"))
<pyarrow.lib.TimestampArray object at 0x7f46ac585480>
[
  2012-01-01 09:01:02.000000000
]
```

This could be fixed on the pyarrow side by checking the unit of the Timestamp, and only using `.value` when it is actually nanoseconds, and otherwise falling back to interpreting it as datetime.datetime and getting the components that way. 

But it would break current pyarrow releases, so if we want to change `.value`, ideally we would wait a bit longer with that to give time for pyarrow to update for this. 

So to summarize, I agree with the above that the easiest would be to keep `.value` as returning nanoseconds, always, regardless the actual unit. 

But long term it would be good to have _some_ way to get the raw underlying integer (that is more efficient that building up this value from the components, as we do for datetime.datetime objects). But this could indeed also be a method, as suggested by @mroeschke 
+1 on @mroeschke 's suggestion

I'll work on `.value` today
Two bikeshed thoughts to what to use instead of `.value` internally: 1) using `asi8` would allow for some code-sharing with DTA/DTI/TDA/TDI, 2) having something distinctive would make it easier to grep for places where we use it.
For now, in https://github.com/pandas-dev/pandas/pull/50891, I just made it `_value`

I wasn't quite prepared for how many files it would involve changing
@jorisvandenbossche @jbrockmendel @mroeschke are we sure this is a good idea?

Because then the public-facing `.value` would be unavailable for old timestamps, e.g. `Timestamp('300-01-01 00:00:00')`, because it would overflow (and this is what motivated the introduction of non-nanosecond resolution)
i guess we'd document that it is for nanos-only and direct users to use e.g. .asm8.view('i8') more generally
sure, I'll add that to the error message

`Timedelta` doesn't support non-nano reso yet, right? If so, perhaps I'll hold off timedelta changes for now then, that'll reduce the diff and make review a bit easier
Timedelta supports non-nano, but doesn't do inference on strings
thanks - how do I set it? I'm seeing
```
In [6]: Timedelta(days=1, unit='s').unit
Out[6]: 'ns'
```

Commit message: fix test missing

Patch to review:
diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx
index 2565d7998c9c7..2a6c26d595548 100644
--- a/pandas/_libs/index.pyx
+++ b/pandas/_libs/index.pyx
@@ -517,14 +517,16 @@ cdef class DatetimeEngine(Int64Engine):
         # NB: caller is responsible for ensuring tzawareness compat
         #  before we get here
         if scalar is NaT:
-            return NaT.value
+            return NaT._value
         elif isinstance(scalar, _Timestamp):
             if scalar._creso == self._creso:
-                return scalar.value
+                return scalar._value
             else:
                 # Note: caller is responsible for catching potential ValueError
                 #  from _as_creso
-                return (<_Timestamp>scalar)._as_creso(self._creso, round_ok=False).value
+                return (
+                    (<_Timestamp>scalar)._as_creso(self._creso, round_ok=False)._value
+                )
         raise TypeError(scalar)
 
     def __contains__(self, val: object) -> bool:
@@ -585,14 +587,16 @@ cdef class TimedeltaEngine(DatetimeEngine):
 
     cdef int64_t _unbox_scalar(self, scalar) except? -1:
         if scalar is NaT:
-            return NaT.value
+            return NaT._value
         elif isinstance(scalar, _Timedelta):
             if scalar._creso == self._creso:
-                return scalar.value
+                return scalar._value
             else:
                 # Note: caller is responsible for catching potential ValueError
                 #  from _as_creso
-                return (<_Timedelta>scalar)._as_creso(self._creso, round_ok=False).value
+                return (
+                    (<_Timedelta>scalar)._as_creso(self._creso, round_ok=False)._value
+                )
         raise TypeError(scalar)
 
 
@@ -600,7 +604,7 @@ cdef class PeriodEngine(Int64Engine):
 
     cdef int64_t _unbox_scalar(self, scalar) except? -1:
         if scalar is NaT:
-            return scalar.value
+            return scalar._value
         if is_period_object(scalar):
             # NB: we assume that we have the correct freq here.
             return scalar.ordinal
diff --git a/pandas/_libs/src/ujson/python/objToJSON.c b/pandas/_libs/src/ujson/python/objToJSON.c
index 13b96f9f8fccd..e892b50515327 100644
--- a/pandas/_libs/src/ujson/python/objToJSON.c
+++ b/pandas/_libs/src/ujson/python/objToJSON.c
@@ -1306,9 +1306,9 @@ char **NpyArr_encodeLabels(PyArrayObject *labels, PyObjectEncoder *enc,
             castfunc(dataptr, &nanosecVal, 1, NULL, NULL);
         } else if (PyDate_Check(item) || PyDelta_Check(item)) {
             is_datetimelike = 1;
-            if (PyObject_HasAttrString(item, "value")) {
+            if (PyObject_HasAttrString(item, "_value")) {
                 // see test_date_index_and_values for case with non-nano
-                nanosecVal = get_long_attr(item, "value");
+                nanosecVal = get_long_attr(item, "_value");
             } else {
                 if (PyDelta_Check(item)) {
                     nanosecVal = total_seconds(item) *
@@ -1554,8 +1554,8 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
         }
         return;
     } else if (PyDelta_Check(obj)) {
-        if (PyObject_HasAttrString(obj, "value")) {
-            value = get_long_attr(obj, "value");
+        if (PyObject_HasAttrString(obj, "_value")) {
+            value = get_long_attr(obj, "_value");
         } else {
             value = total_seconds(obj) * 1000000000LL;  // nanoseconds per sec
         }
diff --git a/pandas/_libs/tslib.pyx b/pandas/_libs/tslib.pyx
index 89a676f51dc47..19dd7aabe6b8e 100644
--- a/pandas/_libs/tslib.pyx
+++ b/pandas/_libs/tslib.pyx
@@ -705,7 +705,7 @@ def array_to_datetime_with_tz(ndarray values, tzinfo tz):
                     # datetime64, tznaive pydatetime, int, float
                     ts = ts.tz_localize(tz)
                 ts = ts.as_unit("ns")
-                ival = ts.value
+                ival = ts._value
 
         # Analogous to: result[i] = ival
         (<int64_t*>cnp.PyArray_MultiIter_DATA(mi, 0))[0] = ival
diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx
index 933e10a35118c..2c70d1681b051 100644
--- a/pandas/_libs/tslibs/conversion.pyx
+++ b/pandas/_libs/tslibs/conversion.pyx
@@ -765,7 +765,7 @@ cdef int64_t parse_pydatetime(
             result = _ts.value
     else:
         if isinstance(val, _Timestamp):
-            result = val.as_unit("ns").value
+            result = val.as_unit("ns")._value
         else:
             result = pydatetime_to_dt64(val, dts)
             check_dts_bounds(dts)
diff --git a/pandas/_libs/tslibs/nattype.pxd b/pandas/_libs/tslibs/nattype.pxd
index e878fa7629f25..32705aa633135 100644
--- a/pandas/_libs/tslibs/nattype.pxd
+++ b/pandas/_libs/tslibs/nattype.pxd
@@ -8,7 +8,7 @@ cdef set c_nat_strings
 
 cdef class _NaT(datetime):
     cdef readonly:
-        int64_t value
+        int64_t _value
 
 cdef _NaT c_NaT
 
diff --git a/pandas/_libs/tslibs/nattype.pyi b/pandas/_libs/tslibs/nattype.pyi
index 72f55bb50895a..04f8943710416 100644
--- a/pandas/_libs/tslibs/nattype.pyi
+++ b/pandas/_libs/tslibs/nattype.pyi
@@ -18,7 +18,9 @@ class _NatComparison:
     def __call__(self, other: _NaTComparisonTypes) -> bool: ...
 
 class NaTType:
-    value: np.int64
+    _value: np.int64
+    @property
+    def value(self) -> int: ...
     @property
     def asm8(self) -> np.datetime64: ...
     def to_datetime64(self) -> np.datetime64: ...
diff --git a/pandas/_libs/tslibs/nattype.pyx b/pandas/_libs/tslibs/nattype.pyx
index 9407f57a282bf..d9d8ce3bb16d1 100644
--- a/pandas/_libs/tslibs/nattype.pyx
+++ b/pandas/_libs/tslibs/nattype.pyx
@@ -357,10 +357,14 @@ class NaTType(_NaT):
         cdef _NaT base
 
         base = _NaT.__new__(cls, 1, 1, 1)
-        base.value = NPY_NAT
+        base._value= NPY_NAT
 
         return base
 
+    @property
+    def value(self) -> int:
+        return self._value
+
     def __reduce_ex__(self, protocol):
         # python 3.6 compat
         # https://bugs.python.org/issue28730
diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx
index 79332f8ede936..9ad95651cb3dc 100644
--- a/pandas/_libs/tslibs/offsets.pyx
+++ b/pandas/_libs/tslibs/offsets.pyx
@@ -183,7 +183,7 @@ def apply_wraps(func):
                     res = result.tz_localize(None)
                 else:
                     res = result
-                value = res.as_unit("ns").value
+                value = res.as_unit("ns")._value
                 result = Timestamp(value + nano)
 
         if tz is not None and result.tzinfo is None:
@@ -3469,7 +3469,7 @@ cdef class FY5253Quarter(FY5253Mixin):
         else:
             tdelta = Timedelta(0)
 
-        # Note: we always have tdelta.value >= 0
+        # Note: we always have tdelta._value>= 0
         return start, num_qtrs, tdelta
 
     @apply_wraps
@@ -3481,7 +3481,7 @@ cdef class FY5253Quarter(FY5253Mixin):
         prev_year_end, num_qtrs, tdelta = self._rollback_to_year(other)
         res = prev_year_end
         n += num_qtrs
-        if self.n <= 0 and tdelta.value > 0:
+        if self.n <= 0 and tdelta._value > 0:
             n += 1
 
         # Possible speedup by handling years first.
diff --git a/pandas/_libs/tslibs/strptime.pyx b/pandas/_libs/tslibs/strptime.pyx
index 3ca87f8680b53..bb06c65597987 100644
--- a/pandas/_libs/tslibs/strptime.pyx
+++ b/pandas/_libs/tslibs/strptime.pyx
@@ -113,14 +113,14 @@ cdef bint parse_today_now(str val, int64_t* iresult, bint utc):
     #  microsecond resolution
     if val == "now":
         if utc:
-            iresult[0] = Timestamp.utcnow().value * 1000
+            iresult[0] = Timestamp.utcnow()._value * 1000
         else:
             # GH#18705 make sure to_datetime("now") matches Timestamp("now")
             # Note using Timestamp.now() is faster than Timestamp("now")
-            iresult[0] = Timestamp.now().value * 1000
+            iresult[0] = Timestamp.now()._value * 1000
         return True
     elif val == "today":
-        iresult[0] = Timestamp.today().value * 1000
+        iresult[0] = Timestamp.today()._value * 1000
         return True
     return False
 
@@ -284,7 +284,7 @@ def array_strptime(
                     utc,
                 )
                 if isinstance(val, _Timestamp):
-                    iresult[i] = val.tz_localize(None).as_unit("ns").value
+                    iresult[i] = val.tz_localize(None).as_unit("ns")._value
                 else:
                     iresult[i] = pydatetime_to_dt64(val.replace(tzinfo=None), &dts)
                     check_dts_bounds(&dts)
diff --git a/pandas/_libs/tslibs/timedeltas.pxd b/pandas/_libs/tslibs/timedeltas.pxd
index 8a354c4cb631f..fb6e29a8932a1 100644
--- a/pandas/_libs/tslibs/timedeltas.pxd
+++ b/pandas/_libs/tslibs/timedeltas.pxd
@@ -14,7 +14,7 @@ cdef bint is_any_td_scalar(object obj)
 
 cdef class _Timedelta(timedelta):
     cdef readonly:
-        int64_t value      # nanoseconds
+        int64_t _value      # nanoseconds
         bint _is_populated  # are my components populated
         int64_t _d, _h, _m, _s, _ms, _us, _ns
         NPY_DATETIMEUNIT _creso
diff --git a/pandas/_libs/tslibs/timedeltas.pyi b/pandas/_libs/tslibs/timedeltas.pyi
index c9904e4592329..d67a330e0b0c2 100644
--- a/pandas/_libs/tslibs/timedeltas.pyi
+++ b/pandas/_libs/tslibs/timedeltas.pyi
@@ -89,6 +89,7 @@ class Timedelta(timedelta):
     max: ClassVar[Timedelta]
     resolution: ClassVar[Timedelta]
     value: int  # np.int64
+    _value: int  # np.int64
     # error: "__new__" must return a class instance (got "Union[Timestamp, NaTType]")
     def __new__(  # type: ignore[misc]
         cls: type[_S],
diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx
index d7352f80132a2..5ecce54e01db6 100644
--- a/pandas/_libs/tslibs/timedeltas.pyx
+++ b/pandas/_libs/tslibs/timedeltas.pyx
@@ -243,7 +243,7 @@ cpdef int64_t delta_to_nanoseconds(
         in_reso = delta._creso
 
     elif isinstance(delta, _Timedelta):
-        n = delta.value
+        n = delta._value
         in_reso = delta._creso
 
     elif is_timedelta64_object(delta):
@@ -342,7 +342,7 @@ cdef convert_to_timedelta64(object ts, str unit):
         if ts._creso != NPY_FR_ns:
             ts = ts.as_unit("ns").asm8
         else:
-            ts = np.timedelta64(ts.value, "ns")
+            ts = np.timedelta64(ts._value, "ns")
     elif is_timedelta64_object(ts):
         ts = ensure_td64ns(ts)
     elif is_integer_object(ts):
@@ -737,7 +737,7 @@ cdef bint _validate_ops_compat(other):
 
 def _op_unary_method(func, name):
     def f(self):
-        new_value = func(self.value)
+        new_value = func(self._value)
         return _timedelta_from_value_and_reso(Timedelta, new_value, self._creso)
     f.__name__ = name
     return f
@@ -795,7 +795,7 @@ def _binary_op_method_timedeltalike(op, name):
         elif self._creso > other._creso:
             other = (<_Timedelta>other)._as_creso(self._creso, round_ok=True)
 
-        res = op(self.value, other.value)
+        res = op(self._value, other._value)
         if res == NPY_NAT:
             # e.g. test_implementation_limits
             # TODO: more generally could do an overflowcheck in op?
@@ -965,7 +965,7 @@ cdef _timedelta_from_value_and_reso(cls, int64_t value, NPY_DATETIMEUNIT reso):
             "Only resolutions 's', 'ms', 'us', 'ns' are supported."
         )
 
-    td_base.value = value
+    td_base._value= value
     td_base._is_populated = 0
     td_base._creso = reso
     return td_base
@@ -1016,6 +1016,17 @@ cdef class _Timedelta(timedelta):
     max = MinMaxReso("max")
     resolution = MinMaxReso("resolution")
 
+    @property
+    def value(self):
+        try:
+            return convert_reso(self._value, self._creso, NPY_FR_ns, False)
+        except OverflowError:
+            raise OverflowError(
+                "Cannot convert Timedelta to nanoseconds without overflow. "
+                "Use `.asm8.view('i8')` to cast represent Timedelta in its own "
+                f"unit (here, {self.unit})."
+            )
+
     @property
     def _unit(self) -> str:
         """
@@ -1089,7 +1100,7 @@ cdef class _Timedelta(timedelta):
             #  if td1 and td2 have different _resos. timedelta64 also has this
             #  non-invariant behavior.
             #  see GH#44504
-            return hash(self.value)
+            return hash(self._value)
         elif self._is_in_pytimedelta_bounds() and (
             self._creso == NPY_FR_ns or self._creso == NPY_DATETIMEUNIT.NPY_FR_us
         ):
@@ -1108,7 +1119,7 @@ cdef class _Timedelta(timedelta):
                 obj = (<_Timedelta>self)._as_creso(<NPY_DATETIMEUNIT>(self._creso + 1))
             except OverflowError:
                 # Doesn't fit, so we're off the hook
-                return hash(self.value)
+                return hash(self._value)
             else:
                 return hash(obj)
 
@@ -1144,7 +1155,7 @@ cdef class _Timedelta(timedelta):
             return NotImplemented
 
         if self._creso == ots._creso:
-            return cmp_scalar(self.value, ots.value, op)
+            return cmp_scalar(self._value, ots._value, op)
         return self._compare_mismatched_resos(ots, op)
 
     # TODO: re-use/share with Timestamp
@@ -1155,13 +1166,13 @@ cdef class _Timedelta(timedelta):
             npy_datetimestruct dts_other
 
         # dispatch to the datetimestruct utils instead of writing new ones!
-        pandas_datetime_to_datetimestruct(self.value, self._creso, &dts_self)
-        pandas_datetime_to_datetimestruct(other.value, other._creso, &dts_other)
+        pandas_datetime_to_datetimestruct(self._value, self._creso, &dts_self)
+        pandas_datetime_to_datetimestruct(other._value, other._creso, &dts_other)
         return cmp_dtstructs(&dts_self,  &dts_other, op)
 
     cdef bint _has_ns(self):
         if self._creso == NPY_FR_ns:
-            return self.value % 1000 != 0
+            return self._value % 1000 != 0
         elif self._creso < NPY_FR_ns:
             # i.e. seconds, millisecond, microsecond
             return False
@@ -1185,7 +1196,7 @@ cdef class _Timedelta(timedelta):
         cdef:
             pandas_timedeltastruct tds
 
-        pandas_timedelta_to_timedeltastruct(self.value, self._creso, &tds)
+        pandas_timedelta_to_timedeltastruct(self._value, self._creso, &tds)
         self._d = tds.days
         self._h = tds.hrs
         self._m = tds.min
@@ -1218,7 +1229,7 @@ cdef class _Timedelta(timedelta):
         Any nanosecond resolution will be lost.
         """
         if self._creso == NPY_FR_ns:
-            return timedelta(microseconds=int(self.value) / 1000)
+            return timedelta(microseconds=int(self._value) / 1000)
 
         # TODO(@WillAyd): is this the right way to use components?
         self._ensure_components()
@@ -1234,7 +1245,7 @@ cdef class _Timedelta(timedelta):
             str abbrev = npy_unit_to_abbrev(self._creso)
         # TODO: way to create a np.timedelta64 obj with the reso directly
         #  instead of having to get the abbrev?
-        return np.timedelta64(self.value, abbrev)
+        return np.timedelta64(self._value, abbrev)
 
     def to_numpy(self, dtype=None, copy=False) -> np.timedelta64:
         """
@@ -1267,7 +1278,7 @@ cdef class _Timedelta(timedelta):
         dtype : str or dtype
             The dtype to view the underlying data as.
         """
-        return np.timedelta64(self.value).view(dtype)
+        return np.timedelta64(self._value).view(dtype)
 
     @property
     def components(self):
@@ -1466,7 +1477,7 @@ cdef class _Timedelta(timedelta):
         return self._repr_base(format="long")
 
     def __bool__(self) -> bool:
-        return self.value != 0
+        return self._value!= 0
 
     def isoformat(self) -> str:
         """
@@ -1552,7 +1563,7 @@ cdef class _Timedelta(timedelta):
             return self
 
         try:
-            value = convert_reso(self.value, self._creso, reso, round_ok=round_ok)
+            value = convert_reso(self._value, self._creso, reso, round_ok=round_ok)
         except OverflowError as err:
             unit = npy_unit_to_abbrev(reso)
             raise OutOfBoundsTimedelta(
@@ -1767,11 +1778,11 @@ class Timedelta(_Timedelta):
             reso = NPY_FR_ns
         else:
             value, reso = state
-        self.value = value
+        self._value= value
         self._creso = reso
 
     def __reduce__(self):
-        object_state = self.value, self._creso
+        object_state = self._value, self._creso
         return (_timedelta_unpickle, object_state)
 
     @cython.cdivision(True)
@@ -1785,7 +1796,7 @@ class Timedelta(_Timedelta):
         to_offset(freq).nanos  # raises on non-fixed freq
         unit = delta_to_nanoseconds(to_offset(freq), self._creso)
 
-        arr = np.array([self.value], dtype="i8")
+        arr = np.array([self._value], dtype="i8")
         result = round_nsint64(arr, mode, unit)[0]
         return Timedelta._from_value_and_reso(result, self._creso)
 
@@ -1851,7 +1862,7 @@ class Timedelta(_Timedelta):
 
             return _timedelta_from_value_and_reso(
                 Timedelta,
-                <int64_t>(other * self.value),
+                <int64_t>(other * self._value),
                 reso=self._creso,
             )
 
@@ -1874,14 +1885,14 @@ class Timedelta(_Timedelta):
                 return np.nan
             if other._creso != self._creso:
                 self, other = self._maybe_cast_to_matching_resos(other)
-            return self.value / float(other.value)
+            return self._value/ float(other._value)
 
         elif is_integer_object(other) or is_float_object(other):
             # integers or floats
             if util.is_nan(other):
                 return NaT
             return Timedelta._from_value_and_reso(
-                <int64_t>(self.value / other), self._creso
+                <int64_t>(self._value/ other), self._creso
             )
 
         elif is_array(other):
@@ -1901,7 +1912,7 @@ class Timedelta(_Timedelta):
                 return np.nan
             if self._creso != other._creso:
                 self, other = self._maybe_cast_to_matching_resos(other)
-            return float(other.value) / self.value
+            return float(other._value) / self._value
 
         elif is_array(other):
             if other.ndim == 0:
@@ -1929,12 +1940,12 @@ class Timedelta(_Timedelta):
                 return np.nan
             if self._creso != other._creso:
                 self, other = self._maybe_cast_to_matching_resos(other)
-            return self.value // other.value
+            return self._value// other._value
 
         elif is_integer_object(other) or is_float_object(other):
             if util.is_nan(other):
                 return NaT
-            return type(self)._from_value_and_reso(self.value // other, self._creso)
+            return type(self)._from_value_and_reso(self._value// other, self._creso)
 
         elif is_array(other):
             if other.ndim == 0:
@@ -1978,7 +1989,7 @@ class Timedelta(_Timedelta):
                 return np.nan
             if self._creso != other._creso:
                 self, other = self._maybe_cast_to_matching_resos(other)
-            return other.value // self.value
+            return other._value// self._value
 
         elif is_array(other):
             if other.ndim == 0:
diff --git a/pandas/_libs/tslibs/timestamps.pxd b/pandas/_libs/tslibs/timestamps.pxd
index 1b87d2ba4eb25..26018cd904249 100644
--- a/pandas/_libs/tslibs/timestamps.pxd
+++ b/pandas/_libs/tslibs/timestamps.pxd
@@ -21,7 +21,7 @@ cdef _Timestamp create_timestamp_from_ts(int64_t value,
 
 cdef class _Timestamp(ABCTimestamp):
     cdef readonly:
-        int64_t value, nanosecond, year
+        int64_t _value, nanosecond, year
         NPY_DATETIMEUNIT _creso
 
     cdef bint _get_start_end_field(self, str field, freq)
diff --git a/pandas/_libs/tslibs/timestamps.pyi b/pandas/_libs/tslibs/timestamps.pyi
index e6a36b69a8d47..a0e2b8df780c6 100644
--- a/pandas/_libs/tslibs/timestamps.pyi
+++ b/pandas/_libs/tslibs/timestamps.pyi
@@ -33,6 +33,7 @@ class Timestamp(datetime):
 
     resolution: ClassVar[Timedelta]
     value: int  # np.int64
+    _value: int  # np.int64
     # error: "__new__" must return a class instance (got "Union[Timestamp, NaTType]")
     def __new__(  # type: ignore[misc]
         cls: type[_DatetimeT],
diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx
index fb3adda155254..c4025c7e5efe7 100644
--- a/pandas/_libs/tslibs/timestamps.pyx
+++ b/pandas/_libs/tslibs/timestamps.pyx
@@ -154,7 +154,7 @@ cdef _Timestamp create_timestamp_from_ts(
                                  dts.day, dts.hour, dts.min,
                                  dts.sec, dts.us, tz, fold=fold)
 
-    ts_base.value = value
+    ts_base._value = value
     ts_base.year = dts.year
     ts_base.nanosecond = dts.ps // 1000
     ts_base._creso = reso
@@ -232,6 +232,17 @@ cdef class _Timestamp(ABCTimestamp):
     max = MinMaxReso("max")
     resolution = MinMaxReso("resolution")  # GH#21336, GH#21365
 
+    @property
+    def value(self) -> int:
+        try:
+            return convert_reso(self._value, self._creso, NPY_FR_ns, False)
+        except OverflowError:
+            raise OverflowError(
+                "Cannot convert Timestamp to nanoseconds without overflow. "
+                "Use `.asm8.view('i8')` to cast represent Timestamp in its own "
+                f"unit (here, {self.unit})."
+            )
+
     @property
     def unit(self) -> str:
         """
@@ -296,10 +307,10 @@ cdef class _Timestamp(ABCTimestamp):
 
     def __hash__(_Timestamp self):
         if self.nanosecond:
-            return hash(self.value)
+            return hash(self._value)
         if not (1 <= self.year <= 9999):
             # out of bounds for pydatetime
-            return hash(self.value)
+            return hash(self._value)
         if self.fold:
             return datetime.__hash__(self.replace(fold=0))
         return datetime.__hash__(self)
@@ -371,7 +382,7 @@ cdef class _Timestamp(ABCTimestamp):
                 "Cannot compare tz-naive and tz-aware timestamps"
             )
         if self._creso == ots._creso:
-            return cmp_scalar(self.value, ots.value, op)
+            return cmp_scalar(self._value, ots._value, op)
         return self._compare_mismatched_resos(ots, op)
 
     # TODO: copied from Timedelta; try to de-duplicate
@@ -382,8 +393,8 @@ cdef class _Timestamp(ABCTimestamp):
             npy_datetimestruct dts_other
 
         # dispatch to the datetimestruct utils instead of writing new ones!
-        pandas_datetime_to_datetimestruct(self.value, self._creso, &dts_self)
-        pandas_datetime_to_datetimestruct(other.value, other._creso, &dts_other)
+        pandas_datetime_to_datetimestruct(self._value, self._creso, &dts_self)
+        pandas_datetime_to_datetimestruct(other._value, other._creso, &dts_other)
         return cmp_dtstructs(&dts_self,  &dts_other, op)
 
     cdef bint _compare_outside_nanorange(_Timestamp self, datetime other,
@@ -428,16 +439,16 @@ cdef class _Timestamp(ABCTimestamp):
             elif self._creso > other._creso:
                 other = (<_Timedelta>other)._as_creso(self._creso, round_ok=True)
 
-            nanos = other.value
+            nanos = other._value
 
             try:
-                new_value = self.value + nanos
+                new_value = self._value+ nanos
                 result = type(self)._from_value_and_reso(
                     new_value, reso=self._creso, tz=self.tzinfo
                 )
             except OverflowError as err:
                 # TODO: don't hard-code nanosecond here
-                new_value = int(self.value) + int(nanos)
+                new_value = int(self._value) + int(nanos)
                 raise OutOfBoundsDatetime(
                     f"Out of bounds nanosecond timestamp: {new_value}"
                 ) from err
@@ -519,7 +530,7 @@ cdef class _Timestamp(ABCTimestamp):
             # scalar Timestamp/datetime - Timestamp/datetime -> yields a
             # Timedelta
             try:
-                res_value = self.value - other.value
+                res_value = self._value- other._value
                 return Timedelta._from_value_and_reso(res_value, self._creso)
             except (OverflowError, OutOfBoundsDatetime, OutOfBoundsTimedelta) as err:
                 if isinstance(other, _Timestamp):
@@ -565,7 +576,7 @@ cdef class _Timestamp(ABCTimestamp):
             pydatetime_to_dtstruct(self, &dts)
             val = npy_datetimestruct_to_datetime(self._creso, &dts) + self.nanosecond
         else:
-            val = self.value
+            val = self._value
         return val
 
     @cython.boundscheck(False)
@@ -945,7 +956,7 @@ cdef class _Timestamp(ABCTimestamp):
         return self.__reduce__()
 
     def __setstate__(self, state):
-        self.value = state[0]
+        self._value= state[0]
         self.tzinfo = state[2]
 
         if len(state) == 3:
@@ -957,7 +968,7 @@ cdef class _Timestamp(ABCTimestamp):
         self._creso = reso
 
     def __reduce__(self):
-        object_state = self.value, None, self.tzinfo, self._creso
+        object_state = self._value, None, self.tzinfo, self._creso
         return (_unpickle_timestamp, object_state)
 
     # -----------------------------------------------------------------
@@ -1084,7 +1095,7 @@ cdef class _Timestamp(ABCTimestamp):
             return self
 
         try:
-            value = convert_reso(self.value, self._creso, creso, round_ok=round_ok)
+            value = convert_reso(self._value, self._creso, creso, round_ok=round_ok)
         except OverflowError as err:
             unit = npy_unit_to_abbrev(creso)
             raise OutOfBoundsDatetime(
@@ -1144,7 +1155,7 @@ cdef class _Timestamp(ABCTimestamp):
 
         denom = periods_per_second(self._creso)
 
-        return round(self.value / denom, 6)
+        return round(self._value/ denom, 6)
 
     cpdef datetime to_pydatetime(_Timestamp self, bint warn=True):
         """
@@ -1177,7 +1188,7 @@ cdef class _Timestamp(ABCTimestamp):
         """
         # TODO: find a way to construct dt64 directly from _reso
         abbrev = npy_unit_to_abbrev(self._creso)
-        return np.datetime64(self.value, abbrev)
+        return np.datetime64(self._value, abbrev)
 
     def to_numpy(self, dtype=None, copy=False) -> np.datetime64:
         """
@@ -1672,9 +1683,9 @@ class Timestamp(_Timestamp):
         # TODO: problem if nanos==0
 
         if self.tz is not None:
-            value = self.tz_localize(None).value
+            value = self.tz_localize(None)._value
         else:
-            value = self.value
+            value = self._value
 
         value = np.array([value], dtype=np.int64)
 
@@ -2070,13 +2081,13 @@ default 'raise'
             tz = maybe_get_tz(tz)
             if not isinstance(ambiguous, str):
                 ambiguous = [ambiguous]
-            value = tz_localize_to_utc_single(self.value, tz,
+            value = tz_localize_to_utc_single(self._value, tz,
                                               ambiguous=ambiguous,
                                               nonexistent=nonexistent,
                                               creso=self._creso)
         elif tz is None:
             # reset tz
-            value = tz_convert_from_utc_single(self.value, self.tz, creso=self._creso)
+            value = tz_convert_from_utc_single(self._value, self.tz, creso=self._creso)
 
         else:
             raise TypeError(
@@ -2136,7 +2147,7 @@ default 'raise'
         else:
             # Same UTC timestamp, different time zone
             tz = maybe_get_tz(tz)
-            out = type(self)._from_value_and_reso(self.value, reso=self._creso, tz=tz)
+            out = type(self)._from_value_and_reso(self._value, reso=self._creso, tz=tz)
             return out
 
     astimezone = tz_convert
@@ -2208,7 +2219,7 @@ default 'raise'
 
         # set to naive if needed
         tzobj = self.tzinfo
-        value = self.value
+        value = self._value
 
         # GH 37610. Preserve fold when replacing.
         if fold is None:
diff --git a/pandas/core/arrays/_ranges.py b/pandas/core/arrays/_ranges.py
index baf8470a866ff..c93fc94685358 100644
--- a/pandas/core/arrays/_ranges.py
+++ b/pandas/core/arrays/_ranges.py
@@ -46,8 +46,8 @@ def generate_regular_range(
     ndarray[np.int64]
         Representing the given resolution.
     """
-    istart = start.value if start is not None else None
-    iend = end.value if end is not None else None
+    istart = start._value if start is not None else None
+    iend = end._value if end is not None else None
     freq.nanos  # raises if non-fixed frequency
     td = Timedelta(freq)
     try:
@@ -59,7 +59,7 @@ def generate_regular_range(
             f"freq={freq} is incompatible with unit={unit}. "
             "Use a lower freq or a higher unit instead."
         ) from err
-    stride = int(td.value)
+    stride = int(td._value)
 
     if periods is None and istart is not None and iend is not None:
         b = istart
diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py
index 4b26528e6661c..437195bbcf7e9 100644
--- a/pandas/core/arrays/datetimelike.py
+++ b/pandas/core/arrays/datetimelike.py
@@ -176,7 +176,7 @@ def new_meth(self, *args, **kwargs):
         if result is NaT:
             return NaT
         elif isinstance(result, Timestamp):
-            return self._box_func(result.value)
+            return self._box_func(result._value)
 
         res_i8 = result.view("i8")
         return self._from_backing_data(res_i8)
@@ -1003,7 +1003,7 @@ def _get_i8_values_and_mask(
             i8values = other.ordinal
             mask = None
         elif isinstance(other, (Timestamp, Timedelta)):
-            i8values = other.value
+            i8values = other._value
             mask = None
         else:
             # PeriodArray, DatetimeArray, TimedeltaArray
diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py
index 49e2d3e8a6637..9daa82bb0b1e9 100644
--- a/pandas/core/arrays/datetimes.py
+++ b/pandas/core/arrays/datetimes.py
@@ -446,7 +446,7 @@ def _generate_range(  # type: ignore[override]
                 xdr = _generate_range(
                     start=start, end=end, periods=periods, offset=freq, unit=unit
                 )
-                i8values = np.array([x.value for x in xdr], dtype=np.int64)
+                i8values = np.array([x._value for x in xdr], dtype=np.int64)
 
             endpoint_tz = start.tz if start is not None else end.tz
 
@@ -476,8 +476,8 @@ def _generate_range(  # type: ignore[override]
             # representable with doubles, so we limit the range that we
             # pass to np.linspace as much as possible
             i8values = (
-                np.linspace(0, end.value - start.value, periods, dtype="int64")
-                + start.value
+                np.linspace(0, end._value - start._value, periods, dtype="int64")
+                + start._value
             )
             if i8values.dtype != "i8":
                 # 2022-01-09 I (brock) am not sure if it is possible for this
@@ -488,8 +488,8 @@ def _generate_range(  # type: ignore[override]
             if not left_inclusive and not right_inclusive:
                 i8values = i8values[1:-1]
         else:
-            start_i8 = Timestamp(start).value
-            end_i8 = Timestamp(end).value
+            start_i8 = Timestamp(start)._value
+            end_i8 = Timestamp(end)._value
             if not left_inclusive or not right_inclusive:
                 if not left_inclusive and len(i8values) and i8values[0] == start_i8:
                     i8values = i8values[1:]
@@ -508,7 +508,7 @@ def _unbox_scalar(self, value) -> np.datetime64:
             raise ValueError("'value' should be a Timestamp.")
         self._check_compatible_with(value)
         if value is NaT:
-            return np.datetime64(value.value, self.unit)
+            return np.datetime64(value._value, self.unit)
         else:
             return value.as_unit(self.unit).asm8
 
diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py
index e6682b0dea814..da1c94101b785 100644
--- a/pandas/core/arrays/period.py
+++ b/pandas/core/arrays/period.py
@@ -331,7 +331,7 @@ def _unbox_scalar(  # type: ignore[override]
     ) -> np.int64:
         if value is NaT:
             # error: Item "Period" of "Union[Period, NaTType]" has no attribute "value"
-            return np.int64(value.value)  # type: ignore[union-attr]
+            return np.int64(value._value)  # type: ignore[union-attr]
         elif isinstance(value, self._scalar_type):
             self._check_compatible_with(value)
             return np.int64(value.ordinal)
diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py
index 861c9712cd2ae..4c9c1e234de3f 100644
--- a/pandas/core/arrays/timedeltas.py
+++ b/pandas/core/arrays/timedeltas.py
@@ -151,7 +151,7 @@ def _scalar_type(self) -> type[Timedelta]:
 
     def _box_func(self, x: np.timedelta64) -> Timedelta | NaTType:
         y = x.view("i8")
-        if y == NaT.value:
+        if y == NaT._value:
             return NaT
         return Timedelta._from_value_and_reso(y, reso=self._creso)
 
@@ -298,7 +298,7 @@ def _generate_range(  # type: ignore[override]
         if freq is not None:
             index = generate_regular_range(start, end, periods, freq, unit=unit)
         else:
-            index = np.linspace(start.value, end.value, periods).astype("i8")
+            index = np.linspace(start._value, end._value, periods).astype("i8")
 
         if not left_closed:
             index = index[1:]
@@ -316,7 +316,7 @@ def _unbox_scalar(self, value) -> np.timedelta64:
             raise ValueError("'value' should be a Timedelta.")
         self._check_compatible_with(value)
         if value is NaT:
-            return np.timedelta64(value.value, self.unit)
+            return np.timedelta64(value._value, self.unit)
         else:
             return value.as_unit(self.unit).asm8
 
diff --git a/pandas/core/computation/pytables.py b/pandas/core/computation/pytables.py
index 04a6f6c6277ee..f7d1314b12da2 100644
--- a/pandas/core/computation/pytables.py
+++ b/pandas/core/computation/pytables.py
@@ -218,13 +218,13 @@ def stringify(value):
             v = Timestamp(v).as_unit("ns")
             if v.tz is not None:
                 v = v.tz_convert("UTC")
-            return TermValue(v, v.value, kind)
+            return TermValue(v, v._value, kind)
         elif kind in ("timedelta64", "timedelta"):
             if isinstance(v, str):
                 v = Timedelta(v)
             else:
                 v = Timedelta(v, unit="s")
-            v = v.as_unit("ns").value
+            v = v.as_unit("ns")._value
             return TermValue(int(v), v, kind)
         elif meta == "category":
             metadata = extract_array(self.metadata, extract_numpy=True)
diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py
index 3be89f6da2bd8..f0b309638321c 100644
--- a/pandas/core/dtypes/cast.py
+++ b/pandas/core/dtypes/cast.py
@@ -814,7 +814,7 @@ def infer_dtype_from_scalar(val, pandas_dtype: bool = False) -> tuple[DtypeObj,
             dtype = _dtype_obj
         else:
             dtype = np.dtype("m8[ns]")
-            val = np.timedelta64(val.value, "ns")
+            val = np.timedelta64(val._value, "ns")
 
     elif is_bool(val):
         dtype = np.dtype(np.bool_)
diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py
index ea0c93e75f496..c5739ad150c8d 100644
--- a/pandas/core/indexes/datetimelike.py
+++ b/pandas/core/indexes/datetimelike.py
@@ -469,8 +469,8 @@ def _as_range_index(self) -> RangeIndex:
         # Convert our i8 representations to RangeIndex
         # Caller is responsible for checking isinstance(self.freq, Tick)
         freq = cast(Tick, self.freq)
-        tick = freq.delta.value
-        rng = range(self[0].value, self[-1].value + tick, tick)
+        tick = freq.delta._value
+        rng = range(self[0]._value, self[-1]._value + tick, tick)
         return RangeIndex(rng)
 
     def _can_range_setop(self, other):
diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py
index 3b0b5d1d55a88..69dacb043010a 100644
--- a/pandas/core/indexes/interval.py
+++ b/pandas/core/indexes/interval.py
@@ -546,7 +546,7 @@ def _maybe_convert_i8(self, key):
             if lib.is_period(key):
                 key_i8 = key.ordinal
             elif isinstance(key_i8, Timestamp):
-                key_i8 = key_i8.value
+                key_i8 = key_i8._value
             elif isinstance(key_i8, (np.datetime64, np.timedelta64)):
                 key_i8 = key_i8.view("i8")
         else:
diff --git a/pandas/core/internals/concat.py b/pandas/core/internals/concat.py
index d46b51a2ee954..0e1c00b8a97b7 100644
--- a/pandas/core/internals/concat.py
+++ b/pandas/core/internals/concat.py
@@ -524,7 +524,7 @@ def get_reindexed_values(self, empty_dtype: DtypeObj, upcasted_na) -> ArrayLike:
 
                 if isinstance(empty_dtype, DatetimeTZDtype):
                     # NB: exclude e.g. pyarrow[dt64tz] dtypes
-                    i8values = np.full(self.shape, fill_value.value)
+                    i8values = np.full(self.shape, fill_value._value)
                     return DatetimeArray(i8values, dtype=empty_dtype)
 
                 elif is_1d_only_ea_dtype(empty_dtype):
diff --git a/pandas/core/resample.py b/pandas/core/resample.py
index d3b3c844e8c4e..95a0bae85e03e 100644
--- a/pandas/core/resample.py
+++ b/pandas/core/resample.py
@@ -2103,19 +2103,19 @@ def _adjust_dates_anchored(
 
     origin_nanos = 0  # origin == "epoch"
     if origin == "start_day":
-        origin_nanos = first.normalize().value
+        origin_nanos = first.normalize()._value
     elif origin == "start":
-        origin_nanos = first.value
+        origin_nanos = first._value
     elif isinstance(origin, Timestamp):
-        origin_nanos = origin.as_unit("ns").value
+        origin_nanos = origin.as_unit("ns")._value
     elif origin in ["end", "end_day"]:
         origin_last = last if origin == "end" else last.ceil("D")
-        sub_freq_times = (origin_last.value - first.value) // freq.nanos
+        sub_freq_times = (origin_last._value - first._value) // freq.nanos
         if closed == "left":
             sub_freq_times += 1
         first = origin_last - sub_freq_times * freq
-        origin_nanos = first.value
-    origin_nanos += offset.value if offset else 0
+        origin_nanos = first._value
+    origin_nanos += offset._value if offset else 0
 
     # GH 10117 & GH 19375. If first and last contain timezone information,
     # Perform the calculation in UTC in order to avoid localizing on an
@@ -2127,34 +2127,34 @@ def _adjust_dates_anchored(
     if last_tzinfo is not None:
         last = last.tz_convert("UTC")
 
-    foffset = (first.value - origin_nanos) % freq.nanos
-    loffset = (last.value - origin_nanos) % freq.nanos
+    foffset = (first._value - origin_nanos) % freq.nanos
+    loffset = (last._value - origin_nanos) % freq.nanos
 
     if closed == "right":
         if foffset > 0:
             # roll back
-            fresult_int = first.value - foffset
+            fresult_int = first._value - foffset
         else:
-            fresult_int = first.value - freq.nanos
+            fresult_int = first._value - freq.nanos
 
         if loffset > 0:
             # roll forward
-            lresult_int = last.value + (freq.nanos - loffset)
+            lresult_int = last._value + (freq.nanos - loffset)
         else:
             # already the end of the road
-            lresult_int = last.value
+            lresult_int = last._value
     else:  # closed == 'left'
         if foffset > 0:
-            fresult_int = first.value - foffset
+            fresult_int = first._value - foffset
         else:
             # start of the road
-            fresult_int = first.value
+            fresult_int = first._value
 
         if loffset > 0:
             # roll forward
-            lresult_int = last.value + (freq.nanos - loffset)
+            lresult_int = last._value + (freq.nanos - loffset)
         else:
-            lresult_int = last.value + freq.nanos
+            lresult_int = last._value + freq.nanos
     fresult = Timestamp(fresult_int)
     lresult = Timestamp(lresult_int)
     if first_tzinfo is not None:
diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py
index 7d8d7a37ff7e7..ad403ae19a274 100644
--- a/pandas/core/reshape/merge.py
+++ b/pandas/core/reshape/merge.py
@@ -2123,7 +2123,7 @@ def injection(obj):
                     lvs = ensure_wrapped_if_datetimelike(left_values)
                     tolerance = tolerance.as_unit(lvs.unit)
 
-                tolerance = tolerance.value
+                tolerance = tolerance._value
 
             # TODO: require left_values.dtype == right_values.dtype, or at least
             #  comparable for e.g. dt64tz
diff --git a/pandas/core/tools/datetimes.py b/pandas/core/tools/datetimes.py
index 152bfcb8822a4..76e144c70c7d5 100644
--- a/pandas/core/tools/datetimes.py
+++ b/pandas/core/tools/datetimes.py
@@ -518,8 +518,8 @@ def _to_datetime_with_unit(arg, unit, name, utc: bool, errors: str) -> Index:
             fvalues = (arg * mult).astype("f8", copy=False)
             fvalues[mask] = 0
 
-            if (fvalues < Timestamp.min.value).any() or (
-                fvalues > Timestamp.max.value
+            if (fvalues < Timestamp.min._value).any() or (
+                fvalues > Timestamp.max._value
             ).any():
                 if errors != "raise":
                     arg = arg.astype(object)
diff --git a/pandas/core/window/ewm.py b/pandas/core/window/ewm.py
index c0a7b2b7cc361..b61fa9a92539e 100644
--- a/pandas/core/window/ewm.py
+++ b/pandas/core/window/ewm.py
@@ -117,7 +117,7 @@ def _calculate_deltas(
     """
     _times = np.asarray(times.view(np.int64), dtype=np.float64)
     # TODO: generalize to non-nano?
-    _halflife = float(Timedelta(halflife).as_unit("ns").value)
+    _halflife = float(Timedelta(halflife).as_unit("ns")._value)
     return np.diff(_times) / _halflife
 
 
diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py
index ceb84161528cc..213acdadfddbc 100644
--- a/pandas/tests/arithmetic/test_datetime64.py
+++ b/pandas/tests/arithmetic/test_datetime64.py
@@ -1719,15 +1719,15 @@ def test_datetimeindex_sub_timestamp_overflow(self):
             with pytest.raises(OverflowError, match=msg):
                 dtimax - variant
 
-        expected = Timestamp.max.value - tspos.value
+        expected = Timestamp.max._value - tspos._value
         for variant in ts_pos_variants:
             res = dtimax - variant
-            assert res[1].value == expected
+            assert res[1]._value == expected
 
-        expected = Timestamp.min.value - tsneg.value
+        expected = Timestamp.min._value - tsneg._value
         for variant in ts_neg_variants:
             res = dtimin - variant
-            assert res[1].value == expected
+            assert res[1]._value == expected
 
         for variant in ts_pos_variants:
             with pytest.raises(OverflowError, match=msg):
@@ -1742,13 +1742,13 @@ def test_datetimeindex_sub_datetimeindex_overflow(self):
         ts_pos = pd.to_datetime(["1980-01-01", "1980-01-01"])
 
         # General tests
-        expected = Timestamp.max.value - ts_pos[1].value
+        expected = Timestamp.max._value - ts_pos[1]._value
         result = dtimax - ts_pos
-        assert result[1].value == expected
+        assert result[1]._value == expected
 
-        expected = Timestamp.min.value - ts_neg[1].value
+        expected = Timestamp.min._value - ts_neg[1]._value
         result = dtimin - ts_neg
-        assert result[1].value == expected
+        assert result[1]._value == expected
         msg = "Overflow in int64 addition"
         with pytest.raises(OverflowError, match=msg):
             dtimax - ts_neg
@@ -2442,4 +2442,4 @@ def test_dt64arr_addsub_object_dtype_2d():
         result2 = dta - dta.astype(object)
 
     assert result2.shape == (4, 1)
-    assert all(td.value == 0 for td in result2.ravel())
+    assert all(td._value == 0 for td in result2.ravel())
diff --git a/pandas/tests/arithmetic/test_timedelta64.py b/pandas/tests/arithmetic/test_timedelta64.py
index 0a79822d26e9a..65d39f7c7b9fb 100644
--- a/pandas/tests/arithmetic/test_timedelta64.py
+++ b/pandas/tests/arithmetic/test_timedelta64.py
@@ -690,7 +690,7 @@ def test_tdi_add_overflow(self):
         with pytest.raises(OutOfBoundsDatetime, match="10155196800000000000"):
             Timestamp("2000") + pd.to_timedelta(106580, "D")
 
-        _NaT = NaT.value + 1
+        _NaT = NaT._value + 1
         msg = "Overflow in int64 addition"
         with pytest.raises(OverflowError, match=msg):
             pd.to_timedelta([106580], "D") + Timestamp("2000")
@@ -754,7 +754,7 @@ def test_timedelta_ops_with_missing_values(self):
             #  supported GH#29794
             DataFrame([NaT]).apply(pd.to_timedelta)  # TODO: belongs elsewhere?
 
-        dfn = DataFrame([NaT.value]).apply(pd.to_timedelta)
+        dfn = DataFrame([NaT._value]).apply(pd.to_timedelta)
 
         scalar1 = pd.to_timedelta("00:00:01")
         scalar2 = pd.to_timedelta("00:00:02")
diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py
index f80051fb187ba..362abee1d482a 100644
--- a/pandas/tests/arrays/test_datetimelike.py
+++ b/pandas/tests/arrays/test_datetimelike.py
@@ -339,7 +339,7 @@ def test_searchsorted_castable_strings(self, arr1d, box, string_storage):
     def test_getitem_near_implementation_bounds(self):
         # We only check tz-naive for DTA bc the bounds are slightly different
         #  for other tzs
-        i8vals = np.asarray([NaT.value + n for n in range(1, 5)], dtype="i8")
+        i8vals = np.asarray([NaT._value + n for n in range(1, 5)], dtype="i8")
         arr = self.array_cls(i8vals, freq="ns")
         arr[0]  # should not raise OutOfBoundsDatetime
 
@@ -815,7 +815,7 @@ def test_take_fill_valid(self, arr1d, fixed_now_ts):
             # Timestamp with mismatched tz-awareness
             arr.take([-1, 1], allow_fill=True, fill_value=now)
 
-        value = NaT.value
+        value = NaT._value
         msg = f"value should be a '{arr1d._scalar_type.__name__}' or 'NaT'. Got"
         with pytest.raises(TypeError, match=msg):
             # require NaT, not iNaT, as it could be confused with an integer
@@ -1038,7 +1038,7 @@ def test_astype_object(self, arr1d):
     def test_take_fill_valid(self, arr1d):
         arr = arr1d
 
-        value = NaT.value
+        value = NaT._value
         msg = f"value should be a '{arr1d._scalar_type.__name__}' or 'NaT'. Got"
         with pytest.raises(TypeError, match=msg):
             # require NaT, not iNaT, as it could be confused with an integer
@@ -1181,15 +1181,15 @@ def test_casting_nat_setitem_array(arr, casting_nats):
     [
         (
             TimedeltaIndex(["1 Day", "3 Hours", "NaT"])._data,
-            (np.datetime64("NaT", "ns"), NaT.value),
+            (np.datetime64("NaT", "ns"), NaT._value),
         ),
         (
             pd.date_range("2000-01-01", periods=3, freq="D")._data,
-            (np.timedelta64("NaT", "ns"), NaT.value),
+            (np.timedelta64("NaT", "ns"), NaT._value),
         ),
         (
             pd.period_range("2000-01-01", periods=3, freq="D")._data,
-            (np.datetime64("NaT", "ns"), np.timedelta64("NaT", "ns"), NaT.value),
+            (np.datetime64("NaT", "ns"), np.timedelta64("NaT", "ns"), NaT._value),
         ),
     ],
     ids=lambda x: type(x).__name__,
diff --git a/pandas/tests/arrays/test_datetimes.py b/pandas/tests/arrays/test_datetimes.py
index 53c9b3d174967..4bd6fd745d56d 100644
--- a/pandas/tests/arrays/test_datetimes.py
+++ b/pandas/tests/arrays/test_datetimes.py
@@ -132,7 +132,7 @@ def test_iter(self, dta):
         expected = dta[0]
 
         assert type(res) is pd.Timestamp
-        assert res.value == expected.value
+        assert res._value == expected._value
         assert res._creso == expected._creso
         assert res == expected
 
diff --git a/pandas/tests/dtypes/test_missing.py b/pandas/tests/dtypes/test_missing.py
index b9aa84aefd2cb..b62d3c96cd137 100644
--- a/pandas/tests/dtypes/test_missing.py
+++ b/pandas/tests/dtypes/test_missing.py
@@ -801,8 +801,8 @@ def test_empty_like(self):
 
 int_na_vals = [
     # Values that match iNaT, which we treat as null in specific cases
-    np.int64(NaT.value),
-    int(NaT.value),
+    np.int64(NaT._value),
+    int(NaT._value),
 ]
 
 sometimes_na_vals = [Decimal("NaN")]
diff --git a/pandas/tests/frame/methods/test_sort_values.py b/pandas/tests/frame/methods/test_sort_values.py
index 43fcb25d122fb..026c3ae7011a0 100644
--- a/pandas/tests/frame/methods/test_sort_values.py
+++ b/pandas/tests/frame/methods/test_sort_values.py
@@ -355,7 +355,7 @@ def test_sort_values_nat_values_in_int_column(self):
         # cause was that the int64 value NaT was considered as "na". Which is
         # only correct for datetime64 columns.
 
-        int_values = (2, int(NaT.value))
+        int_values = (2, int(NaT._value))
         float_values = (2.0, -1.797693e308)
 
         df = DataFrame(
diff --git a/pandas/tests/groupby/test_function.py b/pandas/tests/groupby/test_function.py
index 1ef97fed7ba05..041a45496d8e9 100644
--- a/pandas/tests/groupby/test_function.py
+++ b/pandas/tests/groupby/test_function.py
@@ -927,7 +927,7 @@ def test_cummax(dtypes_for_minmax):
 def test_cummax_i8_at_implementation_bound():
     # the minimum value used to be treated as NPY_NAT+1 instead of NPY_NAT
     #  for int64 dtype GH#46382
-    ser = Series([pd.NaT.value + n for n in range(5)])
+    ser = Series([pd.NaT._value + n for n in range(5)])
     df = DataFrame({"A": 1, "B": ser, "C": ser.view("M8[ns]")})
     gb = df.groupby("A")
 
diff --git a/pandas/tests/indexes/datetimes/methods/test_astype.py b/pandas/tests/indexes/datetimes/methods/test_astype.py
index 007204fd83bd4..8cf1edf5c7bf3 100644
--- a/pandas/tests/indexes/datetimes/methods/test_astype.py
+++ b/pandas/tests/indexes/datetimes/methods/test_astype.py
@@ -267,7 +267,7 @@ def _check_rng(rng):
     )
     def test_integer_index_astype_datetime(self, tz, dtype):
         # GH 20997, 20964, 24559
-        val = [Timestamp("2018-01-01", tz=tz).as_unit("ns").value]
+        val = [Timestamp("2018-01-01", tz=tz).as_unit("ns")._value]
         result = Index(val, name="idx").astype(dtype)
         expected = DatetimeIndex(["2018-01-01"], tz=tz, name="idx")
         tm.assert_index_equal(result, expected)
diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py
index 1d82d3d9c5b9d..175f435fe9696 100644
--- a/pandas/tests/indexes/datetimes/test_constructors.py
+++ b/pandas/tests/indexes/datetimes/test_constructors.py
@@ -73,7 +73,7 @@ def test_freq_validation_with_nat(self, dt_cls):
         with pytest.raises(ValueError, match=msg):
             dt_cls([pd.NaT, Timestamp("2011-01-01")], freq="D")
         with pytest.raises(ValueError, match=msg):
-            dt_cls([pd.NaT, Timestamp("2011-01-01").value], freq="D")
+            dt_cls([pd.NaT, Timestamp("2011-01-01")._value], freq="D")
 
     # TODO: better place for tests shared by DTI/TDI?
     @pytest.mark.parametrize(
@@ -805,7 +805,7 @@ def test_constructor_timestamp_near_dst(self):
     def test_constructor_with_int_tz(self, klass, box, tz, dtype):
         # GH 20997, 20964
         ts = Timestamp("2018-01-01", tz=tz).as_unit("ns")
-        result = klass(box([ts.value]), dtype=dtype)
+        result = klass(box([ts._value]), dtype=dtype)
         expected = klass([ts])
         assert result == expected
 
@@ -1200,6 +1200,6 @@ def test_timestamp_constructor_adjust_value_for_fold(tz, ts_input, fold, value_o
     # Check that we adjust value for fold correctly
     # based on timestamps since utc
     ts = Timestamp(ts_input, tz=tz, fold=fold)
-    result = ts.value
+    result = ts._value
     expected = value_out
     assert result == expected
diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py
index 8979d99675589..ef909feccfcd3 100644
--- a/pandas/tests/indexes/datetimes/test_date_range.py
+++ b/pandas/tests/indexes/datetimes/test_date_range.py
@@ -1236,7 +1236,7 @@ def test_date_range_freq_lower_than_endpoints(self):
         # but we can losslessly cast to "us"
         dti = date_range(start, end, periods=2, unit="us")
         rng = np.array(
-            [start.as_unit("us").value, end.as_unit("us").value], dtype=np.int64
+            [start.as_unit("us")._value, end.as_unit("us")._value], dtype=np.int64
         )
         expected = DatetimeIndex(rng.view("M8[us]"))
         tm.assert_index_equal(dti, expected)
diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py
index 04d1d8204a346..ecdea9ea25c9d 100644
--- a/pandas/tests/indexes/datetimes/test_indexing.py
+++ b/pandas/tests/indexes/datetimes/test_indexing.py
@@ -175,7 +175,7 @@ def test_where_invalid_dtypes(self):
         tm.assert_index_equal(result, expected)
 
         result = dti.where(mask, i2.asi8)
-        expected = Index([pd.NaT.value, pd.NaT.value] + tail, dtype=object)
+        expected = Index([pd.NaT._value, pd.NaT._value] + tail, dtype=object)
         assert isinstance(expected[0], int)
         tm.assert_index_equal(result, expected)
 
diff --git a/pandas/tests/indexes/datetimes/test_timezones.py b/pandas/tests/indexes/datetimes/test_timezones.py
index 65207a4d7a60f..05700841de7e1 100644
--- a/pandas/tests/indexes/datetimes/test_timezones.py
+++ b/pandas/tests/indexes/datetimes/test_timezones.py
@@ -1138,7 +1138,7 @@ def test_dti_convert_tz_aware_datetime_datetime(self, tz):
         assert timezones.tz_compare(result.tz, tz)
 
         converted = to_datetime(dates_aware, utc=True)
-        ex_vals = np.array([Timestamp(x).as_unit("ns").value for x in dates_aware])
+        ex_vals = np.array([Timestamp(x).as_unit("ns")._value for x in dates_aware])
         tm.assert_numpy_array_equal(converted.asi8, ex_vals)
         assert converted.tz is timezone.utc
 
diff --git a/pandas/tests/indexes/datetimes/test_unique.py b/pandas/tests/indexes/datetimes/test_unique.py
index 68ac770f612e6..c18bd99b67000 100644
--- a/pandas/tests/indexes/datetimes/test_unique.py
+++ b/pandas/tests/indexes/datetimes/test_unique.py
@@ -55,7 +55,7 @@ def test_index_unique(rand_series_with_duplicate_datetimeindex):
 
 def test_index_unique2():
     # NaT, note this is excluded
-    arr = [1370745748 + t for t in range(20)] + [NaT.value]
+    arr = [1370745748 + t for t in range(20)] + [NaT._value]
     idx = DatetimeIndex(arr * 3)
     tm.assert_index_equal(idx.unique(), DatetimeIndex(arr))
     assert idx.nunique() == 20
diff --git a/pandas/tests/indexes/interval/test_interval.py b/pandas/tests/indexes/interval/test_interval.py
index a809af7e975e2..dedc3fdd00e08 100644
--- a/pandas/tests/indexes/interval/test_interval.py
+++ b/pandas/tests/indexes/interval/test_interval.py
@@ -378,7 +378,7 @@ def test_maybe_convert_i8(self, breaks):
         # interval
         interval = Interval(breaks[0], breaks[1])
         result = index._maybe_convert_i8(interval)
-        expected = Interval(breaks[0].value, breaks[1].value)
+        expected = Interval(breaks[0]._value, breaks[1]._value)
         assert result == expected
 
         # datetimelike index
@@ -388,7 +388,7 @@ def test_maybe_convert_i8(self, breaks):
 
         # datetimelike scalar
         result = index._maybe_convert_i8(breaks[0])
-        expected = breaks[0].value
+        expected = breaks[0]._value
         assert result == expected
 
         # list-like of datetimelike scalars
@@ -410,7 +410,7 @@ def test_maybe_convert_i8_nat(self, breaks):
         tm.assert_index_equal(result, expected)
 
         to_convert = to_convert.insert(0, breaks[0])
-        expected = expected.insert(0, float(breaks[0].value))
+        expected = expected.insert(0, float(breaks[0]._value))
         result = index._maybe_convert_i8(to_convert)
         tm.assert_index_equal(result, expected)
 
diff --git a/pandas/tests/indexes/period/test_indexing.py b/pandas/tests/indexes/period/test_indexing.py
index 2db1e8c72a87c..228fd2829c5d9 100644
--- a/pandas/tests/indexes/period/test_indexing.py
+++ b/pandas/tests/indexes/period/test_indexing.py
@@ -570,7 +570,7 @@ def test_where_invalid_dtypes(self):
         mask = notna(i2)
 
         result = pi.where(mask, i2.asi8)
-        expected = pd.Index([NaT.value, NaT.value] + tail, dtype=object)
+        expected = pd.Index([NaT._value, NaT._value] + tail, dtype=object)
         assert isinstance(expected[0], int)
         tm.assert_index_equal(result, expected)
 
diff --git a/pandas/tests/indexes/test_engines.py b/pandas/tests/indexes/test_engines.py
index 02d8c5b2a6a22..a4b7ce6822b80 100644
--- a/pandas/tests/indexes/test_engines.py
+++ b/pandas/tests/indexes/test_engines.py
@@ -32,7 +32,7 @@ class TestDatetimeEngine:
         "scalar",
         [
             pd.Timedelta(pd.Timestamp("2016-01-01").asm8.view("m8[ns]")),
-            pd.Timestamp("2016-01-01").value,
+            pd.Timestamp("2016-01-01")._value,
             pd.Timestamp("2016-01-01").to_pydatetime(),
             pd.Timestamp("2016-01-01").to_datetime64(),
         ],
@@ -58,7 +58,7 @@ class TestTimedeltaEngine:
         "scalar",
         [
             pd.Timestamp(pd.Timedelta(days=42).asm8.view("datetime64[ns]")),
-            pd.Timedelta(days=42).value,
+            pd.Timedelta(days=42)._value,
             pd.Timedelta(days=42).to_pytimedelta(),
             pd.Timedelta(days=42).to_timedelta64(),
         ],
diff --git a/pandas/tests/indexes/timedeltas/test_indexing.py b/pandas/tests/indexes/timedeltas/test_indexing.py
index cc166f9f32a34..2d2711520d44f 100644
--- a/pandas/tests/indexes/timedeltas/test_indexing.py
+++ b/pandas/tests/indexes/timedeltas/test_indexing.py
@@ -144,7 +144,7 @@ def test_where_invalid_dtypes(self, fixed_now_ts):
         i2 = Index([NaT, NaT] + tail)
         mask = notna(i2)
 
-        expected = Index([NaT.value, NaT.value] + tail, dtype=object, name="idx")
+        expected = Index([NaT._value, NaT._value] + tail, dtype=object, name="idx")
         assert isinstance(expected[0], int)
         result = tdi.where(mask, i2.asi8)
         tm.assert_index_equal(result, expected)
diff --git a/pandas/tests/indexing/test_datetime.py b/pandas/tests/indexing/test_datetime.py
index dc2fe85679181..e21bc6a4850a3 100644
--- a/pandas/tests/indexing/test_datetime.py
+++ b/pandas/tests/indexing/test_datetime.py
@@ -16,7 +16,7 @@
 class TestDatetimeIndex:
     def test_get_loc_naive_dti_aware_str_deprecated(self):
         # GH#46903
-        ts = Timestamp("20130101").value
+        ts = Timestamp("20130101")._value
         dti = pd.DatetimeIndex([ts + 50 + i for i in range(100)])
         ser = Series(range(100), index=dti)
 
diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py
index 34ecc75769d0b..8aff76c0e1fee 100644
--- a/pandas/tests/indexing/test_loc.py
+++ b/pandas/tests/indexing/test_loc.py
@@ -2560,9 +2560,9 @@ def test_loc_setitem_mask_td64_series_value(self):
         df_copy = df.copy()
         ser = Series([td1])
 
-        expected = df["col"].iloc[1].value
+        expected = df["col"].iloc[1]._value
         df.loc[[True, False]] = ser
-        result = df["col"].iloc[1].value
+        result = df["col"].iloc[1]._value
 
         assert expected == result
         tm.assert_frame_equal(df, df_copy)
diff --git a/pandas/tests/io/json/test_pandas.py b/pandas/tests/io/json/test_pandas.py
index 7b473a56aa200..e6fe7d0cc26c4 100644
--- a/pandas/tests/io/json/test_pandas.py
+++ b/pandas/tests/io/json/test_pandas.py
@@ -1001,7 +1001,7 @@ def test_mixed_timedelta_datetime(self):
         frame = DataFrame({"a": [td, ts]}, dtype=object)
 
         expected = DataFrame(
-            {"a": [pd.Timedelta(td).as_unit("ns").value, ts.as_unit("ns").value]}
+            {"a": [pd.Timedelta(td).as_unit("ns")._value, ts.as_unit("ns")._value]}
         )
         result = read_json(frame.to_json(date_unit="ns"), dtype={"a": "int64"})
         tm.assert_frame_equal(result, expected, check_index_type=False)
diff --git a/pandas/tests/io/json/test_ujson.py b/pandas/tests/io/json/test_ujson.py
index a5d7a16f77a72..472b08963425b 100644
--- a/pandas/tests/io/json/test_ujson.py
+++ b/pandas/tests/io/json/test_ujson.py
@@ -395,16 +395,16 @@ def test_datetime_units(self):
         stamp = Timestamp(val).as_unit("ns")
 
         roundtrip = ujson.decode(ujson.encode(val, date_unit="s"))
-        assert roundtrip == stamp.value // 10**9
+        assert roundtrip == stamp._value // 10**9
 
         roundtrip = ujson.decode(ujson.encode(val, date_unit="ms"))
-        assert roundtrip == stamp.value // 10**6
+        assert roundtrip == stamp._value // 10**6
 
         roundtrip = ujson.decode(ujson.encode(val, date_unit="us"))
-        assert roundtrip == stamp.value // 10**3
+        assert roundtrip == stamp._value // 10**3
 
         roundtrip = ujson.decode(ujson.encode(val, date_unit="ns"))
-        assert roundtrip == stamp.value
+        assert roundtrip == stamp._value
 
         msg = "Invalid value 'foo' for option 'date_unit'"
         with pytest.raises(ValueError, match=msg):
diff --git a/pandas/tests/io/pytables/test_timezones.py b/pandas/tests/io/pytables/test_timezones.py
index ba125ffd28581..058eaa9d0529d 100644
--- a/pandas/tests/io/pytables/test_timezones.py
+++ b/pandas/tests/io/pytables/test_timezones.py
@@ -159,7 +159,7 @@ def test_roundtrip_tz_aware_index(setup_path):
         store.put("frame", df, format="fixed")
         recons = store["frame"]
         tm.assert_frame_equal(recons, df)
-        assert recons.index[0].value == 946706400000000000
+        assert recons.index[0]._value == 946706400000000000
 
 
 def test_store_index_name_with_tz(setup_path):
diff --git a/pandas/tests/reductions/test_reductions.py b/pandas/tests/reductions/test_reductions.py
index e0ae3da482b35..88e62ea0bc79a 100644
--- a/pandas/tests/reductions/test_reductions.py
+++ b/pandas/tests/reductions/test_reductions.py
@@ -63,7 +63,7 @@ def test_ops(self, opname, obj):
         if getattr(obj, "tz", None) is not None:
             # We need to de-localize before comparing to the numpy-produced result
             expected = expected.astype("M8[ns]").astype("int64")
-            assert result.value == expected
+            assert result._value == expected
         else:
             assert result == expected
 
diff --git a/pandas/tests/scalar/period/test_asfreq.py b/pandas/tests/scalar/period/test_asfreq.py
index 386ab4150c6ff..e652c63d46f18 100644
--- a/pandas/tests/scalar/period/test_asfreq.py
+++ b/pandas/tests/scalar/period/test_asfreq.py
@@ -668,7 +668,7 @@ def test_conv_microsecond(self):
         start = per.start_time
         expected = Timestamp("2020-01-30 15:57:27.576166")
         assert start == expected
-        assert start.value == per.ordinal * 1000
+        assert start._value == per.ordinal * 1000
 
         per2 = Period("2300-01-01", "us")
         msg = "2300-01-01"
diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py
index bb9a7dd9374b5..88b1bda6b645c 100644
--- a/pandas/tests/scalar/period/test_period.py
+++ b/pandas/tests/scalar/period/test_period.py
@@ -627,7 +627,7 @@ def test_to_timestamp(self):
         def _ex(p):
             if p.freq == "B":
                 return p.start_time + Timedelta(days=1, nanoseconds=-1)
-            return Timestamp((p + p.freq).start_time.value - 1)
+            return Timestamp((p + p.freq).start_time._value - 1)
 
         for fcode in from_lst:
             p = Period("1982", freq=fcode)
@@ -839,7 +839,7 @@ def test_end_time(self):
         p = Period("2012", freq="A")
 
         def _ex(*args):
-            return Timestamp(Timestamp(datetime(*args)).as_unit("ns").value - 1)
+            return Timestamp(Timestamp(datetime(*args)).as_unit("ns")._value - 1)
 
         xp = _ex(2013, 1, 1)
         assert xp == p.end_time
@@ -891,7 +891,7 @@ def test_end_time_business_friday(self):
 
     def test_anchor_week_end_time(self):
         def _ex(*args):
-            return Timestamp(Timestamp(datetime(*args)).as_unit("ns").value - 1)
+            return Timestamp(Timestamp(datetime(*args)).as_unit("ns")._value - 1)
 
         p = Period("2013-1-1", "W-SAT")
         xp = _ex(2013, 1, 6)
diff --git a/pandas/tests/scalar/test_nat.py b/pandas/tests/scalar/test_nat.py
index e310506935729..3192baacb4ef4 100644
--- a/pandas/tests/scalar/test_nat.py
+++ b/pandas/tests/scalar/test_nat.py
@@ -110,7 +110,7 @@ def test_equality(klass, value, request):
             pytest.mark.xfail(reason="Period cannot parse empty string")
         )
 
-    assert klass(value).value == iNaT
+    assert klass(value)._value == iNaT
 
 
 @pytest.mark.parametrize("klass", [Timestamp, Timedelta])
diff --git a/pandas/tests/scalar/timedelta/test_arithmetic.py b/pandas/tests/scalar/timedelta/test_arithmetic.py
index cbb53ed2b8e36..01ec11c306dcd 100644
--- a/pandas/tests/scalar/timedelta/test_arithmetic.py
+++ b/pandas/tests/scalar/timedelta/test_arithmetic.py
@@ -393,8 +393,8 @@ def test_td_mul_scalar(self, op):
 
         assert op(td, np.nan) is NaT
 
-        assert op(-1, td).value == -1 * td.value
-        assert op(-1.0, td).value == -1.0 * td.value
+        assert op(-1, td)._value == -1 * td._value
+        assert op(-1.0, td)._value == -1.0 * td._value
 
         msg = "unsupported operand type"
         with pytest.raises(TypeError, match=msg):
@@ -463,11 +463,11 @@ def test_td_div_td64_non_nano(self):
         # truediv
         td = Timedelta("1 days 2 hours 3 ns")
         result = td / np.timedelta64(1, "D")
-        assert result == td.value / (86400 * 10**9)
+        assert result == td._value / (86400 * 10**9)
         result = td / np.timedelta64(1, "s")
-        assert result == td.value / 10**9
+        assert result == td._value / 10**9
         result = td / np.timedelta64(1, "ns")
-        assert result == td.value
+        assert result == td._value
 
         # floordiv
         td = Timedelta("1 days 2 hours 3 ns")
@@ -476,7 +476,7 @@ def test_td_div_td64_non_nano(self):
         result = td // np.timedelta64(1, "s")
         assert result == 93600
         result = td // np.timedelta64(1, "ns")
-        assert result == td.value
+        assert result == td._value
 
     def test_td_div_numeric_scalar(self):
         # GH#19738
diff --git a/pandas/tests/scalar/timedelta/test_constructors.py b/pandas/tests/scalar/timedelta/test_constructors.py
index e4120478370d1..ad9dd408fbeaf 100644
--- a/pandas/tests/scalar/timedelta/test_constructors.py
+++ b/pandas/tests/scalar/timedelta/test_constructors.py
@@ -44,7 +44,7 @@ def test_from_td64_retain_resolution():
     obj = np.timedelta64(12345, "ms")
 
     td = Timedelta(obj)
-    assert td.value == obj.view("i8")
+    assert td._value == obj.view("i8")
     assert td._creso == NpyDatetimeUnit.NPY_FR_ms.value
 
     # Case where we cast to nearest-supported reso
@@ -95,22 +95,22 @@ def test_from_tick_reso():
 
 def test_construction():
     expected = np.timedelta64(10, "D").astype("m8[ns]").view("i8")
-    assert Timedelta(10, unit="d").value == expected
-    assert Timedelta(10.0, unit="d").value == expected
-    assert Timedelta("10 days").value == expected
-    assert Timedelta(days=10).value == expected
-    assert Timedelta(days=10.0).value == expected
+    assert Timedelta(10, unit="d")._value == expected
+    assert Timedelta(10.0, unit="d")._value == expected
+    assert Timedelta("10 days")._value == expected
+    assert Timedelta(days=10)._value == expected
+    assert Timedelta(days=10.0)._value == expected
 
     expected += np.timedelta64(10, "s").astype("m8[ns]").view("i8")
-    assert Timedelta("10 days 00:00:10").value == expected
-    assert Timedelta(days=10, seconds=10).value == expected
-    assert Timedelta(days=10, milliseconds=10 * 1000).value == expected
-    assert Timedelta(days=10, microseconds=10 * 1000 * 1000).value == expected
+    assert Timedelta("10 days 00:00:10")._value == expected
+    assert Timedelta(days=10, seconds=10)._value == expected
+    assert Timedelta(days=10, milliseconds=10 * 1000)._value == expected
+    assert Timedelta(days=10, microseconds=10 * 1000 * 1000)._value == expected
 
     # rounding cases
-    assert Timedelta(82739999850000).value == 82739999850000
+    assert Timedelta(82739999850000)._value == 82739999850000
     assert "0 days 22:58:59.999850" in str(Timedelta(82739999850000))
-    assert Timedelta(123072001000000).value == 123072001000000
+    assert Timedelta(123072001000000)._value == 123072001000000
     assert "1 days 10:11:12.001" in str(Timedelta(123072001000000))
 
     # string conversion with/without leading zero
@@ -200,7 +200,7 @@ def test_construction():
     expected = np.timedelta64(10, "s").astype("m8[ns]").view("i8") + np.timedelta64(
         500, "ms"
     ).astype("m8[ns]").view("i8")
-    assert Timedelta(10.5, unit="s").value == expected
+    assert Timedelta(10.5, unit="s")._value == expected
 
     # offset
     assert to_timedelta(offsets.Hour(2)) == Timedelta(hours=2)
@@ -239,7 +239,7 @@ def test_td_construction_with_np_dtypes(npdtype, item):
     # GH#8757: test construction with np dtypes
     pykwarg, npkwarg = item
     expected = np.timedelta64(1, npkwarg).astype("m8[ns]").view("i8")
-    assert Timedelta(**{pykwarg: npdtype(1)}).value == expected
+    assert Timedelta(**{pykwarg: npdtype(1)})._value == expected
 
 
 @pytest.mark.parametrize(
@@ -261,7 +261,7 @@ def test_td_construction_with_np_dtypes(npdtype, item):
 def test_td_from_repr_roundtrip(val):
     # round-trip both for string and value
     td = Timedelta(val)
-    assert Timedelta(td.value) == td
+    assert Timedelta(td._value) == td
 
     assert Timedelta(str(td)) == td
     assert Timedelta(td._repr_base(format="all")) == td
@@ -270,7 +270,7 @@ def test_td_from_repr_roundtrip(val):
 
 def test_overflow_on_construction():
     # GH#3374
-    value = Timedelta("1day").value * 20169940
+    value = Timedelta("1day")._value * 20169940
     msg = "Cannot cast 1742682816000000000000 from ns to 'ns' without overflow"
     with pytest.raises(OutOfBoundsTimedelta, match=msg):
         Timedelta(value)
@@ -512,3 +512,23 @@ class MyCustomTimedelta(Timedelta):
 
     td = MyCustomTimedelta("1 minute")
     assert isinstance(td, MyCustomTimedelta)
+
+
+def test_non_nano_value():
+    # https://github.com/pandas-dev/pandas/issues/49076
+    result = Timedelta(10, unit="D").as_unit("s").value
+    # `.value` shows nanoseconds, even though unit is 's'
+    assert result == 864000000000000
+
+    # out-of-nanoseconds-bounds `.value` raises informative message
+    msg = (
+        r"Cannot convert Timedelta to nanoseconds without overflow. "
+        r"Use `.asm8.view\('i8'\)` to cast represent Timedelta in its "
+        r"own unit \(here, s\).$"
+    )
+    td = Timedelta(1_000, "D").as_unit("s") * 1_000
+    with pytest.raises(OverflowError, match=msg):
+        td.value
+    # check that the suggested workaround actually works
+    result = td.asm8.view("i8")
+    assert result == 86400000000
diff --git a/pandas/tests/scalar/timedelta/test_timedelta.py b/pandas/tests/scalar/timedelta/test_timedelta.py
index 924f756edb233..dc4399a4a38de 100644
--- a/pandas/tests/scalar/timedelta/test_timedelta.py
+++ b/pandas/tests/scalar/timedelta/test_timedelta.py
@@ -32,27 +32,27 @@ def test_as_unit(self):
         assert td.as_unit("ns") is td
 
         res = td.as_unit("us")
-        assert res.value == td.value // 1000
+        assert res._value == td._value // 1000
         assert res._creso == NpyDatetimeUnit.NPY_FR_us.value
 
         rt = res.as_unit("ns")
-        assert rt.value == td.value
+        assert rt._value == td._value
         assert rt._creso == td._creso
 
         res = td.as_unit("ms")
-        assert res.value == td.value // 1_000_000
+        assert res._value == td._value // 1_000_000
         assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value
 
         rt = res.as_unit("ns")
-        assert rt.value == td.value
+        assert rt._value == td._value
         assert rt._creso == td._creso
 
         res = td.as_unit("s")
-        assert res.value == td.value // 1_000_000_000
+        assert res._value == td._value // 1_000_000_000
         assert res._creso == NpyDatetimeUnit.NPY_FR_s.value
 
         rt = res.as_unit("ns")
-        assert rt.value == td.value
+        assert rt._value == td._value
         assert rt._creso == td._creso
 
     def test_as_unit_overflows(self):
@@ -65,7 +65,7 @@ def test_as_unit_overflows(self):
             td.as_unit("ns")
 
         res = td.as_unit("ms")
-        assert res.value == us // 1000
+        assert res._value == us // 1000
         assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value
 
     def test_as_unit_rounding(self):
@@ -76,7 +76,7 @@ def test_as_unit_rounding(self):
         assert res == expected
 
         assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value
-        assert res.value == 1
+        assert res._value == 1
 
         with pytest.raises(ValueError, match="Cannot losslessly convert units"):
             td.as_unit("ms", round_ok=False)
@@ -85,13 +85,13 @@ def test_as_unit_non_nano(self):
         # case where we are going neither to nor from nano
         td = Timedelta(days=1).as_unit("ms")
         assert td.days == 1
-        assert td.value == 86_400_000
+        assert td._value == 86_400_000
         assert td.components.days == 1
         assert td._d == 1
         assert td.total_seconds() == 86400
 
         res = td.as_unit("us")
-        assert res.value == 86_400_000_000
+        assert res._value == 86_400_000_000
         assert res.components.days == 1
         assert res.components.hours == 0
         assert res._d == 1
@@ -129,7 +129,7 @@ def td(self, unit, val):
     def test_from_value_and_reso(self, unit, val):
         # Just checking that the fixture is giving us what we asked for
         td = Timedelta._from_value_and_reso(val, unit)
-        assert td.value == val
+        assert td._value == val
         assert td._creso == unit
         assert td.days == 106752
 
@@ -148,7 +148,7 @@ def test_mul_preserves_reso(self, td, unit):
         # The td fixture should always be far from the implementation
         #  bound, so doubling does not risk overflow.
         res = td * 2
-        assert res.value == td.value * 2
+        assert res._value == td._value * 2
         assert res._creso == unit
 
     def test_cmp_cross_reso(self, td):
@@ -169,7 +169,7 @@ def test_to_timedelta64(self, td, unit):
         for res in [td.to_timedelta64(), td.to_numpy(), td.asm8]:
 
             assert isinstance(res, np.timedelta64)
-            assert res.view("i8") == td.value
+            assert res.view("i8") == td._value
             if unit == NpyDatetimeUnit.NPY_FR_s.value:
                 assert res.dtype == "m8[s]"
             elif unit == NpyDatetimeUnit.NPY_FR_ms.value:
@@ -181,7 +181,7 @@ def test_truediv_timedeltalike(self, td):
         assert td / td == 1
         assert (2.5 * td) / td == 2.5
 
-        other = Timedelta(td.value)
+        other = Timedelta(td._value)
         msg = "Cannot cast 106752 days 00:00:00 to unit='ns' without overflow."
         with pytest.raises(OutOfBoundsTimedelta, match=msg):
             td / other
@@ -206,18 +206,18 @@ def test_truediv_numeric(self, td):
         assert td / np.nan is NaT
 
         res = td / 2
-        assert res.value == td.value / 2
+        assert res._value == td._value / 2
         assert res._creso == td._creso
 
         res = td / 2.0
-        assert res.value == td.value / 2
+        assert res._value == td._value / 2
         assert res._creso == td._creso
 
     def test_floordiv_timedeltalike(self, td):
         assert td // td == 1
         assert (2.5 * td) // td == 2
 
-        other = Timedelta(td.value)
+        other = Timedelta(td._value)
         msg = "Cannot cast 106752 days 00:00:00 to unit='ns' without overflow"
         with pytest.raises(OutOfBoundsTimedelta, match=msg):
             td // other
@@ -240,21 +240,21 @@ def test_floordiv_numeric(self, td):
         assert td // np.nan is NaT
 
         res = td // 2
-        assert res.value == td.value // 2
+        assert res._value == td._value // 2
         assert res._creso == td._creso
 
         res = td // 2.0
-        assert res.value == td.value // 2
+        assert res._value == td._value // 2
         assert res._creso == td._creso
 
         assert td // np.array(np.nan) is NaT
 
         res = td // np.array(2)
-        assert res.value == td.value // 2
+        assert res._value == td._value // 2
         assert res._creso == td._creso
 
         res = td // np.array(2.0)
-        assert res.value == td.value // 2
+        assert res._value == td._value // 2
         assert res._creso == td._creso
 
     def test_addsub_mismatched_reso(self, td):
@@ -293,12 +293,12 @@ def test_addsub_mismatched_reso(self, td):
     def test_min(self, td):
         assert td.min <= td
         assert td.min._creso == td._creso
-        assert td.min.value == NaT.value + 1
+        assert td.min._value == NaT._value + 1
 
     def test_max(self, td):
         assert td.max >= td
         assert td.max._creso == td._creso
-        assert td.max.value == np.iinfo(np.int64).max
+        assert td.max._value == np.iinfo(np.int64).max
 
     def test_resolution(self, td):
         expected = Timedelta._from_value_and_reso(1, td._creso)
@@ -310,7 +310,7 @@ def test_resolution(self, td):
 def test_timedelta_class_min_max_resolution():
     # when accessed on the class (as opposed to an instance), we default
     #  to nanoseconds
-    assert Timedelta.min == Timedelta(NaT.value + 1)
+    assert Timedelta.min == Timedelta(NaT._value + 1)
     assert Timedelta.min._creso == NpyDatetimeUnit.NPY_FR_ns.value
 
     assert Timedelta.max == Timedelta(np.iinfo(np.int64).max)
@@ -362,9 +362,9 @@ class TestTimedeltas:
     def test_rounding_on_int_unit_construction(self, unit, value, expected):
         # GH 12690
         result = Timedelta(value, unit=unit)
-        assert result.value == expected
+        assert result._value == expected
         result = Timedelta(str(value) + unit)
-        assert result.value == expected
+        assert result._value == expected
 
     def test_total_seconds_scalar(self):
         # see gh-10939
@@ -383,10 +383,10 @@ def test_conversion(self):
             assert td == pydt
             assert isinstance(pydt, timedelta) and not isinstance(pydt, Timedelta)
 
-            assert td == np.timedelta64(td.value, "ns")
+            assert td == np.timedelta64(td._value, "ns")
             td64 = td.to_timedelta64()
 
-            assert td64 == np.timedelta64(td.value, "ns")
+            assert td64 == np.timedelta64(td._value, "ns")
             assert td == td64
 
             assert isinstance(td64, np.timedelta64)
@@ -425,8 +425,8 @@ def check(value):
         assert abs(td) == Timedelta("13:48:48")
         assert str(td) == "-1 days +10:11:12"
         assert -td == Timedelta("0 days 13:48:48")
-        assert -Timedelta("-1 days, 10:11:12").value == 49728000000000
-        assert Timedelta("-1 days, 10:11:12").value == -49728000000000
+        assert -Timedelta("-1 days, 10:11:12")._value == 49728000000000
+        assert Timedelta("-1 days, 10:11:12")._value == -49728000000000
 
         rng = to_timedelta("-1 days, 10:11:12.100123456")
         assert rng.days == -1
@@ -882,8 +882,8 @@ def test_implementation_limits(self):
 
         # GH 12727
         # timedelta limits correspond to int64 boundaries
-        assert min_td.value == iNaT + 1
-        assert max_td.value == lib.i8max
+        assert min_td._value == iNaT + 1
+        assert max_td._value == lib.i8max
 
         # Beyond lower limit, a NAT before the Overflow
         assert (min_td - Timedelta(1, "ns")) is NaT
@@ -896,16 +896,16 @@ def test_implementation_limits(self):
             max_td + Timedelta(1, "ns")
 
         # Same tests using the internal nanosecond values
-        td = Timedelta(min_td.value - 1, "ns")
+        td = Timedelta(min_td._value - 1, "ns")
         assert td is NaT
 
         msg = "Cannot cast -9223372036854775809 from ns to 'ns' without overflow"
         with pytest.raises(OutOfBoundsTimedelta, match=msg):
-            Timedelta(min_td.value - 2, "ns")
+            Timedelta(min_td._value - 2, "ns")
 
         msg = "Cannot cast 9223372036854775808 from ns to 'ns' without overflow"
         with pytest.raises(OutOfBoundsTimedelta, match=msg):
-            Timedelta(max_td.value + 1, "ns")
+            Timedelta(max_td._value + 1, "ns")
 
     def test_total_seconds_precision(self):
         # GH 19458
@@ -963,5 +963,5 @@ def test_timedelta_attribute_precision():
     result += td.microseconds
     result *= 1000
     result += td.nanoseconds
-    expected = td.value
+    expected = td._value
     assert result == expected
diff --git a/pandas/tests/scalar/timestamp/test_arithmetic.py b/pandas/tests/scalar/timestamp/test_arithmetic.py
index 0ad3436e55787..2dac346bc54d5 100644
--- a/pandas/tests/scalar/timestamp/test_arithmetic.py
+++ b/pandas/tests/scalar/timestamp/test_arithmetic.py
@@ -200,7 +200,7 @@ def test_timestamp_add_timedelta64_unit(self, other, expected_difference):
         now = datetime.utcnow()
         ts = Timestamp(now).as_unit("ns")
         result = ts + other
-        valdiff = result.value - ts.value
+        valdiff = result._value - ts._value
         assert valdiff == expected_difference
 
         ts2 = Timestamp(now)
diff --git a/pandas/tests/scalar/timestamp/test_constructors.py b/pandas/tests/scalar/timestamp/test_constructors.py
index 8129985ef9bea..5ea8fc53a6bab 100644
--- a/pandas/tests/scalar/timestamp/test_constructors.py
+++ b/pandas/tests/scalar/timestamp/test_constructors.py
@@ -160,11 +160,11 @@ def test_constructor(self):
             for result in [Timestamp(date_str), Timestamp(date_obj)]:
                 result = result.as_unit("ns")  # test originally written before non-nano
                 # only with timestring
-                assert result.as_unit("ns").value == expected
+                assert result.as_unit("ns")._value == expected
 
                 # re-creation shouldn't affect to internal value
                 result = Timestamp(result)
-                assert result.as_unit("ns").value == expected
+                assert result.as_unit("ns")._value == expected
 
             # with timezone
             for tz, offset in timezones:
@@ -173,11 +173,11 @@ def test_constructor(self):
                         "ns"
                     )  # test originally written before non-nano
                     expected_tz = expected - offset * 3600 * 1_000_000_000
-                    assert result.as_unit("ns").value == expected_tz
+                    assert result.as_unit("ns")._value == expected_tz
 
                     # should preserve tz
                     result = Timestamp(result)
-                    assert result.as_unit("ns").value == expected_tz
+                    assert result.as_unit("ns")._value == expected_tz
 
                     # should convert to UTC
                     if tz is not None:
@@ -185,7 +185,7 @@ def test_constructor(self):
                     else:
                         result = Timestamp(result, tz="UTC")
                     expected_utc = expected - offset * 3600 * 1_000_000_000
-                    assert result.as_unit("ns").value == expected_utc
+                    assert result.as_unit("ns")._value == expected_utc
 
     def test_constructor_with_stringoffset(self):
         # GH 7833
@@ -217,31 +217,31 @@ def test_constructor_with_stringoffset(self):
         for date_str, expected in tests:
             for result in [Timestamp(date_str)]:
                 # only with timestring
-                assert result.as_unit("ns").value == expected
+                assert result.as_unit("ns")._value == expected
 
                 # re-creation shouldn't affect to internal value
                 result = Timestamp(result)
-                assert result.as_unit("ns").value == expected
+                assert result.as_unit("ns")._value == expected
 
             # with timezone
             for tz, offset in timezones:
                 result = Timestamp(date_str, tz=tz)
                 expected_tz = expected
-                assert result.as_unit("ns").value == expected_tz
+                assert result.as_unit("ns")._value == expected_tz
 
                 # should preserve tz
                 result = Timestamp(result)
-                assert result.as_unit("ns").value == expected_tz
+                assert result.as_unit("ns")._value == expected_tz
 
                 # should convert to UTC
                 result = Timestamp(result).tz_convert("UTC")
                 expected_utc = expected
-                assert result.as_unit("ns").value == expected_utc
+                assert result.as_unit("ns")._value == expected_utc
 
         # This should be 2013-11-01 05:00 in UTC
         # converted to Chicago tz
         result = Timestamp("2013-11-01 00:00:00-0500", tz="America/Chicago")
-        assert result.value == Timestamp("2013-11-01 05:00").value
+        assert result._value == Timestamp("2013-11-01 05:00")._value
         expected = "Timestamp('2013-11-01 00:00:00-0500', tz='America/Chicago')"
         assert repr(result) == expected
         assert result == eval(repr(result))
@@ -249,7 +249,7 @@ def test_constructor_with_stringoffset(self):
         # This should be 2013-11-01 05:00 in UTC
         # converted to Tokyo tz (+09:00)
         result = Timestamp("2013-11-01 00:00:00-0500", tz="Asia/Tokyo")
-        assert result.value == Timestamp("2013-11-01 05:00").value
+        assert result._value == Timestamp("2013-11-01 05:00")._value
         expected = "Timestamp('2013-11-01 14:00:00+0900', tz='Asia/Tokyo')"
         assert repr(result) == expected
         assert result == eval(repr(result))
@@ -258,7 +258,7 @@ def test_constructor_with_stringoffset(self):
         # This should be 2015-11-18 10:00 in UTC
         # converted to Asia/Katmandu
         result = Timestamp("2015-11-18 15:45:00+05:45", tz="Asia/Katmandu")
-        assert result.value == Timestamp("2015-11-18 10:00").value
+        assert result._value == Timestamp("2015-11-18 10:00")._value
         expected = "Timestamp('2015-11-18 15:45:00+0545', tz='Asia/Katmandu')"
         assert repr(result) == expected
         assert result == eval(repr(result))
@@ -266,7 +266,7 @@ def test_constructor_with_stringoffset(self):
         # This should be 2015-11-18 10:00 in UTC
         # converted to Asia/Kolkata
         result = Timestamp("2015-11-18 15:30:00+05:30", tz="Asia/Kolkata")
-        assert result.value == Timestamp("2015-11-18 10:00").value
+        assert result._value == Timestamp("2015-11-18 10:00")._value
         expected = "Timestamp('2015-11-18 15:30:00+0530', tz='Asia/Kolkata')"
         assert repr(result) == expected
         assert result == eval(repr(result))
@@ -491,12 +491,12 @@ def test_invalid_date_kwarg_with_string_input(self, arg):
 
     def test_out_of_bounds_integer_value(self):
         # GH#26651 check that we raise OutOfBoundsDatetime, not OverflowError
-        msg = str(Timestamp.max.value * 2)
+        msg = str(Timestamp.max._value * 2)
         with pytest.raises(OutOfBoundsDatetime, match=msg):
-            Timestamp(Timestamp.max.value * 2)
-        msg = str(Timestamp.min.value * 2)
+            Timestamp(Timestamp.max._value * 2)
+        msg = str(Timestamp.min._value * 2)
         with pytest.raises(OutOfBoundsDatetime, match=msg):
-            Timestamp(Timestamp.min.value * 2)
+            Timestamp(Timestamp.min._value * 2)
 
     def test_out_of_bounds_value(self):
         one_us = np.timedelta64(1).astype("timedelta64[us]")
@@ -563,7 +563,7 @@ def test_bounds_with_different_units(self):
                 ts = Timestamp(dt64)
                 if unit in ["s", "ms", "us"]:
                     # We can preserve the input unit
-                    assert ts.value == dt64.view("i8")
+                    assert ts._value == dt64.view("i8")
                 else:
                     # we chose the closest unit that we _do_ support
                     assert ts._creso == NpyDatetimeUnit.NPY_FR_s.value
@@ -724,8 +724,8 @@ def test_constructor_ambigous_dst():
     # on Timestamp created from ambiguous time
     # doesn't change Timestamp.value
     ts = Timestamp(1382835600000000000, tz="dateutil/Europe/London")
-    expected = ts.value
-    result = Timestamp(ts).value
+    expected = ts._value
+    result = Timestamp(ts)._value
     assert result == expected
 
 
@@ -738,7 +738,7 @@ def test_constructor_before_dst_switch(epoch):
     ts = Timestamp(epoch, tz="dateutil/America/Los_Angeles")
     result = ts.tz.dst(ts)
     expected = timedelta(seconds=0)
-    assert Timestamp(ts).value == epoch
+    assert Timestamp(ts)._value == epoch
     assert result == expected
 
 
@@ -767,3 +767,23 @@ def test_timestamp_nano_range(nano):
     # GH 48255
     with pytest.raises(ValueError, match="nanosecond must be in 0..999"):
         Timestamp(year=2022, month=1, day=1, nanosecond=nano)
+
+
+def test_non_nano_value():
+    # https://github.com/pandas-dev/pandas/issues/49076
+    result = Timestamp("1800-01-01", unit="s").value
+    # `.value` shows nanoseconds, even though unit is 's'
+    assert result == -5364662400000000000
+
+    # out-of-nanoseconds-bounds `.value` raises informative message
+    msg = (
+        r"Cannot convert Timestamp to nanoseconds without overflow. "
+        r"Use `.asm8.view\('i8'\)` to cast represent Timestamp in its "
+        r"own unit \(here, s\).$"
+    )
+    ts = Timestamp("0300-01-01")
+    with pytest.raises(OverflowError, match=msg):
+        ts.value
+    # check that the suggested workaround actually works
+    result = ts.asm8.view("i8")
+    assert result == -52700112000
diff --git a/pandas/tests/scalar/timestamp/test_timestamp.py b/pandas/tests/scalar/timestamp/test_timestamp.py
index 22f5286569c6e..968ec122cde20 100644
--- a/pandas/tests/scalar/timestamp/test_timestamp.py
+++ b/pandas/tests/scalar/timestamp/test_timestamp.py
@@ -245,7 +245,7 @@ def test_utc_z_designator(self):
 
     def test_asm8(self):
         np.random.seed(7_960_929)
-        ns = [Timestamp.min.value, Timestamp.max.value, 1000]
+        ns = [Timestamp.min._value, Timestamp.max._value, 1000]
 
         for n in ns:
             assert (
@@ -256,7 +256,7 @@ def test_asm8(self):
 
     def test_class_ops_pytz(self):
         def compare(x, y):
-            assert int((Timestamp(x).value - Timestamp(y).value) / 1e9) == 0
+            assert int((Timestamp(x)._value - Timestamp(y)._value) / 1e9) == 0
 
         compare(Timestamp.now(), datetime.now())
         compare(Timestamp.now("UTC"), datetime.now(pytz.timezone("UTC")))
@@ -291,8 +291,8 @@ def test_class_ops_dateutil(self):
         def compare(x, y):
             assert (
                 int(
-                    np.round(Timestamp(x).value / 1e9)
-                    - np.round(Timestamp(y).value / 1e9)
+                    np.round(Timestamp(x)._value / 1e9)
+                    - np.round(Timestamp(y)._value / 1e9)
                 )
                 == 0
             )
@@ -386,24 +386,24 @@ def test_roundtrip(self):
         # further test accessors
         base = Timestamp("20140101 00:00:00").as_unit("ns")
 
-        result = Timestamp(base.value + Timedelta("5ms").value)
+        result = Timestamp(base._value + Timedelta("5ms")._value)
         assert result == Timestamp(f"{base}.005000")
         assert result.microsecond == 5000
 
-        result = Timestamp(base.value + Timedelta("5us").value)
+        result = Timestamp(base._value + Timedelta("5us")._value)
         assert result == Timestamp(f"{base}.000005")
         assert result.microsecond == 5
 
-        result = Timestamp(base.value + Timedelta("5ns").value)
+        result = Timestamp(base._value + Timedelta("5ns")._value)
         assert result == Timestamp(f"{base}.000000005")
         assert result.nanosecond == 5
         assert result.microsecond == 0
 
-        result = Timestamp(base.value + Timedelta("6ms 5us").value)
+        result = Timestamp(base._value + Timedelta("6ms 5us")._value)
         assert result == Timestamp(f"{base}.006005")
         assert result.microsecond == 5 + 6 * 1000
 
-        result = Timestamp(base.value + Timedelta("200ms 5us").value)
+        result = Timestamp(base._value + Timedelta("200ms 5us")._value)
         assert result == Timestamp(f"{base}.200005")
         assert result.microsecond == 5 + 200 * 1000
 
@@ -446,24 +446,24 @@ def test_nanosecond_string_parsing(self):
         # GH 7878
         expected_repr = "2013-05-01 07:15:45.123456789"
         expected_value = 1_367_392_545_123_456_789
-        assert ts.value == expected_value
+        assert ts._value == expected_value
         assert expected_repr in repr(ts)
 
         ts = Timestamp("2013-05-01 07:15:45.123456789+09:00", tz="Asia/Tokyo")
-        assert ts.value == expected_value - 9 * 3600 * 1_000_000_000
+        assert ts._value == expected_value - 9 * 3600 * 1_000_000_000
         assert expected_repr in repr(ts)
 
         ts = Timestamp("2013-05-01 07:15:45.123456789", tz="UTC")
-        assert ts.value == expected_value
+        assert ts._value == expected_value
         assert expected_repr in repr(ts)
 
         ts = Timestamp("2013-05-01 07:15:45.123456789", tz="US/Eastern")
-        assert ts.value == expected_value + 4 * 3600 * 1_000_000_000
+        assert ts._value == expected_value + 4 * 3600 * 1_000_000_000
         assert expected_repr in repr(ts)
 
         # GH 10041
         ts = Timestamp("20130501T071545.123456789")
-        assert ts.value == expected_value
+        assert ts._value == expected_value
         assert expected_repr in repr(ts)
 
     def test_nanosecond_timestamp(self):
@@ -471,33 +471,33 @@ def test_nanosecond_timestamp(self):
         expected = 1_293_840_000_000_000_005
         t = Timestamp("2011-01-01") + offsets.Nano(5)
         assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')"
-        assert t.value == expected
+        assert t._value == expected
         assert t.nanosecond == 5
 
         t = Timestamp(t)
         assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')"
-        assert t.value == expected
+        assert t._value == expected
         assert t.nanosecond == 5
 
         t = Timestamp("2011-01-01 00:00:00.000000005")
         assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000005')"
-        assert t.value == expected
+        assert t._value == expected
         assert t.nanosecond == 5
 
         expected = 1_293_840_000_000_000_010
         t = t + offsets.Nano(5)
         assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')"
-        assert t.value == expected
+        assert t._value == expected
         assert t.nanosecond == 10
 
         t = Timestamp(t)
         assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')"
-        assert t.value == expected
+        assert t._value == expected
         assert t.nanosecond == 10
 
         t = Timestamp("2011-01-01 00:00:00.000000010")
         assert repr(t) == "Timestamp('2011-01-01 00:00:00.000000010')"
-        assert t.value == expected
+        assert t._value == expected
         assert t.nanosecond == 10
 
 
@@ -534,7 +534,7 @@ def test_conversion(self):
         assert type(result) == type(expected)
 
         result = ts.to_datetime64()
-        expected = np.datetime64(ts.value, "ns")
+        expected = np.datetime64(ts._value, "ns")
         assert result == expected
         assert type(result) == type(expected)
         assert result.dtype == expected.dtype
@@ -588,7 +588,8 @@ def test_to_datetime_bijective(self):
             pydt_max = Timestamp.max.to_pydatetime()
 
         assert (
-            Timestamp(pydt_max).as_unit("ns").value / 1000 == Timestamp.max.value / 1000
+            Timestamp(pydt_max).as_unit("ns")._value / 1000
+            == Timestamp.max._value / 1000
         )
 
         exp_warning = None if Timestamp.min.nanosecond == 0 else UserWarning
@@ -601,8 +602,8 @@ def test_to_datetime_bijective(self):
         assert pydt_min + tdus > Timestamp.min
 
         assert (
-            Timestamp(pydt_min + tdus).as_unit("ns").value / 1000
-            == Timestamp.min.value / 1000
+            Timestamp(pydt_min + tdus).as_unit("ns")._value / 1000
+            == Timestamp.min._value / 1000
         )
 
     def test_to_period_tz_warning(self):
@@ -664,10 +665,10 @@ def ts(self, dt64):
     @pytest.fixture
     def ts_tz(self, ts, tz_aware_fixture):
         tz = maybe_get_tz(tz_aware_fixture)
-        return Timestamp._from_value_and_reso(ts.value, ts._creso, tz)
+        return Timestamp._from_value_and_reso(ts._value, ts._creso, tz)
 
     def test_non_nano_construction(self, dt64, ts, reso):
-        assert ts.value == dt64.view("i8")
+        assert ts._value == dt64.view("i8")
 
         if reso == "s":
             assert ts._creso == NpyDatetimeUnit.NPY_FR_s.value
@@ -714,7 +715,7 @@ def test_month_name(self, dt64, ts):
         assert ts.month_name() == alt.month_name()
 
     def test_tz_convert(self, ts):
-        ts = Timestamp._from_value_and_reso(ts.value, ts._creso, utc)
+        ts = Timestamp._from_value_and_reso(ts._value, ts._creso, utc)
 
         tz = pytz.timezone("US/Pacific")
         result = ts.tz_convert(tz)
@@ -788,7 +789,7 @@ def test_cmp_cross_reso_reversed_dt64(self):
     def test_pickle(self, ts, tz_aware_fixture):
         tz = tz_aware_fixture
         tz = maybe_get_tz(tz)
-        ts = Timestamp._from_value_and_reso(ts.value, ts._creso, tz)
+        ts = Timestamp._from_value_and_reso(ts._value, ts._creso, tz)
         rt = tm.round_trip_pickle(ts)
         assert rt._creso == ts._creso
         assert rt == ts
@@ -888,12 +889,12 @@ def test_sub_datetimelike_mismatched_reso(self, ts_tz):
 
         result = ts - other
         assert isinstance(result, Timedelta)
-        assert result.value == 0
+        assert result._value == 0
         assert result._creso == max(ts._creso, other._creso)
 
         result = other - ts
         assert isinstance(result, Timedelta)
-        assert result.value == 0
+        assert result._value == 0
         assert result._creso == max(ts._creso, other._creso)
 
         if ts._creso < other._creso:
@@ -983,12 +984,12 @@ def test_sub_timedelta64_mismatched_reso(self, ts_tz):
     def test_min(self, ts):
         assert ts.min <= ts
         assert ts.min._creso == ts._creso
-        assert ts.min.value == NaT.value + 1
+        assert ts.min._value == NaT._value + 1
 
     def test_max(self, ts):
         assert ts.max >= ts
         assert ts.max._creso == ts._creso
-        assert ts.max.value == np.iinfo(np.int64).max
+        assert ts.max._value == np.iinfo(np.int64).max
 
     def test_resolution(self, ts):
         expected = Timedelta._from_value_and_reso(1, ts._creso)
@@ -1000,7 +1001,7 @@ def test_resolution(self, ts):
 def test_timestamp_class_min_max_resolution():
     # when accessed on the class (as opposed to an instance), we default
     #  to nanoseconds
-    assert Timestamp.min == Timestamp(NaT.value + 1)
+    assert Timestamp.min == Timestamp(NaT._value + 1)
     assert Timestamp.min._creso == NpyDatetimeUnit.NPY_FR_ns.value
 
     assert Timestamp.max == Timestamp(np.iinfo(np.int64).max)
@@ -1018,27 +1019,27 @@ def test_as_unit(self):
         assert ts.as_unit("ns") is ts
 
         res = ts.as_unit("us")
-        assert res.value == ts.value // 1000
+        assert res._value == ts._value // 1000
         assert res._creso == NpyDatetimeUnit.NPY_FR_us.value
 
         rt = res.as_unit("ns")
-        assert rt.value == ts.value
+        assert rt._value == ts._value
         assert rt._creso == ts._creso
 
         res = ts.as_unit("ms")
-        assert res.value == ts.value // 1_000_000
+        assert res._value == ts._value // 1_000_000
         assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value
 
         rt = res.as_unit("ns")
-        assert rt.value == ts.value
+        assert rt._value == ts._value
         assert rt._creso == ts._creso
 
         res = ts.as_unit("s")
-        assert res.value == ts.value // 1_000_000_000
+        assert res._value == ts._value // 1_000_000_000
         assert res._creso == NpyDatetimeUnit.NPY_FR_s.value
 
         rt = res.as_unit("ns")
-        assert rt.value == ts.value
+        assert rt._value == ts._value
         assert rt._creso == ts._creso
 
     def test_as_unit_overflows(self):
@@ -1051,7 +1052,7 @@ def test_as_unit_overflows(self):
             ts.as_unit("ns")
 
         res = ts.as_unit("ms")
-        assert res.value == us // 1000
+        assert res._value == us // 1000
         assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value
 
     def test_as_unit_rounding(self):
@@ -1062,7 +1063,7 @@ def test_as_unit_rounding(self):
         assert res == expected
 
         assert res._creso == NpyDatetimeUnit.NPY_FR_ms.value
-        assert res.value == 1
+        assert res._value == 1
 
         with pytest.raises(ValueError, match="Cannot losslessly convert units"):
             ts.as_unit("ms", round_ok=False)
@@ -1076,7 +1077,7 @@ def test_as_unit_non_nano(self):
         assert ts.hour == ts.minute == ts.second == ts.microsecond == ts.nanosecond == 0
 
         res = ts.as_unit("s")
-        assert res.value == 24 * 3600
+        assert res._value == 24 * 3600
         assert res.year == 1970
         assert res.month == 1
         assert res.day == 2
diff --git a/pandas/tests/scalar/timestamp/test_timezones.py b/pandas/tests/scalar/timestamp/test_timezones.py
index e2df4d23bd858..820b2e17a9d3f 100644
--- a/pandas/tests/scalar/timestamp/test_timezones.py
+++ b/pandas/tests/scalar/timestamp/test_timezones.py
@@ -49,7 +49,7 @@ def test_tz_localize_pushes_out_of_bounds(self):
             f"underflows past {Timestamp.min}"
         )
         pac = Timestamp.min.tz_localize("US/Pacific")
-        assert pac.value > Timestamp.min.value
+        assert pac._value > Timestamp.min._value
         pac.tz_convert("Asia/Tokyo")  # tz_convert doesn't change value
         with pytest.raises(OutOfBoundsDatetime, match=msg):
             Timestamp.min.tz_localize("Asia/Tokyo")
@@ -60,7 +60,7 @@ def test_tz_localize_pushes_out_of_bounds(self):
             f"overflows past {Timestamp.max}"
         )
         tokyo = Timestamp.max.tz_localize("Asia/Tokyo")
-        assert tokyo.value < Timestamp.max.value
+        assert tokyo._value < Timestamp.max._value
         tokyo.tz_convert("US/Pacific")  # tz_convert doesn't change value
         with pytest.raises(OutOfBoundsDatetime, match=msg):
             Timestamp.max.tz_localize("US/Pacific")
@@ -103,7 +103,7 @@ def test_tz_localize_ambiguous(self):
         ts_dst = ts.tz_localize("US/Eastern", ambiguous=True)
         ts_no_dst = ts.tz_localize("US/Eastern", ambiguous=False)
 
-        assert ts_no_dst.value - ts_dst.value == 3600
+        assert ts_no_dst._value - ts_dst._value == 3600
         msg = re.escape(
             "'ambiguous' parameter must be one of: "
             "True, False, 'NaT', 'raise' (default)"
@@ -189,8 +189,8 @@ def test_tz_localize_ambiguous_compat(self):
         dateutil_zone = "dateutil/Europe/London"
         result_pytz = naive.tz_localize(pytz_zone, ambiguous=False)
         result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=False)
-        assert result_pytz.value == result_dateutil.value
-        assert result_pytz.value == 1382835600
+        assert result_pytz._value == result_dateutil._value
+        assert result_pytz._value == 1382835600
 
         # fixed ambiguous behavior
         # see gh-14621, GH#45087
@@ -201,8 +201,8 @@ def test_tz_localize_ambiguous_compat(self):
         # 1 hour difference
         result_pytz = naive.tz_localize(pytz_zone, ambiguous=True)
         result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=True)
-        assert result_pytz.value == result_dateutil.value
-        assert result_pytz.value == 1382832000
+        assert result_pytz._value == result_dateutil._value
+        assert result_pytz._value == 1382832000
 
         # see gh-14621
         assert str(result_pytz) == str(result_dateutil)
@@ -431,7 +431,7 @@ def test_timestamp_constructor_near_dst_boundary(self):
             Timestamp("2017-03-26 02:00", tz="Europe/Paris")
 
         result = Timestamp("2017-03-26 02:00:00+0100", tz="Europe/Paris")
-        naive = Timestamp(result.as_unit("ns").value)
+        naive = Timestamp(result.as_unit("ns")._value)
         expected = naive.tz_localize("UTC").tz_convert("Europe/Paris")
         assert result == expected
 
diff --git a/pandas/tests/scalar/timestamp/test_unary_ops.py b/pandas/tests/scalar/timestamp/test_unary_ops.py
index f87922336b714..62bfede7f4261 100644
--- a/pandas/tests/scalar/timestamp/test_unary_ops.py
+++ b/pandas/tests/scalar/timestamp/test_unary_ops.py
@@ -268,21 +268,21 @@ def test_round_int64(self, timestamp, freq):
 
         # test floor
         result = dt.floor(freq)
-        assert result.value % unit == 0, f"floor not a {freq} multiple"
-        assert 0 <= dt.value - result.value < unit, "floor error"
+        assert result._value % unit == 0, f"floor not a {freq} multiple"
+        assert 0 <= dt._value - result._value < unit, "floor error"
 
         # test ceil
         result = dt.ceil(freq)
-        assert result.value % unit == 0, f"ceil not a {freq} multiple"
-        assert 0 <= result.value - dt.value < unit, "ceil error"
+        assert result._value % unit == 0, f"ceil not a {freq} multiple"
+        assert 0 <= result._value - dt._value < unit, "ceil error"
 
         # test round
         result = dt.round(freq)
-        assert result.value % unit == 0, f"round not a {freq} multiple"
-        assert abs(result.value - dt.value) <= unit // 2, "round error"
-        if unit % 2 == 0 and abs(result.value - dt.value) == unit // 2:
+        assert result._value % unit == 0, f"round not a {freq} multiple"
+        assert abs(result._value - dt._value) <= unit // 2, "round error"
+        if unit % 2 == 0 and abs(result._value - dt._value) == unit // 2:
             # round half to even
-            assert result.value // unit % 2 == 0, "round half to even error"
+            assert result._value // unit % 2 == 0, "round half to even error"
 
     def test_round_implementation_bounds(self):
         # See also: analogous test for Timedelta
@@ -315,7 +315,7 @@ def test_round_sanity(self, val, method):
 
         def checker(res, ts, nanos):
             if method is Timestamp.round:
-                diff = np.abs((res - ts).value)
+                diff = np.abs((res - ts)._value)
                 assert diff <= nanos / 2
             elif method is Timestamp.floor:
                 assert res <= ts
@@ -326,38 +326,38 @@ def checker(res, ts, nanos):
 
         res = method(ts, "us")
         nanos = 1000
-        assert np.abs((res - ts).value) < nanos
-        assert res.value % nanos == 0
+        assert np.abs((res - ts)._value) < nanos
+        assert res._value % nanos == 0
         checker(res, ts, nanos)
 
         res = method(ts, "ms")
         nanos = 1_000_000
-        assert np.abs((res - ts).value) < nanos
-        assert res.value % nanos == 0
+        assert np.abs((res - ts)._value) < nanos
+        assert res._value % nanos == 0
         checker(res, ts, nanos)
 
         res = method(ts, "s")
         nanos = 1_000_000_000
-        assert np.abs((res - ts).value) < nanos
-        assert res.value % nanos == 0
+        assert np.abs((res - ts)._value) < nanos
+        assert res._value % nanos == 0
         checker(res, ts, nanos)
 
         res = method(ts, "min")
         nanos = 60 * 1_000_000_000
-        assert np.abs((res - ts).value) < nanos
-        assert res.value % nanos == 0
+        assert np.abs((res - ts)._value) < nanos
+        assert res._value % nanos == 0
         checker(res, ts, nanos)
 
         res = method(ts, "h")
         nanos = 60 * 60 * 1_000_000_000
-        assert np.abs((res - ts).value) < nanos
-        assert res.value % nanos == 0
+        assert np.abs((res - ts)._value) < nanos
+        assert res._value % nanos == 0
         checker(res, ts, nanos)
 
         res = method(ts, "D")
         nanos = 24 * 60 * 60 * 1_000_000_000
-        assert np.abs((res - ts).value) < nanos
-        assert res.value % nanos == 0
+        assert np.abs((res - ts)._value) < nanos
+        assert res._value % nanos == 0
         checker(res, ts, nanos)
 
     # --------------------------------------------------------------
diff --git a/pandas/tests/series/indexing/test_setitem.py b/pandas/tests/series/indexing/test_setitem.py
index 1a52e02ee314f..3d09954ed3c0f 100644
--- a/pandas/tests/series/indexing/test_setitem.py
+++ b/pandas/tests/series/indexing/test_setitem.py
@@ -949,7 +949,7 @@ class TestSetitemNAPeriodDtype(SetitemCastingEquivalents):
     @pytest.fixture
     def expected(self, key):
         exp = Series(period_range("2000-01-01", periods=10, freq="D"))
-        exp._values.view("i8")[key] = NaT.value
+        exp._values.view("i8")[key] = NaT._value
         assert exp[key] is NaT or all(x is NaT for x in exp[key])
         return exp
 
diff --git a/pandas/tests/series/methods/test_asof.py b/pandas/tests/series/methods/test_asof.py
index 8cb0328eb8634..6ae978b22e24d 100644
--- a/pandas/tests/series/methods/test_asof.py
+++ b/pandas/tests/series/methods/test_asof.py
@@ -17,7 +17,7 @@
 
 class TestSeriesAsof:
     def test_asof_nanosecond_index_access(self):
-        ts = Timestamp("20130101").as_unit("ns").value
+        ts = Timestamp("20130101").as_unit("ns")._value
         dti = DatetimeIndex([ts + 50 + i for i in range(100)])
         ser = Series(np.random.randn(100), index=dti)
 
diff --git a/pandas/tests/series/methods/test_fillna.py b/pandas/tests/series/methods/test_fillna.py
index 9fded26c37caf..ae6622da1d407 100644
--- a/pandas/tests/series/methods/test_fillna.py
+++ b/pandas/tests/series/methods/test_fillna.py
@@ -26,7 +26,7 @@
 
 class TestSeriesFillNA:
     def test_fillna_nat(self):
-        series = Series([0, 1, 2, NaT.value], dtype="M8[ns]")
+        series = Series([0, 1, 2, NaT._value], dtype="M8[ns]")
 
         filled = series.fillna(method="pad")
         filled2 = series.fillna(value=series.values[2])
@@ -44,7 +44,7 @@ def test_fillna_nat(self):
         tm.assert_frame_equal(filled, expected)
         tm.assert_frame_equal(filled2, expected)
 
-        series = Series([NaT.value, 0, 1, 2], dtype="M8[ns]")
+        series = Series([NaT._value, 0, 1, 2], dtype="M8[ns]")
 
         filled = series.fillna(method="bfill")
         filled2 = series.fillna(value=series[1])
diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py
index 7f65bce873126..08dc35c849d37 100644
--- a/pandas/tests/series/test_constructors.py
+++ b/pandas/tests/series/test_constructors.py
@@ -901,7 +901,7 @@ def test_constructor_datelike_coercion2(self):
 
     def test_constructor_mixed_int_and_timestamp(self, frame_or_series):
         # specifically Timestamp with nanos, not datetimes
-        objs = [Timestamp(9), 10, NaT.value]
+        objs = [Timestamp(9), 10, NaT._value]
         result = frame_or_series(objs, dtype="M8[ns]")
 
         expected = frame_or_series([Timestamp(9), Timestamp(10), NaT])
diff --git a/pandas/tests/series/test_missing.py b/pandas/tests/series/test_missing.py
index 3c0f962b90086..81e1e4c205cf7 100644
--- a/pandas/tests/series/test_missing.py
+++ b/pandas/tests/series/test_missing.py
@@ -44,7 +44,7 @@ def test_timedelta64_nan(self):
         td1 = td.copy()
         td1[0] = np.nan
         assert isna(td1[0])
-        assert td1[0].value == iNaT
+        assert td1[0]._value == iNaT
         td1[0] = td[0]
         assert not isna(td1[0])
 
@@ -58,7 +58,7 @@ def test_timedelta64_nan(self):
 
         td1[2] = NaT
         assert isna(td1[2])
-        assert td1[2].value == iNaT
+        assert td1[2]._value == iNaT
         td1[2] = td[2]
         assert not isna(td1[2])
 
diff --git a/pandas/tests/series/test_reductions.py b/pandas/tests/series/test_reductions.py
index e9d2877148c2b..eb11b62a651cc 100644
--- a/pandas/tests/series/test_reductions.py
+++ b/pandas/tests/series/test_reductions.py
@@ -59,7 +59,7 @@ def test_td64_summation_overflow():
 
     # the computation is converted to float so
     # might be some loss of precision
-    assert np.allclose(result.value / 1000, expected.value / 1000)
+    assert np.allclose(result._value / 1000, expected._value / 1000)
 
     # sum
     msg = "overflow in timedelta operation"
diff --git a/pandas/tests/series/test_repr.py b/pandas/tests/series/test_repr.py
index 43a6c7028883b..23de7106e08a4 100644
--- a/pandas/tests/series/test_repr.py
+++ b/pandas/tests/series/test_repr.py
@@ -241,7 +241,7 @@ def test_format_pre_1900_dates(self):
         repr(ts)
 
     def test_series_repr_nat(self):
-        series = Series([0, 1000, 2000, pd.NaT.value], dtype="M8[ns]")
+        series = Series([0, 1000, 2000, pd.NaT._value], dtype="M8[ns]")
 
         result = repr(series)
         expected = (
diff --git a/pandas/tests/tools/test_to_datetime.py b/pandas/tests/tools/test_to_datetime.py
index 7a93d2fe8b5ce..93ea31fe68f0f 100644
--- a/pandas/tests/tools/test_to_datetime.py
+++ b/pandas/tests/tools/test_to_datetime.py
@@ -945,8 +945,8 @@ def test_to_datetime_now(self):
 
             # These should all be equal with infinite perf; this gives
             # a generous margin of 10 seconds
-            assert abs(pdnow.value - now.value) < 1e10
-            assert abs(pdnow2.value - now.value) < 1e10
+            assert abs(pdnow._value - now._value) < 1e10
+            assert abs(pdnow2._value - now._value) < 1e10
 
             assert pdnow.tzinfo is None
             assert pdnow2.tzinfo is None
@@ -970,10 +970,10 @@ def test_to_datetime_today(self, tz):
 
             # These should all be equal with infinite perf; this gives
             # a generous margin of 10 seconds
-            assert abs(pdtoday.normalize().value - nptoday) < 1e10
-            assert abs(pdtoday2.normalize().value - nptoday) < 1e10
-            assert abs(pdtoday.value - tstoday.value) < 1e10
-            assert abs(pdtoday.value - tstoday2.value) < 1e10
+            assert abs(pdtoday.normalize()._value - nptoday) < 1e10
+            assert abs(pdtoday2.normalize()._value - nptoday) < 1e10
+            assert abs(pdtoday._value - tstoday._value) < 1e10
+            assert abs(pdtoday._value - tstoday2._value) < 1e10
 
             assert pdtoday.tzinfo is None
             assert pdtoday2.tzinfo is None
diff --git a/pandas/tests/tools/test_to_timedelta.py b/pandas/tests/tools/test_to_timedelta.py
index 0ce2a424f6915..6be499b6dc474 100644
--- a/pandas/tests/tools/test_to_timedelta.py
+++ b/pandas/tests/tools/test_to_timedelta.py
@@ -73,7 +73,7 @@ def test_to_timedelta_units_dtypes(self, dtype, unit):
         tm.assert_index_equal(result, expected)
 
     def test_to_timedelta_oob_non_nano(self):
-        arr = np.array([pd.NaT.value + 1], dtype="timedelta64[m]")
+        arr = np.array([pd.NaT._value + 1], dtype="timedelta64[m]")
 
         msg = (
             "Cannot convert -9223372036854775807 minutes to "
@@ -218,7 +218,7 @@ def test_to_timedelta_on_missing_values(self):
     @pytest.mark.parametrize("val", [np.nan, pd.NaT])
     def test_to_timedelta_on_missing_values_scalar(self, val):
         actual = to_timedelta(val)
-        assert actual.value == np.timedelta64("NaT").astype("int64")
+        assert actual._value == np.timedelta64("NaT").astype("int64")
 
     def test_to_timedelta_float(self):
         # https://github.com/pandas-dev/pandas/issues/25077
@@ -280,7 +280,7 @@ def test_to_timedelta_zerodim(self, fixed_now_ts):
         arg2 = arg.view("m8[ns]")
         result = to_timedelta(arg2)
         assert isinstance(result, pd.Timedelta)
-        assert result.value == dt64.view("i8")
+        assert result._value == dt64.view("i8")
 
     def test_to_timedelta_numeric_ea(self, any_numeric_ea_dtype):
         # GH#48796
diff --git a/pandas/tests/tseries/offsets/test_ticks.py b/pandas/tests/tseries/offsets/test_ticks.py
index 13619c2c0c828..69953955ebbce 100644
--- a/pandas/tests/tseries/offsets/test_ticks.py
+++ b/pandas/tests/tseries/offsets/test_ticks.py
@@ -257,7 +257,7 @@ def test_tick_division(cls):
         assert not isinstance(result, cls)
         assert result.delta == off.delta / 1000
 
-    if cls._nanos_inc < Timedelta(seconds=1).value:
+    if cls._nanos_inc < Timedelta(seconds=1)._value:
         # Case where we end up with a bigger class
         result = off / 0.001
         assert isinstance(result, offsets.Tick)
diff --git a/pandas/tests/tslibs/test_timezones.py b/pandas/tests/tslibs/test_timezones.py
index 386b89fa03471..28e4889983fb9 100644
--- a/pandas/tests/tslibs/test_timezones.py
+++ b/pandas/tests/tslibs/test_timezones.py
@@ -57,7 +57,7 @@ def test_tzlocal_offset():
     offset = dateutil.tz.tzlocal().utcoffset(datetime(2011, 1, 1))
     offset = offset.total_seconds()
 
-    assert ts.value + offset == Timestamp("2011-01-01").value
+    assert ts._value + offset == Timestamp("2011-01-01")._value
 
 
 def test_tzlocal_is_not_utc():


Code review comments:
diff_hunk: @@ -814,7 +814,7 @@ def infer_dtype_from_scalar(val, pandas_dtype: bool = False) -> tuple[DtypeObj,
             dtype = _dtype_obj
         else:
             dtype = np.dtype("m8[ns]")
-            val = np.timedelta64(val.value, "ns")
+            val = np.timedelta64(val._value, "ns")
path: pandas/core/dtypes/cast.py
text: @user1:
i think this one is expecting the nanos value?  (and probably needs to be updated to allow non-nano?)