Una fecha en R es un conteo de días disfrazado
Para convertir una cadena en una fecha de verdad, usa as.Date(); para obtener hoy, usa Sys.Date(). Detrás de ambas hay un truco sencillo: la clase Date de R es solo un número — el conteo de días desde el 1 de enero de 1970 — con un disfraz encima que hace que se imprima como una fecha de calendario. Puedes quitarle el disfraz con unclass():
Ese 20672 es el conteo de días en crudo, y es lo que hace funcionar todo lo demás en esta página: las comparaciones, la resta y las secuencias son solo aritmética de enteros por debajo. El disfraz es lo que la hace usable: el mismo número se imprime como fecha, se formatea como fecha y se grafica en un eje de fechas.
as.Date() parsea encantada la disposición ISO "YYYY-MM-DD" sin ayuda, que es una de varias buenas razones para almacenar las fechas así en tus archivos. Un hábito para construir pronto: un parseo fallido devuelve NA en silencio — no un error — así que echa siempre un vistazo al resultado tras parsear algo nuevo.
Las cadenas que meramente parecen fechas siguen siendo solo cadenas: "2026-08-07" < "2026-11-01" da la casualidad de que se compara correctamente porque el orden ISO coincide con el alfabético, pero "07/08/2026" se ordena como un disparate. Convierte primero, compara después.
Parsear otras disposiciones con format =
El mundo no escribe fechas ISO. Para todo lo demás, as.Date() acepta un argumento format =: una receta que describe la cadena entrante, construida con códigos %.
Las tres se parsean al mismo día. La receta debe coincidir exactamente con la cadena, separadores incluidos: "%d/%m/%Y" no parseará "07-08-2026". Los códigos que usarás de verdad:
| Código | Significado | Ejemplo |
|---|---|---|
%Y | Año de 4 dígitos | 2026 |
%y | Año de 2 dígitos | 26 |
%m | Número de mes | 08 |
%d | Día del mes | 07 |
%b | Nombre de mes abreviado | Aug |
%B | Nombre de mes completo | August |
%a | Día de la semana abreviado | Fri |
%A | Día de la semana completo | Friday |
%H | Hora (00-23) | 14 |
%M | Minuto | 30 |
%S | Segundo | 05 |
La emboscada clásica es "07/08/2026" en sí: día/mes/año en la mayor parte del mundo, mes/día/año en EE. UU., y R no puede adivinar cuál quiere decir tu archivo. Peor: una suposición errónea a menudo "funciona" — ambas lecturas son fechas válidas — hasta que llega el día 13 de algún mes y se parsea a NA (no existe el mes 13). Conoce la convención de tus datos antes de escribir la receta.
Formatear fechas para la salida
format() es la imagen especular de as.Date(): los mismos códigos %, corriendo en dirección contraria — Date dentro, cadena fuera.
Usa esto para títulos de informes, etiquetas y nombres de archivo — format(Sys.Date(), "%Y-%m-%d") produce nombres que se ordenan cronológicamente. Dos detalles que conviene saber: %d rellena con ceros ("August 07"), y %B/%A producen nombres en el idioma configurado en tu sistema — una sesión configurada en alemán imprime "Freitag" en lugar de "Friday". Mantén el formateo en los bordes de tu script, para humanos; internamente, deja las fechas como Dates.
Aritmética de fechas y secuencias
Como una Date es un conteo de días, la aritmética funciona como cabría esperar. Restar dos fechas da un objeto difftime:
Tres hábitos para llevarte de ese bloque. Primero, envuelve un difftime en as.numeric() antes de hacer cálculos con él — difftime lleva un atributo de unidades que puede sorprender a cálculos posteriores. Segundo, cuando las unidades importan, decláralas con difftime(units = ) en lugar de aceptar lo que R escoja. Tercero, sumar un número a secas significa sumar días — no existe + 1 mes en R base, porque "un mes" no es un número fijo de días.
Para avanzar con conciencia de calendario, usa seq(), que entiende "day", "week", "month", "quarter" y "year":
Las secuencias mensuales son la herramienta estándar para períodos de informes y cortes de eje. Una peculiaridad: empieza una secuencia mensual el día 31 y R sigue contando días reales a través de los meses que no lo tienen, así que la entrada de "febrero" cae a principios de marzo. Ancla las secuencias mensuales en el día 1 y deriva cualquier otra cosa a partir de ahí.
Extraer partes de una fecha
R base tiene dos extractores de conveniencia y un idioma general. weekdays() y months() devuelven nombres; para números, haz el viaje de ida y vuelta por format():
El movimiento format()-y-luego-as.integer() parece dar un rodeo, pero es el idioma estándar de R base, y está vectorizado: dale una columna entera de fechas y recibes una columna entera de años de vuelta. Eso es exactamente lo que quieres tras importar un conjunto de datos con fechas desde un archivo CSV: parsea la columna de fechas una vez con as.Date() y luego deriva columnas de año y mes para agrupar.
Cuando los días no bastan: POSIXct, y lubridate
Date no tiene concepto de horas. En cuanto tus datos tienen timestamps — entradas de log, lecturas de sensores, "pedido realizado a las 14:32" — necesitas POSIXct, la clase de fecha-hora de R: segundos desde 1970 en lugar de días, y consciente de la zona horaria.
Todo se traslada: los mismos códigos % (ahora incluyendo %H, %M, %S) funcionan para el parseo y para format(), la resta da difftimes, Sys.time() es "ahora". La nueva carga es la zona horaria — pasa tz = explícitamente al parsear, porque de lo contrario dos sesiones en zonas distintas leerán la misma cadena como dos instantes diferentes. Y resiste la tentación de almacenar datos de calendario como POSIXct "por si acaso": un cumpleaños almacenado como medianoche-en-alguna-zona puede imprimirse como el día anterior en otra zona, un bug genuinamente miserable de rastrear. Días enteros: Date. Instantes: POSIXct.
Por último, el paquete lubridate es la cara más amable que la mayoría del código tidyverse le pone a todo lo anterior — vale la pena adoptarlo una vez que la mecánica base tenga sentido:
library(lubridate)
ymd("2026-08-07") # order-based parsing: no format string
mdy("08/07/2026") # ...you just say which order the parts come in
dmy("7 August 2026")
floor_date(Sys.Date(), "month") # snap to the start of the period
ymd(), mdy() y dmy() reemplazan las recetas de formato con una simple declaración del orden de las partes, y floor_date() resuelve "agrupa estos timestamps por mes" en una sola llamada. lubridate cabalga sobre las mismas clases Date/POSIXct por debajo — un volante mejor, no un motor distinto.
Lo que te llevas
- Una
Datees un conteo de días desde 1970-01-01 disfrazado para imprimirse como fecha;unclass()muestra el número. as.Date("2026-08-07")parsea ISO directamente; cualquier otra cosa necesita una recetaformat =de códigos%— y un parseo fallido devuelveNA, en silencio.format(fecha, "...")es el inverso: los mismos códigos, produciendo cadenas para mostrar.- La resta da un difftime — establece
units =explícitamente,as.numeric()antes de hacer cálculos.+ nsuma días; para meses, usaseq(by = "month"). weekdays(),months()y el idiomaas.integer(format(...))extraen partes, vectorizados.Datepara días enteros,POSIXct(con untzexplícito) para timestamps; lubridate hace ambos más amables.
A continuación: qué hacer cuando R te grita — leer mensajes de error y depurarlos con método.
Preguntas frecuentes
¿Cómo se convierte una cadena a fecha en R?
Con as.Date(). Si la cadena está en formato ISO, funciona sin más: as.Date("2026-08-07"). Cualquier otra disposición necesita una receta format = construida con códigos %: as.Date("07/08/2026", format = "%d/%m/%Y"). Un parseo fallido devuelve NA en lugar de un error, así que revisa el resultado.
¿Cómo se obtiene la fecha de hoy en R?
Sys.Date() devuelve hoy como un objeto Date; Sys.time() devuelve la fecha-hora actual como POSIXct. Ambas salen del reloj y la configuración de zona horaria de tu ordenador.
¿Cómo se calcula la diferencia entre dos fechas en R?
Réstalas: as.Date("2026-08-07") - as.Date("2026-01-01") da un difftime de 218 días. Envuélvelo en as.numeric() para usar el número en cálculos, o llama a difftime(d1, d2, units = "weeks") para elegir tú las unidades en lugar de dejar que R decida.
¿Cuál es la diferencia entre Date y POSIXct en R?
Date almacena días enteros (internamente: días desde 1970-01-01) y no sabe nada de horas ni de zonas horarias. POSIXct almacena un instante en el tiempo (segundos desde 1970) y es consciente de la zona horaria. Usa Date para datos de calendario como cumpleaños y fechas límite; usa POSIXct solo cuando importa la hora del día, como en timestamps y logs.