This guide is for Go developers who need to move a clock reading backward or forward by a fixed length of time, or who need the span between two instants. In the standard library those are different operations: shifting one time.Time uses Add with a positive or negative time.Duration, while the gap between two times uses Sub or Since. Many tutorials only show time.Now; here you also see fixed dates, parsed strings, calendar steps with AddDate, and common mistakes so you can subtract a duration from a time.Time without reaching for the wrong API.
Tested on: Go 1.22 on 64-bit Linux; snippets were run with
go runwhile this article was revised.
Quick answer: subtract a duration with time.Add
To subtract a duration from a time.Time, call Add with a negative duration, for example time.Now().Add(-time.Hour) to get a moment one hour earlier. Do not pass a time.Duration to Sub; Sub takes another time.Time and returns the span between the two instants.
package main
import (
"fmt"
"time"
)
func main() {
oneHourAgo := time.Now().Add(-1 * time.Hour)
fmt.Println(oneHourAgo)
}The line printed is a concrete timestamp in the past relative to the moment you click Run; the zero or monotonic detail in the string is normal for your environment.
How to Subtract Time in Go
time.Time values are immutable: Add returns a new time. Subtraction is always “add a negative duration” or calendar adjustment with AddDate.
Use time.Add with a negative duration
Write t.Add(-d) where d is a positive time.Duration, or t.Add(d) if you already built a negative duration. That is the idiomatic answer for golang time minus duration and golang subtract duration from time.
Subtract 1 hour from time.Now
time.Now().Add(-time.Hour) and time.Now().Add(-1 * time.Hour) are equivalent. Both are common in logs, cutoffs, and caches.
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
oneHourAgo := now.Add(-1 * time.Hour)
fmt.Println("Current time:", now)
fmt.Println("One hour ago:", oneHourAgo)
}You should see two lines whose clock values differ by about one hour (wall labels depend on your local zone).
Subtract minutes, seconds, hours, and days
Go provides named duration constants such as time.Second, time.Minute, and time.Hour. Combine them with integer multiplication for fixed-length steps. There is no time.Day constant because a “day” in civil calendars is not always exactly twenty-four hours of wall time in every zone.
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println("Now:", now)
fmt.Println("10 seconds ago:", now.Add(-10*time.Second))
fmt.Println("30 minutes ago:", now.Add(-30*time.Minute))
fmt.Println("1 hour ago:", now.Add(-1*time.Hour))
fmt.Println("24 hours ago:", now.Add(-24*time.Hour))
}Each printed line is a full RFC3339-style timestamp shifted backward by the labeled amount.
| Step you need | Typical expression |
|---|---|
| Seconds | t.Add(-10 * time.Second) |
| Minutes | t.Add(-30 * time.Minute) |
| Hours | t.Add(-2 * time.Hour) |
| Exactly twenty-four clock hours | t.Add(-24 * time.Hour) |
Build a duration from a string
For config-driven delays, time.ParseDuration accepts strings such as "1h30m". Subtract by negating after parse.
package main
import (
"fmt"
"time"
)
func main() {
d, err := time.ParseDuration("1h30m")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(time.Now().Add(-d))
}The printed time is ninety minutes before the moment you run it.
Subtract a duration from a specific time
Everything above works on any time.Time, not only time.Now(). Database timestamps, API payloads, and time.Date values all support the same Add pattern.
package main
import (
"fmt"
"time"
)
func main() {
start := time.Date(2026, 6, 18, 10, 30, 0, 0, time.UTC)
result := start.Add(-45 * time.Minute)
fmt.Println("Original time:", start)
fmt.Println("After subtracting 45 minutes:", result)
}The second line should read forty-five minutes earlier than 10:30 on the same calendar date in UTC.
Subtract duration from a parsed time
When the instant comes from a string, parse first, then subtract.
package main
import (
"fmt"
"log"
"time"
)
func main() {
layout := "2006-01-02 15:04:05"
t, err := time.Parse(layout, "2026-06-18 14:30:00")
if err != nil {
log.Fatal(err)
}
result := t.Add(-2 * time.Hour)
fmt.Println("Original:", t)
fmt.Println("Two hours earlier:", result)
}On success you get two UTC timestamps on 2026-06-18 separated by two hours.
Subtract duration from a custom time.Date value
time.Date constructs a wall-clock instant in a chosen location. After that, Add and AddDate behave the same as for time.Now().
time.Add vs time.Sub in Go
Both names appear in golang time.sub style searches, but they answer different questions.
| Goal | Use | Example |
|---|---|---|
| Move a time forward | t.Add(duration) |
now.Add(time.Hour) |
| Move a time backward | t.Add(-duration) |
now.Add(-time.Hour) |
| Difference between two times | t1.Sub(t2) |
end.Sub(start) |
| Subtract calendar days, months, years | t.AddDate |
now.AddDate(0, 0, -1) |
Use Add(-duration) when you want a new instant in the past or future. Use Sub when you already have two times and need a time.Duration between them.
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
past := now.Add(-2 * time.Hour)
diff := now.Sub(past)
fmt.Println("Past time:", past)
fmt.Println("Difference:", diff)
}The duration line should read two hours (plus or minus a tiny amount of sub-second noise from how fast the program runs).
Subtract calendar days, months, and years
AddDate(years, months, days) normalizes the result like the date picker on civil calendars: month length and leap years are handled for you. Negative arguments move backward.
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
yesterday := now.AddDate(0, 0, -1)
lastMonth := now.AddDate(0, -1, 0)
lastYear := now.AddDate(-1, 0, 0)
fmt.Println("Now:", now)
fmt.Println("Yesterday:", yesterday)
fmt.Println("Last month:", lastMonth)
fmt.Println("Last year:", lastYear)
}Four timestamps print in order; “yesterday” is one calendar day before “now” in the same location, which is not always the same as subtracting 24 * time.Hour near a daylight-saving transition.
| Requirement | Prefer |
|---|---|
| Subtract exactly twenty-four clock hours | t.Add(-24 * time.Hour) |
| Subtract one calendar day | t.AddDate(0, 0, -1) |
| Subtract one calendar month | t.AddDate(0, -1, 0) |
| Subtract one calendar year | t.AddDate(-1, 0, 0) |
Common time subtraction use cases
Get records from the last 1 hour
package main
import (
"fmt"
"time"
)
func main() {
cutoff := time.Now().Add(-1 * time.Hour)
fmt.Println("cutoff for queries:", cutoff)
}Use cutoff in SQL WHERE created_at >= ? style filters or in-memory comparisons.
Create expiration and cutoff times
package main
import (
"fmt"
"time"
)
func main() {
createdAt := time.Now().Add(-3 * time.Hour)
maxAge := 2 * time.Hour
if time.Since(createdAt) > maxAge {
fmt.Println("expired")
}
}time.Since(t) is shorthand for time.Now().Sub(t). Here the program should print expired because the synthetic createdAt is three hours in the past and maxAge is two hours.
Calculate retry or backoff windows
package main
import (
"fmt"
"time"
)
func main() {
lastAttempt := time.Now().Add(-15 * time.Minute)
if time.Since(lastAttempt) > 10*time.Minute {
fmt.Println("retry allowed")
}
}You should see retry allowed because fifteen minutes ago is more than ten minutes before now.
Find age of an event using time.Since
package main
import (
"fmt"
"time"
)
func main() {
startedAt := time.Now().Add(-90 * time.Second)
elapsed := time.Since(startedAt)
fmt.Println("Elapsed:", elapsed)
}Elapsed should be about one and a half minutes, formatted like 1m30s or similar.
Common mistakes
Using time.Sub to subtract a duration
Sub expects another time.Time. The expression time.Now().Sub(time.Hour) does not compile because time.Hour is a time.Duration, not a time.Time. Move the clock with time.Now().Add(-time.Hour) instead.
Confusing 24 hours with 1 calendar day
Add(-24 * time.Hour) rewinds the clock by exactly twenty-four hours of absolute time. AddDate(0, 0, -1) rewinds the calendar date in the location of t. Near DST they can disagree by an hour.
Ignoring time zones when comparing times
Parse and compare times in a consistent location, usually UTC for storage. Mixing time.Local strings with UTC columns is a frequent source of off-by-hours bugs.
Forgetting that time.Duration does not support months
There is no 30 * time.Month. Month lengths vary; use AddDate(0, -1, 0) for “one calendar month earlier.”
Forgetting that Add returns a new time
time.Time values are immutable. Assign the result of Add:
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
oneHourAgo := now.Add(-time.Hour)
fmt.Println(oneHourAgo)
}Discarding the return value of Add leaves now unchanged, which surprises newcomers.
Go time subtraction cheat sheet
| Goal | Use | Example |
|---|---|---|
| Current time minus 1 hour | Add with negative duration |
time.Now().Add(-time.Hour) |
| Current time minus 30 minutes | Add |
time.Now().Add(-30 * time.Minute) |
| Specific time minus duration | Add |
t.Add(-2 * time.Hour) |
| Difference between two times | Sub |
end.Sub(start) |
| Elapsed since an instant | Since |
time.Since(createdAt) |
| Add a duration forward | Add |
t.Add(10 * time.Minute) |
| Subtract one calendar day | AddDate |
t.AddDate(0, 0, -1) |
| Subtract one calendar month | AddDate |
t.AddDate(0, -1, 0) |
| Subtract one calendar year | AddDate |
t.AddDate(-1, 0, 0) |
Which time function should you use?
- Move one instant by a fixed length:
Addwith positive or negativetime.Duration. - Measure the gap between two instants:
Sub, orSincewhen one side istime.Now(). - Move on the civil calendar by years, months, or days:
AddDatewith negative arguments.
For zero-value behavior of time.Time, see zero value for time in Go.
Summary
Golang subtract time and golang time subtract duration from a single instant both mean t.Add(-d) with a time.Duration. Golang time now minus 1 hour is time.Now().Add(-time.Hour). time.Sub answers how far apart two time.Time values are; it does not subtract a duration from one clock reading. Calendar steps use AddDate with negative arguments. Separate twenty-four clock hours from one calendar day when DST matters, and use AddDate instead of inventing month-length durations.

