---
title: "How to add and subtract time intervals in ClickHouse®"
excerpt: "Master ClickHouse® date arithmetic with addDays, subtractMonths, date_add functions plus performance tips, timezone handling, and real API examples."
authors: "Cameron Archer"
categories: "AI Resources"
createdOn: "2025-10-03 17:22:12"
publishedOn: "2025-10-03 17:22:12"
updatedOn: "2025-10-03 17:22:12"
status: "published"
---

Working with timestamps and dates in ClickHouse® means you'll inevitably need to add or subtract time intervals, whether you're calculating retention periods, building time-series comparisons, or filtering data by relative date ranges. ClickHouse® offers multiple approaches for date arithmetic, from simple helper functions like `addDays()` to SQL-standard `DATE_ADD` syntax.

This guide covers the practical syntax for each method, common edge cases that can trip you up in production, and performance considerations when working with large datasets.

## Quick Reference to ClickHouse® Date Arithmetic Functions

ClickHouse® gives you several ways to add or subtract time intervals from dates and datetimes. You can use helper functions like `addDays()` and `subtractMonths()`, or the SQL-standard `DATE_ADD` and `DATE_SUB` functions with interval specifications.

The helper functions follow a simple pattern: the function name tells you the operation and time unit, then you provide the date value and the number of units to add or subtract. ClickHouse® handles tricky cases like leap years and month-end rollovers automatically.

### addSeconds and subtractSeconds

The `addSeconds()` and `subtractSeconds()` functions work with both Date and DateTime types, though they're most useful when you're working with timestamps that include time components.

```sql
SELECT
    addSeconds(now(), 30) AS thirty_seconds_later,
    subtractSeconds(now(), 3600) AS one_hour_ago;
```

When you use Date types with these functions, ClickHouse® first converts the date to a DateTime at midnight before doing the math.

### addMinutes and subtractMinutes

Minute arithmetic comes in handy for calculating time windows in real-time analytics scenarios.

```sql
SELECT
    addMinutes(toDateTime('2024-01-15 14:30:00'), 45) AS meeting_end,
    subtractMinutes(now(), 15) AS fifteen_minutes_ago;
```

You'll often use these functions in WHERE clauses to filter data within specific time ranges, like finding events from the last 30 minutes.

### addHours and subtractHours

Hour-based calculations are common for daily reporting and time-based data segmentation.

```sql
SELECT
    addHours(toDateTime('2024-01-15 09:00:00'), 8) AS end_of_workday,
    subtractHours(now(), 6) AS six_hours_ago;
```

The functions respect timezone settings when working with DateTime64 types that include timezone information.

### addDays and subtractDays

Day arithmetic represents the most frequently used date functions in ClickHouse® queries. The functions work seamlessly with both Date and DateTime types.

```sql
SELECT
    addDays(today(), 7) AS next_week,
    subtractDays(toDate('2024-01-15'), 30) AS thirty_days_prior;
```

The `subtractDays()` function appears constantly in analytical queries for comparing current data with historical periods.

### addWeeks and subtractWeeks

Week-based functions provide a convenient shorthand for 7-day intervals, especially useful in business reporting contexts.

```sql
SELECT
    addWeeks(today(), 2) AS two_weeks_from_now,
    subtractWeeks(toDate('2024-01-15'), 4) AS four_weeks_ago;
```

The functions always add or subtract exactly 7 days, regardless of how weeks align with month boundaries.

### addMonths and subtractMonths

Month arithmetic requires special handling for edge cases like February 29th or January 31st plus one month.

```sql
SELECT
    addMonths(toDate('2024-01-31'), 1) AS february_result,
    subtractMonths(toDate('2024-03-31'), 1) AS february_from_march;
```

ClickHouse® handles invalid dates by moving to the last valid day of the target month. Adding one month to January 31st yields February 29th in leap years or February 28th otherwise.

### addYears and subtractYears

Year arithmetic functions handle leap year transitions automatically, making them reliable for long-term date calculations.

```sql
SELECT
    addYears(toDate('2024-02-29'), 1) AS next_year_leap_day,
    subtractYears(today(), 5) AS five_years_ago;
```

When adding years to February 29th, the result becomes February 28th in non-leap years.

## Using date_add and date_sub Aliases in SQL Queries

The `DATE_ADD` and `DATE_SUB` functions provide SQL-standard alternatives to the helper functions, accepting an interval unit as a parameter. The aliases offer more flexibility when the interval type comes from a variable or calculation.

```sql
SELECT
    DATE_ADD(HOUR, 3, now()) AS three_hours_later,
    DATE_SUB(DAY, 7, today()) AS last_week;
```

### Supported Units and Abbreviations

ClickHouse® supports several interval units with `DATE_ADD` and `DATE_SUB`:

- **SECOND:** Add or subtract seconds from DateTime values
- **MINUTE:** Minute-level arithmetic for time calculations
- **HOUR:** Hour-based intervals for daily operations
- **DAY:** Most common unit for date arithmetic
- **WEEK:** Seven-day intervals for weekly reporting
- **MONTH:** Monthly calculations with automatic edge case handling
- **QUARTER:** Three-month intervals for business reporting
- **YEAR:** Annual arithmetic with leap year awareness

The unit names are case-insensitive, so `day`, `DAY`, and `Day` all work identically.

### Sample Query Comparing Alias and Helper

Both approaches produce identical results, but the syntax differs in readability and parameter order:

```sql
SELECT
    -- Using helper functions
    addDays(today(), -7) AS last_week_helper,
    subtractDays(today(), 7) AS last_week_subtract,

    -- Using DATE_ADD/DATE_SUB aliases
    DATE_ADD(DAY, -7, today()) AS last_week_add_alias,
    DATE_SUB(DAY, 7, today()) AS last_week_sub_alias;
```

The helper functions place the date first, while the aliases follow SQL standard order with the interval unit first.

## Choosing Between Helper Functions and Interval Literals

ClickHouse® also supports INTERVAL literal syntax for date arithmetic, similar to PostgreSQL and other SQL databases. The choice between approaches often depends on query complexity and readability preferences.

```sql
-- INTERVAL literal syntax
SELECT
    today() + INTERVAL 1 MONTH AS next_month,
    now() - INTERVAL 2 HOUR AS two_hours_ago;
```

### When to Prefer Interval Literals

INTERVAL literals shine when combining multiple time units in a single expression or when the syntax feels more natural to read.

```sql
SELECT
    now() + INTERVAL 1 MONTH + INTERVAL 2 DAY AS complex_future_date,
    created_at - INTERVAL 1 YEAR - INTERVAL 6 MONTH AS eighteen_months_ago
FROM events;
```

This approach becomes particularly readable when building complex date expressions that involve multiple different interval types.

### When Helper Functions Are Clearer

Helper functions work better when the interval value comes from a column, parameter, or calculation rather than a literal constant.

```sql
SELECT
    addDays(order_date, shipping_days) AS estimated_delivery,
    subtractMonths(today(), report_period_months) AS report_start_date
FROM orders;
```

The helper function syntax also tends to be more discoverable through IDE autocomplete and feels more natural when the interval is dynamic.

## Common Pitfalls With Months, Years, and Time Zones

Date arithmetic becomes tricky when dealing with variable-length months, leap years, and timezone transitions. Understanding edge cases prevents unexpected results in production queries.

### February and Leap Years

Adding months to dates near month boundaries can produce surprising results, especially around February in leap years.

```sql
SELECT
    addMonths(toDate('2024-01-31'), 1) AS jan_31_plus_month,  -- 2024-02-29
    addMonths(toDate('2023-01-31'), 1) AS jan_31_non_leap;    -- 2023-02-28
```

ClickHouse® resolves invalid dates by finding the last valid day of the target month, which explains why January 31st plus one month becomes February 28th or 29th.

### End-of-Month Rollovers

Month arithmetic with dates like March 31st can create unexpected rollover behavior when the target month has fewer days.

```sql
SELECT
    addMonths(toDate('2024-03-31'), 1) AS march_31_plus_month,  -- 2024-04-30
    addMonths(toDate('2024-05-31'), 1) AS may_31_plus_month;    -- 2024-06-30
```

This behavior is consistent but can catch developers off guard when building month-over-month comparison queries.

### Daylight Saving Transitions

Hour arithmetic during daylight saving transitions can produce times that don't exist or exist twice, depending on your timezone settings.

```sql
-- This query behavior depends on your timezone setting
SELECT
    addHours(toDateTime('2024-03-10 01:30:00'), 1) AS spring_forward,
    addHours(toDateTime('2024-11-03 01:30:00'), 1) AS fall_back;
```

For consistent behavior across timezone changes, consider using UTC timestamps for calculations and converting to local time only for display.

## Performance Tips for High-Volume Date Math

Date arithmetic performance becomes critical when processing millions of rows or running frequent analytical queries. A few optimization strategies can significantly improve query execution times.

### Avoiding Implicit Casts

Using proper DateTime types instead of strings prevents expensive implicit conversions during date arithmetic operations.

```sql
-- Slower: string conversion required
SELECT addDays('2024-01-15', 7) AS next_week;

-- Faster: native DateTime type
SELECT addDays(toDate('2024-01-15'), 7) AS next_week;
```

When possible, store timestamps as DateTime or DateTime64 types in your tables rather than strings to avoid conversion overhead.

### Using Constant Folding

ClickHouse® can optimize date arithmetic expressions involving constants at query planning time rather than computing them for each row.

```sql
-- Optimized: constant folded at planning time
SELECT * FROM events
WHERE created_at >= subtractDays(today(), 30);

-- Less optimal: computed per row
SELECT * FROM events
WHERE created_at >= subtractDays(created_at, days_offset);
```

Place constant date calculations in the WHERE clause when filtering large datasets for better performance.

### Pre-Computing Intervals in Materialized Views

For frequently-accessed date ranges, consider pre-computing the intervals in [materialized views](https://tinybird.co/docs/forward/work-with-data/optimize/materialized-views) to avoid repeated calculations.

```sql
CREATE MATERIALIZED VIEW daily_metrics_mv
ENGINE = SummingMergeTree()
ORDER BY (date, metric_type)
AS SELECT
    toDate(timestamp) AS date,
    metric_type,
    sum(value) AS total_value
FROM raw_events
GROUP BY date, metric_type;
```

This approach works particularly well for time-series dashboards that repeatedly query the same date ranges.

## Building ClickHouse®-based time series analytics APIs with Tinybird

Transform your date arithmetic queries into comprehensive customer lifecycle analytics using [Tinybird](https://www.tinybird.co)'s managed ClickHouse® platform. This approach enables real-time cohort analysis, retention tracking, and customer journey insights across multiple time dimensions.

Instead of managing ClickHouse® infrastructure, you define your customer analytics logic as code and [Tinybird](https://www.tinybird.co) handles the operational complexity. The platform provides sub-second query performance for complex time-based customer analytics while abstracting away database administration.

### 1. Create a data source for customer lifecycle events

Define your customer lifecycle data structure in a [data source](https://www.tinybird.co/docs/forward/get-data-in/data-sources) file:

```tinybird
SCHEMA >
    `timestamp` DateTime64(3, 'UTC') `json:$.timestamp`,
    `customer_id` String `json:$.customer_id`,
    `event_type` LowCardinality(String) `json:$.event_type`,
    `session_id` String `json:$.session_id`,
    `product_id` String `json:$.product_id`,
    `revenue` Decimal(10, 2) `json:$.revenue`,
    `page_views` UInt32 `json:$.page_views`,
    `time_on_site` UInt32 `json:$.time_on_site`,
    `device_type` LowCardinality(String) `json:$.device_type`,
    `country` LowCardinality(String) `json:$.country`,
    `subscription_tier` LowCardinality(String) `json:$.subscription_tier`,
    `lifetime_value` Decimal(12, 2) `json:$.lifetime_value`,
    `churn_risk_score` Float32 `json:$.churn_risk_score`

ENGINE "MergeTree"
ENGINE_PARTITION_KEY "toYYYYMM(timestamp)"
ENGINE_SORTING_KEY "timestamp, customer_id"
```

This schema captures comprehensive customer lifecycle data including events, revenue, engagement metrics, and predictive indicators for advanced customer analytics.

### 2. Ingest example data using the Events API

Add sample customer lifecycle data to test your analytics using the [Events API](https://www.tinybird.co/docs/forward/get-data-in/events-api). First, start your local Tinybird development environment:

```bash
# Start Tinybird locally
tb dev
```

Then ingest sample data to your local instance:

```bash
# Ingest sample customer lifecycle data to localhost
curl -X POST "http://localhost:7181/v0/events" \
  -H "Authorization: Bearer $TINYBIRD_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "timestamp": "2024-01-15T10:30:00.000Z",
      "customer_id": "cust_001",
      "event_type": "signup",
      "session_id": "sess_001",
      "product_id": "prod_premium",
      "revenue": 99.99,
      "page_views": 12,
      "time_on_site": 1800,
      "device_type": "desktop",
      "country": "US",
      "subscription_tier": "premium",
      "lifetime_value": 99.99,
      "churn_risk_score": 0.1
    },
    {
      "timestamp": "2024-01-15T11:00:00.000Z",
      "customer_id": "cust_002",
      "event_type": "purchase",
      "session_id": "sess_002",
      "product_id": "prod_basic",
      "revenue": 29.99,
      "page_views": 8,
      "time_on_site": 1200,
      "device_type": "mobile",
      "country": "CA",
      "subscription_tier": "basic",
      "lifetime_value": 29.99,
      "churn_risk_score": 0.3
    },
    {
      "timestamp": "2024-01-15T12:00:00.000Z",
      "customer_id": "cust_003",
      "event_type": "upgrade",
      "session_id": "sess_003",
      "product_id": "prod_enterprise",
      "revenue": 199.99,
      "page_views": 15,
      "time_on_site": 2400,
      "device_type": "desktop",
      "country": "GB",
      "subscription_tier": "enterprise",
      "lifetime_value": 199.99,
      "churn_risk_score": 0.05
    }
  ]'
```

This sample data includes various customer lifecycle events across different subscription tiers, devices, and regions to test your analytics pipes.

### 3. Build customer lifecycle analytics pipes

Create [pipes](https://www.tinybird.co/docs/forward/work-with-data/pipes) that analyze customer behavior across multiple time dimensions:

```tinybird
NODE customer_events
SQL >
    %
    SELECT
        timestamp,
        customer_id,
        event_type,
        session_id,
        product_id,
        revenue,
        page_views,
        time_on_site,
        device_type,
        country,
        subscription_tier,
        lifetime_value,
        churn_risk_score,
        -- Date arithmetic for cohort analysis
        toDate(timestamp) AS event_date,
        toStartOfMonth(timestamp) AS cohort_month,
        toStartOfWeek(timestamp, 1) AS cohort_week,
        subtractDays(timestamp, 30) AS thirty_days_ago,
        subtractDays(timestamp, 90) AS ninety_days_ago,
        subtractDays(timestamp, 365) AS one_year_ago
    FROM customer_events
    WHERE timestamp >= {{DateTime(start_date, '2024-01-01 00:00:00')}}
      AND timestamp <= {{DateTime(end_date, '2024-12-31 23:59:59')}}
    {\% if defined(customer_filter) %}
      AND customer_id = {{String(customer_filter)}}
    {\% end %}
    {\% if defined(event_type_filter) %}
      AND event_type = {{String(event_type_filter)}}
    {\% end %}
    {\% if defined(country_filter) %}
      AND country = {{String(country_filter)}}
    {\% end %}

NODE customer_cohort_analysis
SQL >
    %
    SELECT
        cohort_month,
        subscription_tier,
        country,
        count(DISTINCT customer_id) AS total_customers,
        count() AS total_events,
        sum(revenue) AS total_revenue,
        round(avg(lifetime_value), 2) AS avg_lifetime_value,
        round(avg(churn_risk_score) * 100, 2) AS avg_churn_risk_percent,
        round(avg(time_on_site), 2) AS avg_time_on_site,
        round(avg(page_views), 2) AS avg_page_views,
        -- Cohort retention metrics
        count(DISTINCT CASE
            WHEN timestamp >= addDays(cohort_month, 30)
            AND timestamp < addDays(cohort_month, 60)
            THEN customer_id
        END) AS retained_30_days,
        count(DISTINCT CASE
            WHEN timestamp >= addDays(cohort_month, 90)
            AND timestamp < addDays(cohort_month, 120)
            THEN customer_id
        END) AS retained_90_days,
        -- Growth calculations
        round((sum(revenue) - lag(sum(revenue)) OVER (PARTITION BY subscription_tier, country ORDER BY cohort_month)) * 100.0 / lag(sum(revenue)) OVER (PARTITION BY subscription_tier, country ORDER BY cohort_month), 2) AS revenue_growth_percent
    FROM customer_events
    GROUP BY cohort_month, subscription_tier, country
    ORDER BY cohort_month DESC, total_revenue DESC
    {\% if defined(limit) %}
    LIMIT {{Int32(limit, 50)}}
    {\% end %}

TYPE ENDPOINT
```

Create a customer journey analysis pipe:

```tinybird
NODE customer_journey_analysis
SQL >
    %
    SELECT
        customer_id,
        subscription_tier,
        country,
        min(timestamp) AS first_event,
        max(timestamp) AS last_event,
        count() AS total_events,
        sum(revenue) AS total_revenue,
        round(avg(churn_risk_score) * 100, 2) AS avg_churn_risk_percent,
        round(avg(time_on_site), 2) AS avg_time_on_site,
        round(avg(page_views), 2) AS avg_page_views,
        -- Journey duration calculations
        dateDiff('day', min(timestamp), max(timestamp)) AS journey_days,
        dateDiff('hour', min(timestamp), max(timestamp)) AS journey_hours,
        -- Recent activity indicators
        CASE
            WHEN max(timestamp) >= subtractDays(now(), 7) THEN 'active'
            WHEN max(timestamp) >= subtractDays(now(), 30) THEN 'recent'
            WHEN max(timestamp) >= subtractDays(now(), 90) THEN 'dormant'
            ELSE 'inactive'
        END AS activity_status,
        -- Customer segmentation
        CASE
            WHEN sum(revenue) >= 500 AND avg(churn_risk_score) < 0.2 THEN 'high_value_low_risk'
            WHEN sum(revenue) >= 200 AND avg(churn_risk_score) < 0.4 THEN 'medium_value_medium_risk'
            WHEN sum(revenue) < 100 OR avg(churn_risk_score) >= 0.6 THEN 'low_value_high_risk'
            ELSE 'standard'
        END AS customer_segment
    FROM customer_events
    GROUP BY customer_id, subscription_tier, country
    ORDER BY total_revenue DESC, avg_churn_risk_percent ASC
    {\% if defined(limit) %}
    LIMIT {{Int32(limit, 100)}}
    {\% end %}

TYPE ENDPOINT
```

### 4. Test locally and deploy to cloud

Test your customer lifecycle analytics APIs locally first:

```bash
# Test customer cohort analysis locally
curl "http://localhost:7181/v0/pipes/customer_cohort_analysis.json?start_date=2024-01-01&end_date=2024-01-31&limit=10" \
  -H "Authorization: Bearer $TINYBIRD_TOKEN"
```

Here's an example API response:

```json
{
  "meta": [
    {
      "name": "cohort_month",
      "type": "Date"
    },
    {
      "name": "subscription_tier",
      "type": "String"
    },
    {
      "name": "country",
      "type": "String"
    },
    {
      "name": "total_customers",
      "type": "UInt64"
    },
    {
      "name": "total_events",
      "type": "UInt64"
    },
    {
      "name": "total_revenue",
      "type": "Decimal(10,2)"
    },
    {
      "name": "avg_lifetime_value",
      "type": "Float64"
    },
    {
      "name": "avg_churn_risk_percent",
      "type": "Float64"
    },
    {
      "name": "avg_time_on_site",
      "type": "Float64"
    },
    {
      "name": "avg_page_views",
      "type": "Float64"
    },
    {
      "name": "retained_30_days",
      "type": "UInt64"
    },
    {
      "name": "retained_90_days",
      "type": "UInt64"
    },
    {
      "name": "revenue_growth_percent",
      "type": "Float64"
    }
  ],
  "data": [
    {
      "cohort_month": "2024-01-01",
      "subscription_tier": "premium",
      "country": "US",
      "total_customers": 1,
      "total_events": 1,
      "total_revenue": 99.99,
      "avg_lifetime_value": 99.99,
      "avg_churn_risk_percent": 10.0,
      "avg_time_on_site": 1800.0,
      "avg_page_views": 12.0,
      "retained_30_days": 0,
      "retained_90_days": 0,
      "revenue_growth_percent": null
    }
  ],
  "rows": 1,
  "statistics": {
    "elapsed": 0.001234,
    "rows_read": 3,
    "bytes_read": 1024
  }
}
```

Once you're satisfied with your local testing, deploy to Tinybird's cloud infrastructure:

```bash
# Deploy to cloud
tb --cloud deploy
```

Test your production APIs:

```bash
# Customer cohort analysis
curl "https://api.tinybird.co/v0/pipes/customer_cohort_analysis.json?start_date=2024-01-01&end_date=2024-06-30&subscription_tier=premium&limit=20" \
  -H "Authorization: Bearer $TINYBIRD_TOKEN"

# Customer journey analysis
curl "https://api.tinybird.co/v0/pipes/customer_journey_analysis.json?start_date=2024-01-01&end_date=2024-12-31&country_filter=US&limit=50" \
  -H "Authorization: Bearer $TINYBIRD_TOKEN"
```

The APIs return comprehensive customer lifecycle insights including cohort retention, journey analysis, revenue trends, churn risk assessment, and customer segmentation. This enables real-time customer analytics across multiple time dimensions, subscription tiers, and geographic regions for data-driven customer success strategies.

## Wrap up and next steps with managed ClickHouse®

While ClickHouse®'s date arithmetic functions are powerful, operating ClickHouse® at scale introduces significant operational complexity. Managing clusters, handling replication, optimizing queries, and ensuring high availability requires dedicated engineering resources and deep ClickHouse® expertise.

Production ClickHouse® deployments face challenges like:

- **Cluster Management**: Coordinating multiple nodes, handling failovers, and maintaining data consistency across replicas
- **Query Optimization**: Tuning performance for complex date arithmetic across millions of rows while maintaining sub-second response times
- **Infrastructure Scaling**: Automatically scaling resources during traffic spikes without downtime
- **Monitoring & Alerting**: Tracking query performance, resource usage, and system health across distributed nodes
- **Backup & Recovery**: Implementing reliable backup strategies and disaster recovery procedures

[Tinybird](https://www.tinybird.co) eliminates these operational burdens by providing [managed ClickHouse® infrastructure](https://www.tinybird.co/clickhouse) with built-in optimizations for real-time analytics. The platform handles cluster management, automatic scaling, and query optimization while providing a streamlined developer experience for building analytics APIs.

[Start with Tinybird's free plan](https://cloud.tinybird.co/signup) and deploy your first analytics API in minutes.

## FAQs About ClickHouse® Interval Arithmetic

### Why does subtractMonths sometimes return a date in the next month?

ClickHouse® handles invalid dates by moving to the last valid day of the target month, which can appear as moving forward when subtracting. For example, subtracting one month from March 31st yields February 28th or 29th, but the day-of-month decreased even though it might seem like the function moved "forward" to a valid February date.

### Can I use negative values with addDays?

Yes, `addDays(date, -7)` is equivalent to `subtractDays(date, 7)` and both produce identical results. This pattern works for all the helper functions; negative values in add functions behave exactly like positive values in subtract functions.

### Is date_add available in older ClickHouse® versions?

The `DATE_ADD` and `DATE_SUB` aliases were introduced in ClickHouse® 21.x, but the underlying helper functions work in all modern versions. If you're using an older ClickHouse® version, stick with functions like `addDays()` and `subtractMonths()` for compatibility.

## Additional resources

- [Date and Time Functions](https://clickhouse.com/docs/en/sql-reference/functions/date-time-functions)
- [addDays Function](https://clickhouse.com/docs/en/sql-reference/functions/date-time-functions#adddays)
- [subtractMonths Function](https://clickhouse.com/docs/en/sql-reference/functions/date-time-functions#subtractmonths)
- [INTERVAL Literals](https://clickhouse.com/docs/en/sql-reference/functions/date-time-functions#interval-literals)
- [Materialized Views](https://clickhouse.com/docs/en/engines/table-engines/special/materializedview)
- [Tinybird vs ClickHouse®](https://www.tinybird.co/blog-posts/tinybird-vs-clickhouse)
- [How to calculate date differences using unit boundaries with dateDiff in ClickHouse®](https://www.tinybird.co/blog-posts/how-to-use-datediff-unit-boundaries-clickhouse)
- [ClickHouse® age function for timestamp difference](https://www.tinybird.co/blog-posts/clickhouse-age-function-timestamp-difference)
- [Convert date to Unix timestamp in ClickHouse®](https://www.tinybird.co/blog-posts/convert-date-to-unix-timestamp-clickhouse)
- [Parse numeric date formats in ClickHouse®](https://www.tinybird.co/blog-posts/parse-numeric-date-formats-clickhouse)
