Skip to content
Empieza gratis

¿Por qué BETWEEN pierde el último día? Filtrar fechas con hora

Filtra un día, un mes o una semana completos aunque la columna tenga hora, con un intervalo semiabierto que no pierde el último día.

Curso gratis. Tu Maestro, una IA, .

Los pedidos en línea

Café Altura también vende por internet. La tienda en línea guarda cada pedido en la tabla pedidos: un pedido_id, el momento en que se creó (creado_utc) y el total en pesos. Son 304 pedidos sintéticos de febrero y marzo de 2026.

Esta columna ya es una fecha, no un texto, pero trae algo más: la hora. El primer pedido se creó el 2026-02-01 02:44:40. A una fecha con hora se le llama timestamp, y en DuckDB su tipo es TIMESTAMP.

El nombre de la columna dice utc: esas horas están en UTC, no en la hora de Ciudad de México. Eso lo resuelves en la siguiente lección. Aquí el problema es otro, y aparece aunque todo estuviera en tu hora local. Predice.

Cuatro pedidos de fin de marzo, con hora, y dos maneras de quedarte con los de marzo. Escribe qué crees que imprime cada programa y por qué.

Marzo con <= '2026-03-31'

Ejemplo 1 de 2

cerrado.py
import pandas as pdpedidos = pd.Series(pd.to_datetime([    "2026-03-30 18:05",    "2026-03-31 00:00",    "2026-03-31 09:15",    "2026-03-31 21:40",]))de_marzo = pedidos[(pedidos >= "2026-03-01") & (pedidos <= "2026-03-31")]print(len(de_marzo))

Adivinar está bien. Lo que escribas se queda en este navegador y te espera en tu curso.

Ejemplo 2 de 2, se abre cuando expliques este

Una fecha sola es la medianoche

Cuando comparas un timestamp con una fecha sin hora, la fecha vale lo mismo que su primer instante: '2026-03-31' es 2026-03-31 00:00:00. Con eso se explican tres errores comunes:

  • BETWEEN '2026-03-01' AND '2026-03-31' incluye sus dos extremos, pero el extremo final es la medianoche del 31. En pedidos cuenta 154 pedidos y 33,469 pesos. Marzo tuvo 159 pedidos y 34,630 pesos en UTC.
  • creado_utc = '2026-03-31' busca pedidos creados exactamente a las 00:00:00. Hubo 5 pedidos ese día y el filtro encuentra 0.
  • <= '2026-03-31 23:59:59' parece arreglarlo, pero deja fuera lo que pase después del último segundo entero, si tus datos guardan fracciones de segundo.

Si no ves por qué BETWEEN pierde el 31, pregúntale a tu Maestro con tus palabras.

El intervalo semiabierto

La forma que no falla es un intervalo semiabierto: desde el primer instante del periodo, incluido, hasta el primer instante del periodo siguiente, sin incluirlo.

creado_utc >= '2026-03-01' AND creado_utc < '2026-04-01'

Funciona igual para un día (>= '2026-03-31' AND < '2026-04-01'), una semana o un año, y no depende de cuántos días tiene el mes ni de cuántos decimales trae la hora.

Compara la columna con dos textos de fecha y une las condiciones con &, cada una entre paréntesis:

Python
marzo = data[(data["creado_utc"] >= "2026-03-01") & (data["creado_utc"] < "2026-04-01")]

Series.between("2026-03-01", "2026-03-31") tiene el mismo problema que BETWEEN: en pedidos cuenta 154.

SQL
SELECT count(*) AS pedidos, sum(total) AS totalFROM pedidosWHERE creado_utc >= '2026-03-01'  AND creado_utc < '2026-04-01';

Otra salida que funciona para días completos es quitarle la hora a la columna antes de comparar: creado_utc::DATE BETWEEN '2026-03-01' AND '2026-03-31' también cuenta 159.

Inténtalo

La consulta de abajo usa BETWEEN y pierde pedidos. Cámbiala por un intervalo semiabierto. Una buena respuesta tiene una fila: 159 pedidos y 34,630 pesos.

Tu turno

Cuenta los pedidos de marzo de 2026 (en UTC) y suma su total sin perder ningún pedido del día 31.

Tablas: pedidos (pedido_id, creado_utc, total)

pedidos · 304 filas

ColumnaTipo
pedido_idBIGINT
creado_utc Cuándo se hizo el pedido, en UTC, como lo guarda la tienda en línea.TIMESTAMP
total Total del pedido en pesos.BIGINT

Primeras filas

pedido_idcreado_utctotal
50012026-02-01T02:44:40Z89
50022026-02-01T02:54:59Z420
50032026-02-01T15:15:38Z89

Inténtalo sin ayuda

Ahora en pandas: cuenta los pedidos del 31 de marzo de 2026, en UTC, y suma su total. Usa un intervalo semiabierto de un día. Una buena respuesta cuenta 5 pedidos. Si te sale 0, pégale tu código a tu Maestro.

Tu turno

Cuenta los pedidos del 31 de marzo de 2026 (en UTC) y suma su total, con un intervalo semiabierto.

Datos: pedidos-en-linea, 304 filas
Los datos del ejercicio, "pedidos-en-linea". Tus cambios corren con tu código.
FilaQuitar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Página 1 de 16

Comprueba lo que sabes: ¿Cuál de estos filtros cuenta todos los pedidos del 15 de marzo de 2026, a cualquier hora?