lubridate now() in R: Current Date-Time With Time Zones
The now() function in lubridate returns the current system date and time as a POSIXct object. Pass a time zone string like now("UTC") to get the same instant in a different zone.
now() # current datetime, local tz now("UTC") # current datetime, UTC now("America/New_York") # specific timezone now() - hours(1) # one hour ago now() + days(7) # seven days from now format(now(), "%Y-%m-%d %H:%M:%S") # custom string format as.Date(now()) # drop the time, keep the date difftime(now(), event_time, units = "mins") # minutes since event
Need explanation? Read on for examples and pitfalls.
What now() does in one sentence
now() returns the current system clock time as a POSIXct object. The result includes both date and time down to the second, tagged with a time zone.
This is the lubridate equivalent of base R's Sys.time(). The two return the same instant, but now() accepts a time zone argument directly and integrates cleanly with the rest of the lubridate API.
Syntax
now(tzone = ""). The single optional argument is the time zone string.
tzone = "" (the default) uses the session time zone returned by Sys.timezone(). Pass any IANA zone name like "UTC" or "Europe/Paris" to override. The underlying instant is identical; only the printed representation changes.
now() over Sys.time() when you want a specific time zone inline. Sys.time() always returns the system zone, so you would have to call with_tz() afterwards. now("Asia/Tokyo") does it in one step.Five common patterns
1. Current datetime in the local zone
The output shows the date, time of day, and the abbreviated zone (here IST). Sys.timezone() reports the full zone string.
2. Current datetime in UTC or another zone
The numeric instant is the same in all three calls. Only the printed clock changes. UTC is the safe default for logs and timestamps shared across machines.
3. Arithmetic: relative datetimes
hours(), days(), minutes(), weeks(), years() are lubridate period constructors. Adding them to now() produces a new POSIXct shifted by the amount.
4. Format the output
format() uses the standard strftime codes. %Y four-digit year, %m month, %d day, %H hour 24h, %M minute, %S second, %A weekday name, %B month name.
5. Elapsed time since an event
difftime() returns a difftime object with attached units. Coerce with as.numeric() to get a plain number for further math.
now() reads the system clock, converts it to seconds since the Unix epoch, and prints it in whatever zone you ask for. This is why now(), now("UTC"), and now("Asia/Tokyo") are the same instant but different strings.now() vs Sys.time() vs today() vs Sys.Date()
Four functions for current-time work, each with a distinct return type.
| Function | Package | Returns | Includes time? | Time zone arg? |
|---|---|---|---|---|
now() |
lubridate | POSIXct | Yes | Yes |
Sys.time() |
base R | POSIXct | Yes | No (session zone) |
today() |
lubridate | Date | No | Yes |
Sys.Date() |
base R | Date | No | No (session zone) |
Use now() when you need a datetime with explicit zone control. Use today() when only the calendar date matters. Reach for base R when you want zero dependencies; otherwise the lubridate pair is friendlier.
Common pitfalls
Pitfall 1: comparing across time zones. now("UTC") == now("Asia/Tokyo") returns TRUE because both are the same instant, but format(now("UTC")) == format(now("Asia/Tokyo")) returns FALSE. Compare POSIXct values directly, not their formatted strings.
Pitfall 2: confusing duration with period. now() + days(1) adds a period (calendar day, may differ by DST). now() + ddays(1) adds exactly 86,400 seconds. The two diverge across spring-forward and fall-back transitions.
now() is impure: it changes on every call. Two calls one second apart return different values. For reproducible analysis, capture the value once: run_started <- now(). Re-running now() in tests will break snapshot assertions.datetime.now() or datetime.now(tz=ZoneInfo("UTC")). The lubridate API is intentionally similar, including the optional time zone string.A practical workflow with now()
Logging, deadlines, and elapsed-time reporting are the three places now() shows up most often in real code.
The three patterns:
- Log a timestamp at the start of a job:
run_started <- now("UTC")and write it to a log file. - Check a deadline:
if (now() > deadline) stop("Deadline passed")wheredeadlineis a POSIXct. - Report elapsed time: capture
t0 <- now()before a step anddifftime(now(), t0, units = "secs")after.
For pipelines that span servers or time zones, always log timestamps in UTC. Convert to local time only at the display layer. This avoids the silent bugs that show up around DST transitions and across geographically distributed systems.
Try it yourself
Try it: Compute how many minutes are left until midnight in your local time zone. Save the result to ex_mins_left.
Click to reveal solution
Explanation: as.Date(now()) + 1 is tomorrow's date. Pasting "00:00:00" and parsing as POSIXct gives the next midnight. difftime() with units = "mins" returns the gap as a number.
Related lubridate functions
After mastering now(), look at:
today(): current Date (no time component)Sys.time(),Sys.Date(): base R equivalentswith_tz(),force_tz(): change time zone of a POSIXctas_datetime(),as_date(): convert between Date and POSIXcthours(),days(),minutes(): period constructors for arithmeticinterval(),difftime(): durations between two instants
For parsing existing datetime strings into POSIXct, use ymd_hms() and its siblings rather than now().
FAQ
What is the difference between now() and Sys.time() in R?
Both return the current system time as POSIXct. now() accepts a time zone argument directly: now("UTC"). Sys.time() always uses the session zone and requires a separate with_tz() call to shift it. The underlying instant is identical.
How do I get the current date without time in R?
Use today() from lubridate or Sys.Date() from base R. Both return a Date object representing today. Pass a time zone to today("Asia/Tokyo") if the calendar boundary matters for your location.
How do I get the current time in UTC with lubridate?
Call now("UTC"). The output prints in UTC and the attached time zone attribute is "UTC". Use this for logs, file names, and any value that crosses servers.
How do I subtract two datetimes in R?
Use difftime(end, start, units = "mins") (or "secs", "hours", "days"). The result is a difftime object. Coerce with as.numeric() if you need a plain number for arithmetic.
Why does now() return a different value every time I call it?
now() reads the system clock at the moment of the call. Each call advances. For reproducible output, capture the value once into a variable and reuse it: t0 <- now().