lubridate today() in R: Current Date as a Date Object
The today() function in lubridate returns the current calendar date in R as a Date object. Pass a time zone like today("UTC") when the calendar boundary matters across regions.
today() # current date, local tz today("UTC") # date in UTC today("Asia/Tokyo") # date in Tokyo today() + days(7) # one week from now today() - days(30) # thirty days ago format(today(), "%A %d %B %Y") # weekday day month year as.numeric(today() - ymd("2024-01-01")) # days since 2024-01-01 wday(today(), label = TRUE) # weekday name
Need explanation? Read on for examples and pitfalls.
What today() does in one sentence
today() returns the current calendar date as a Date object. No time component, no seconds, just the year, month, and day in your session's time zone.
Date objects are stored internally as the number of days since 1970-01-01. This makes today() ideal for deadlines, age calculations, day counts, and anything where the time of day is noise rather than signal.
Syntax
today(tzone = "") takes one optional argument: the time zone string.
The default tzone = "" uses your session zone returned by Sys.timezone(). Pass any IANA zone name like "UTC" or "Pacific/Auckland" to read the calendar date in that location instead.
today() when the time of day is irrelevant. Date objects are smaller, sort cleanly, and avoid the timezone surprises that POSIXct values can produce around midnight boundaries.Six common patterns
1. Today in the local zone
The output is a single Date value formatted as YYYY-MM-DD. There is no time component to print.
2. Today in a different region
Around midnight UTC, regions east of the date line can already be on tomorrow's date while the US is still on yesterday's. This matters for daily reports that aggregate by calendar day.
3. Date arithmetic with periods
days(), weeks(), months(), and years() are period constructors. The %m+% operator handles end-of-month edge cases (Jan 31 + 1 month = Feb 28 instead of an invalid date).
4. Days between two dates
Subtracting two Date values returns a difftime measured in days. Coerce with as.numeric() to get a plain integer for downstream math.
5. Extract date parts
year(), month(), day(), wday(), quarter(), and week() work on any Date or POSIXct value. Use label = TRUE for the named version when displaying month or weekday.
6. Round to month, week, or year
Useful for grouping daily records into months, computing first-of-next-month billing cycles, or aligning reports to ISO week boundaries (Monday start).
Date is just a count of days since 1970-01-01. That is why subtracting two dates gives a plain difftime in days, and why today() + 7 adds seven days without any timezone math. POSIXct, by contrast, carries a time and a zone, which is where most date-time bugs originate.today() vs Sys.Date() vs now()
Three functions for current-time work, each returning a different type.
| Function | Package | Returns | Time component | Time zone arg |
|---|---|---|---|---|
today() |
lubridate | Date | No | Yes |
Sys.Date() |
base R | Date | No | No (session zone) |
now() |
lubridate | POSIXct | Yes | Yes |
Reach for today() when the calendar date is what matters and you want explicit zone control. Sys.Date() is the zero-dependency base R equivalent. Use now() when seconds, minutes, or hours are part of the answer.
Common pitfalls
Pitfall 1: comparing dates against POSIXct. Mixing today() == Sys.time() returns FALSE because R coerces the Date to a POSIXct at midnight, which almost never equals the current instant. Compare like with like: today() == as.Date(Sys.time()).
Pitfall 2: assuming today() is stable within a session. Like now(), today() reads the system clock at call time. If your script runs across midnight, the value changes mid-execution. Capture it once: today_run <- today().
today() at the same wall-clock instant and get different results. For shared logs and reports, prefer today("UTC") so the calendar boundary is unambiguous.today() corresponds to datetime.date.today(). Both ignore the time of day and return a date object that supports arithmetic in days.Try it yourself
Try it: Compute how many days remain until the next New Year's Day. Save the result to ex_days_left.
Click to reveal solution
Explanation: year(today()) + 1 gives next year, and ymd() parses the date string. Subtracting two Date values yields a difftime in days; as.numeric() converts it to a plain integer.
Related lubridate functions
After mastering today(), look at:
now(): current POSIXct datetime, with time and zoneSys.Date(),Sys.time(): base R equivalentsymd(),mdy(),dmy(): parse date strings into Date objectsfloor_date(),ceiling_date(),round_date(): align dates to month, week, or yearyear(),month(),day(),wday(): extract components from a Dateinterval(),as.duration(): durations and intervals between two dates
For the official package documentation, see the lubridate reference site.
FAQ
What is the difference between today() and Sys.Date() in R?
Both return the current calendar date as a Date object. today() accepts a time zone argument: today("UTC") returns the calendar date in UTC, which can differ from your session zone near midnight. Sys.Date() always uses the session zone and has no time zone parameter, so you would need to set the system zone first.
How do I get yesterday's date in R with lubridate?
Subtract one day: today() - days(1). The days() constructor returns a period of one calendar day; subtracting it from any Date gives you the previous day. For tomorrow, use today() + days(1). Both expressions return a Date object you can pass to any function that accepts a Date.
Why does today() return a different date in different time zones?
Calendar dates change at midnight in each region. When New York is on May 15 at 10pm, Auckland is already on May 16 at 2pm. today("Pacific/Auckland") reads the current instant and returns the date in that zone, which can be one day ahead or behind your session date.
How do I check if today is a weekend?
Use wday(today(), week_start = 1) >= 6. With week_start = 1 (Monday), Saturday is 6 and Sunday is 7, so the comparison flags weekend days. Alternatively, wday(today(), label = TRUE) %in% c("Sat", "Sun") reads more clearly.
How do I get the first day of the current month?
Call floor_date(today(), "month"). It rounds the date down to the start of its month, returning a Date for the first day. Use ceiling_date(today(), "month") for the first day of next month, useful for billing cycles or end-of-period reporting.