Dates & Time¶
Dates are fundamental to analytics. ASQL provides a clean, intuitive, and portable date syntax that compiles to the right SQL for any dialect.
Date Literals¶
Use the @ prefix for date literals:
from users
where signup_date >= @2024-01-01
from orders
where order_date between @2024-01-01 and @2024-12-31
This compiles to DATE '2024-01-01' in SQL.
For timestamps, include the time:
@2024-01-15T10:30:00
Time Truncation Functions¶
Truncate dates to a specific unit:
| Function | Result | Example Output |
|---|---|---|
year(date) |
Truncate to year start | 2025-01-01 |
month(date) |
Truncate to month start | 2025-01-01 |
week(date) |
Truncate to week start | 2025-01-06 |
day(date) |
Truncate to day | 2025-01-15 |
hour(date) |
Truncate to hour | 2025-01-15 14:00:00 |
quarter(date) |
Truncate to quarter start | 2025-01-01 |
from orders
group by month(created_at) (
sum(amount) as revenue
)
Natural Language Alternatives¶
All of these are equivalent:
year(created_at) -- function style
year created_at -- space style
year_created_at -- underscore style
year of created_at -- "of" style
Date Part Extraction¶
Extract specific parts (returns integers, not dates):
| Expression | Returns | Example |
|---|---|---|
day of week date |
1-7 | 3 (Wednesday) |
day of month date |
1-31 | 15 |
day of year date |
1-366 | 45 |
week of year date |
1-52 | 12 |
month of year date |
1-12 | 6 |
quarter of year date |
1-4 | 2 |
-- Weekend orders
from orders
where day of week order_date in (6, 7)
-- Sales by day of week
from sales
group by day of week sale_date (
sum(amount) as revenue
)
Truncation vs Extraction¶
- Truncation (
month(date)): Returns a date, for time series - Extraction (
month of year date): Returns an integer, for "all Januaries"
month(created_at) -- → 2025-01-01 (date)
month of year created_at -- → 1 (integer)
Date Arithmetic¶
Add or subtract from dates using clean inline syntax:
order_date + 7 days
order_date - 1 month
order_date + 2 weeks
created_at + 24 hours
Singular and plural both work:
order_date + 1 day -- singular
order_date + 7 days -- plural
This compiles to dialect-appropriate SQL:
-- PostgreSQL
order_date + INTERVAL '7 days'
-- MySQL
DATE_ADD(order_date, INTERVAL 7 DAY)
-- SQL Server
DATEADD(day, 7, order_date)
Date Difference¶
Calculate the difference between dates:
days(end_date - start_date) -- Integer days
months(end_date - start_date) -- Integer months
years(end_date - start_date) -- Integer years
hours(end_date - start_date) -- Integer hours
weeks(end_date - start_date) -- Integer weeks
Alternative function syntax:
days_between(start_date, end_date)
months_between(start_date, end_date)
Example:
from orders
select
days(shipped_date - order_date) as fulfillment_days,
months(now() - customer_since) as customer_tenure_months
Relative Dates¶
Past Dates (ago)¶
from users
where last_login >= 7 days ago
from orders
where created_at >= 30 days ago
where created_at >= 1 month ago
Future Dates (from now)¶
from orders
where estimated_delivery <= 3 days from now
from reminders
where remind_at <= 1 hour from now
These compile to dialect-appropriate SQL using CURRENT_TIMESTAMP and intervals.
Time Since/Until Functions¶
Calculate time elapsed since a date, or time remaining until a future date.
Three Equivalent Syntaxes¶
All of these are equivalent:
-- Function call (recommended)
days_since(created_at)
months_until(due_date)
-- Space notation (natural language)
days since created_at
months until due_date
-- Underscore alias (compact)
days_since_created_at
months_until_due_date
Available Functions¶
| Since (time elapsed) | Until (time remaining) |
|---|---|
days_since(col) |
days_until(col) |
weeks_since(col) |
weeks_until(col) |
months_since(col) |
months_until(col) |
years_since(col) |
years_until(col) |
hours_since(col) |
hours_until(col) |
minutes_since(col) |
minutes_until(col) |
seconds_since(col) |
seconds_until(col) |
Examples¶
from users
select
name,
days_since(last_login), -- Function call
months since signup_date, -- Space notation
years_since_birth_date as age -- Underscore alias
from tasks
where days_until(due_date) < 7
-- or: where days until due_date < 7
-- or: where days_until_due_date < 7
Week Start Configuration¶
Default: ISO 8601 standard (Monday = day 1)
week(created_at) -- Default: ISO (Monday start)
week_monday(created_at) -- Explicit Monday start
week_sunday(created_at) -- US-style Sunday start
day of week created_at -- 1 = Monday, 7 = Sunday (ISO)
Time Bucketing (Grouping)¶
Time bucketing is simply grouping by a time function:
from orders
group by month(created_at) (
sum(amount) as revenue
)
from sessions
group by week(start_time) (
count(distinct user_id) as active_users
)
Timezone Handling¶
Use :: syntax for timezone conversion:
-- Short timezone codes
created_at::PST
created_at::UTC
created_at::EST
-- Full IANA timezone names (quoted)
created_at::"America/Los_Angeles"
created_at::"Europe/London"
-- Chained with other operations
month(created_at::PST)
created_at::UTC + 7 days
Quick Reference¶
| Operation | Syntax | Example |
|---|---|---|
| Date literal | @YYYY-MM-DD |
@2025-01-15 |
| Truncation | unit(col) |
month(created_at) |
| Extraction | unit of period col |
day of week created_at |
| Add/subtract | date + N unit |
order_date + 7 days |
| Difference | unit(date1 - date2) |
days(end - start) |
| Relative past | N unit ago |
7 days ago |
| Relative future | N unit from now |
3 days from now |
| Time since | unit_since(col) or unit since col |
days_since(created_at) |
| Time until | unit_until(col) or unit until col |
days_until(due_date) |
| Timezone | col::TZ |
created_at::PST |
Real-World Examples¶
Daily Revenue for Last 30 Days¶
from orders
where created_at >= 30 days ago
group by day(created_at) (
sum(amount) as revenue
)
order by day(created_at)
Monthly User Signups¶
from users
group by month(created_at) (
# as signups
)
order by month
Orders with Fulfillment Time¶
from orders
where shipped_date is not null
select
id,
order_date,
shipped_date,
days(shipped_date - order_date) as fulfillment_days
Active Users Last Week¶
from users
where last_login >= 7 days ago
select name, email, days_since_last_login
Next Steps¶
- Aggregations — Grouping by date periods
- Guaranteed Groups — Gap-filling for time series
- Window Functions — Prior/next for date comparisons