rguides

lubridate::ymd

ymd(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale('LC_TIME'), truncated = 0)

ymd() parses dates in year-month-day order from character strings or numbers. It is the most commonly used parser in lubridate because machine-generated date formats, CSV exports, database dumps, API responses, tend to follow this arrangement. The function auto-detects separators (hyphens, slashes, spaces, or none) and handles mixed formats within a single vector without you specifying a format string.

Syntax

ymd(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0)

ymd() is part of a family of parsers sharing the same signature. The function name encodes the element order:

FunctionElement orderExample inputParsed as
ymd()year, month, day"2009-01-02"2009-01-02
ydm()year, day, month"2009-02-01"2009-01-02
mdy()month, day, year"01-02-2009"2009-01-02
myd()month, year, day"01-2009-02"2009-01-02
dmy()day, month, year"02-01-2009"2009-01-02
dym()day, year, month"02-2009-01"2009-01-02
yq()year, quarter"2014.2"2014-04-01
ym()year, month"2012-06"2012-06-01
my()month, year"Jan 2009"2009-01-01

Use ymd_hms() (and variants) when you need to parse times as well.

Parameters

ParameterTypeDefaultDescription
...character or numericRequiredA vector of suspected dates. Each element may use a different format.
quietlogicalFALSESuppress parsing progress messages. Set to TRUE for large vectors.
tzcharacterNULLTimezone. NULL returns a Date; any other value returns POSIXct.
localecharacterSys.getlocale("LC_TIME")Locale for parsing month names. Rarely needs changing.
truncatedinteger0Allow N rightmost components to be missing. truncated = 2 parses "2012" as "2012-01-01".

Return value

Returns a Date object by default. When tz is set, returns a POSIXct object with the specified timezone instead.

ymd("20090101")
# [1] "2009-01-01"
# class: Date

ymd("20090101", tz = "UTC")
# [1] "2009-01-01 UTC"
# class: POSIXct POSIXt

The examples below demonstrate the main usage patterns you will encounter in practice: parsing individual dates, processing vectors, handling incomplete dates with truncation, controlling the output type with timezone, and integrating ymd() directly into dplyr pipelines for column conversion within a data frame.

Examples

Basic usage

library(lubridate)

# From character — any separator works
ymd("2009-01-01")
# [1] "2009-01-01"

# From numeric — compact form, no separator needed
ymd(20090101)
# [1] "2009-01-01"

ymd() handles vectors seamlessly, so you can parse an entire column of date strings in a single call. Pass a vector of any length and every element gets parsed independently regardless of its individual format, separators or no separators.

Multiple dates at once

# Multiple arguments — each argument becomes one element
ymd(090101, 90102)
# [1] "2009-01-01" "2009-01-02"

# Single vector with mixed formats
ymd(c(20090101, "2009-01-02", "2009 01 03", "2009-1-4"))
# [1] "2009-01-01" "2009-01-02" "2009-01-03" "2009-01-04"

When date strings arrive incomplete, such as "2012-06" missing the day or "2012" missing both month and day, ymd() normally rejects them. The truncated parameter tells the parser to fill in the missing components with sensible defaults, the first day of the month and January respectively.

Truncated dates

When some components are missing, set truncated to allow the parser to fill in defaults (day and month default to 01). The value passed to truncated tells the parser how many rightmost components may be absent, so truncated = 1 allows the day to be missing and truncated = 2 allows both month and day to be omitted. This is particularly useful when importing datasets where dates are stored at varying levels of precision, such as quarterly reports that sometimes record only the year.

# Year and month only — day becomes 01
ymd("2012-06", truncated = 1)
# [1] "2012-06-01"

# Year only — both month and day become 01
ymd("2012", truncated = 2)
# [1] "2012-01-01"

By default ymd() returns a plain Date object with no timezone information. When you need a full timestamp instead, pass a timezone string through the tz argument and the return value becomes a POSIXct with the correct timezone attribute attached.

With timezone

# POSIXct when tz is specified
ymd("2009-01-01", tz = "America/New_York")
# [1] "2009-01-01 EST"

In practice, ymd() rarely appears in isolation. It is most often called inside a mutate() or transmute() step to convert a character column into a proper date column as part of a data cleaning pipeline. The function integrates cleanly with dplyr because it is vectorised and returns a vector the same length as its input.

Using with dplyr

library(dplyr)

events <- data.frame(
  date_chr = c("20240315", "20240316", "20240317"),
  event = c("login", "purchase", "logout")
)

events %>%
  mutate(date = ymd(date_chr))
#       date_chr   event       date
# 1  20240315    login 2024-03-15
# 2  20240316 purchase 2024-03-16
# 3  20240317   logout 2024-03-17

While ymd() handles most practical date formats without trouble, a few edge cases produce confusing results. The problems below cover the situations where the parser’s heuristics break down and what to do instead.

Common problems

“All formats failed to parse”: When the input has too many NA values or non-date strings, lubridate cannot guess the format reliably. Switch to parse_date_time() with an explicit format list.

Two-digit years: ymd("990101") is parsed as 2099-01-01 in current lubridate. The century interpretation has changed across lubridate versions, do not rely on it for two-digit years without explicit conversion.

NA with warning: Individual unparseable elements return NA with a warning listing how many failed. This is not an error, check is.na() on the result to find the problem elements.

ymd() and its variants (mdy(), dmy(), ymd_hms(), etc.) are the primary entry points for parsing date strings in R. They use a heuristic parser that recognizes a wide range of separators and formats: ymd("2024-01-15"), ymd("20240115"), and ymd("2024/01/15") all parse correctly. When the format is ambiguous (e.g., "01/02/03"), the order implied by the function name (mdy) determines the interpretation.

After parsing, lubridate dates are stored as POSIXct or Date objects, which are internally numeric (seconds since epoch for POSIXct, days since 1970-01-01 for Date). This means arithmetic works: ymd("2024-01-15") + 30 gives the date 30 days later. For time-zone-aware operations, use the tz argument: ymd_hms("2024-01-15 14:00:00", tz = "America/New_York"). Without tz, datetime strings are parsed in UTC.

See also