The error means you called total_seconds() on None; make sure you have a real timedelta or pandas Timedelta before calling the method.
Why this page? You’re seeing a crash that blocks progress. This guide gives a fast, practical path to fix it, plus patterns to keep it from coming back.
What The Error Actually Means
Quick context: In Python, total_seconds() is a method on datetime.timedelta that returns the duration in seconds. If the object you call it on is None, Python raises AttributeError with the message you’re seeing. The method is documented in the standard library; it converts a timedelta to a floating-point count of seconds.
The official docs state that timedelta.total_seconds() “returns the total number of seconds contained in the duration.” That call only works on a real timedelta, not on None.
Pandas mirrors this behavior: pd.Timedelta also has .total_seconds(), returning a float, again only when the value is a real timeduration.
Why does None show up? Functions that finish without a return value produce None by default, so any timing helper that forgets to return a duration will hand you None. The Python tutorial confirms: return with no value returns None; falling off the end also returns None.
AttributeError: ‘NoneType’ Object Has No Attribute ‘Total_Seconds’ — Causes And Easy Checks
Fast triage: Run through these short checks to find why your value is None.
- Confirm The Method Name And Case — Python is case-sensitive. The correct name is
total_seconds(), notTotal_Seconds; a wrong attribute name triggers anAttributeErroron any type. - Verify You Hold A Timedelta — Print the value before the call:
print(type(delta), delta). You should see<class 'datetime.timedelta'>orpandas.Timedelta. If it printsNone, backtrack to the producer. - Check Function Returns — If your helper has a path with no
return, it outputsNone. Add an explicit return or raise. The tutorial line aboutreturn→Noneis the key here. - Confirm Subtraction Produces A Timedelta —
datetime.now() - startgives atimedeltawhenstartis a realdatetime. IfstartisNone(or a non-datetime), you’ll get a different failure earlier or a bogus pipeline that setsdeltatoNone. - Pandas: Guard Parsing And Arithmetic — Use
pd.to_datetime(..., errors="coerce")so bad strings becomeNaT, then subtract to getTimedelta. Call.dt.total_seconds()on the result. Pandas docs showTimedelta.total_seconds()and the Timedelta basics. - Mind Known Edge Reports — Some library bugs or edge inputs have produced this exact message during parsing. If a fresh pandas version still shows it on parsing step, skim open/closed issues as a sanity check.
Proven Fix Patterns You Can Drop In
Return a real timedelta from helpers:
from datetime import datetime
def elapsed_since(ts):
# Ensure ts is a datetime and return a timedelta
if ts is None:
raise ValueError("missing start time")
return datetime.now() - ts # always returns a timedelta
delta = elapsed_since(datetime.now())
seconds = delta.total_seconds() # OK
print(seconds)
Guard against None at the callsite:
delta = maybe_get_delta() # could be None
if delta is not None:
seconds = delta.total_seconds()
else:
seconds = 0.0 # or skip, or raise
Make the function always return something: A function with no return yields None. Add a sensible default or raise clearly. The tutorial spells out the rule on return → None.
def duration_or_zero(start, end):
if start and end:
return end - start # timedelta
return timedelta(0) # never None
Use the correct attribute and call pattern: Always call the method with parentheses: delta.total_seconds(). The standard docs clarify what it returns and why it’s the right call for total seconds, not .seconds alone.
# Good
total = delta.total_seconds()
# Not the same
within_day = delta.seconds # ignores whole days
Pandas: vectorized, null-safe pipeline: Create datetimes safely, compute differences, then seconds.
import pandas as pd
# Parse with coercion so bad rows are NaT, not None
df["start"] = pd.to_datetime(df["start"], errors="coerce")
df["end"] = pd.to_datetime(df["end"], errors="coerce")
# Subtract → Timedelta, then total seconds; NaT diffs become NaN
df["elapsed_s"] = (df["end"] - df["start"]).dt.total_seconds()
Pandas documents Timedelta.total_seconds(), and the Timedelta user guide outlines how these objects behave across days and units.
Cause-To-Fix Cheatsheet
| What You See | Likely Cause | Safe Fix |
|---|---|---|
Object is None before total_seconds() |
Function returned None or missing branch returned nothing |
Return a timedelta or raise; add default branch that returns a real duration. |
AttributeError with 'Total_Seconds' |
Wrong case or underscore naming | Use total_seconds() exactly; Python names are case-sensitive. |
| Wrong values when spanning days | Using .seconds instead of .total_seconds() |
Call total_seconds() to include whole days. |
Pandas column fails on .dt.total_seconds() |
Bad timestamps; arithmetic produced NaT/missing |
Coerce bad rows with to_datetime(..., errors="coerce"); compute then handle NaN. |
Solid Examples For Common Workflows
Datetime Subtraction In Pure Python
from datetime import datetime
start = datetime.now()
# ... work ...
end = datetime.now()
delta = end - start # timedelta
elapsed = delta.total_seconds() # float seconds
print(elapsed)
That call to total_seconds() is the supported path for converting a timedelta to seconds per the standard library.
Measuring A Block With A Helper That Never Returns None
from contextlib import contextmanager
from datetime import datetime, timedelta
@contextmanager
def stopwatch():
start = datetime.now()
try:
yield
finally:
delta = datetime.now() - start
print(f"{delta.total_seconds():.6f}s")
Pandas Series Of Seconds Between Two Columns
# df has 'start' and 'end' columns with strings or datetimes
df["start"] = pd.to_datetime(df["start"], errors="coerce")
df["end"] = pd.to_datetime(df["end"], errors="coerce")
diff = df["end"] - df["start"] # Timedelta Series
df["elapsed_s"] = diff.dt.total_seconds() # float Series
# NaT pairs produce NaN; fill if needed:
df["elapsed_s"] = df["elapsed_s"].fillna(0)
These APIs and behaviors are described in pandas’ Timedelta reference and user guide.
Testing Your Fix Quickly
- Add A Type Print —
print(type(delta))should showtimedeltaorpandas.Timedeltabefore callingtotal_seconds(). - Probe Edge Rows — In pandas, check
df[df["elapsed_s"].isna()]right after the computation; decide whether to drop or fill. - Write A Tiny Assertion —
assert delta is not None; in pandas, assertdiff.notna().all()for the slice you’ll convert. - Unit Test A Missing Path — Create a test where inputs produce no duration, and confirm your function returns
timedelta(0)or raises a clear error text.
Prevent The Error In New Code
- Return Types That Can’t Be None — When a duration isn’t available, return
timedelta(0)rather thanNone, or raise. The tutorial notes the defaultNone; being explicit avoids surprises. - Type Hints Help — Hint
-> timedeltafor functions that must return a real duration; useOptional[timedelta]only when truly optional. - Input Validation Early — If the start value can be missing, validate at entry points and short-circuit.
- Pandas Null Discipline — Always parse with
errors="coerce"; treatNaTandNaNdeliberately withdropna,fillna, or masks. - Use The Right Property — Prefer
total_seconds()when spans may cross days; using.secondshides whole days.
When Optional Durations Are Expected
Design for “maybe” timing: Sometimes a duration truly might not exist. Model that cleanly so your call site never reaches for total_seconds() on None.
from datetime import timedelta
def try_duration(start, end):
if not start or not end:
return None # explicit
return end - start
delta = try_duration(start, end)
seconds = delta.total_seconds() if delta is not None else None
That pattern makes intent clear and keeps the error away. If you need a numeric value downstream, supply a default such as 0.0.
Keyword Variants And Search Matches
Many readers paste the full message into a search box. Using the exact phrase helps you land here again later: AttributeError: ‘NoneType’ Object Has No Attribute ‘Total_Seconds’. A close variant you might also see in code comments or logs is “nonetype has no attribute total_seconds,” which points to the same root cause: a missing timedelta value.
Why This Fix Works
Everything hinges on two facts: the standard library defines total_seconds() on timedelta, and pandas implements the same for Timedelta. If you ensure your variable is one of those types before calling the method, the call succeeds and returns the seconds value you need.
One More Look At The Common Pitfall
Hidden None from a helper: A helper that logs time but forgets to return the timedelta will silently hand back None. Python’s rules about falling off the end make that the default. Tightening return paths or raising when data is missing removes that ambiguity.
Can I Use .Seconds Instead?
Short answer for design clarity: .seconds is the number of seconds in the time portion within a day. It drops whole days. total_seconds() converts the entire span to seconds, days included. When you need a full span in seconds, use the method that the docs recommend.
Final Checklist Before You Ship
- Print The Type — It’s a
timedeltaor apd.Timedelta. - Method Name Correct —
total_seconds(), exact case, with parentheses. - No Hidden None — Every helper path returns a real duration or raises.
- Pandas Pipeline Null-Safe — Parsing uses
errors="coerce"; missing values are handled. - Cross-Day Spans — Use
total_seconds(), not.seconds.
