Using Filters
Dates & Time Filters
Format dates, calculate time differences, and work with localized date formats
Nimbu provides powerful date and time filters with full localization support and timezone awareness.
Date Formatting
date
Format dates using strftime patterns:
{{ "now" | date: "%Y-%m-%d" }}
<!-- Output: 2025-10-07 -->
{{ article.published_at | date: "%B %d, %Y" }}
<!-- Output: October 07, 2025 -->
{{ order.created_at | date: "%d/%m/%Y %H:%M" }}
<!-- Output: 07/10/2025 14:30 -->Common Format Patterns:
%Y- Year (2025)%m- Month (01-12)%d- Day (01-31)%B- Month name (October)%b- Short month (Oct)%A- Day name (Monday)%a- Short day (Mon)%H- Hour 24h (00-23)%I- Hour 12h (01-12)%M- Minutes (00-59)%S- Seconds (00-59)%p- AM/PM
localized_date
Format dates with full localization:
{{ article.published_at | localized_date: "long" }}
<!-- Output: October 7, 2025 (English) -->
<!-- Output: 7 oktober 2025 (Dutch) -->
{{ event.start_date | localized_date: "short" }}
<!-- Output: 10/07/2025 (US) -->
<!-- Output: 07/10/2025 (EU) -->
{{ order.created_at | localized_date: "full" }}
<!-- Output: Monday, October 7, 2025 at 2:30 PM -->Format Options:
default- Standard date and timelong- Long date formatshort- Short date formattime- Time onlyfull- Complete date and timedate_only- Date without time- Custom strftime patterns
With Locale:
{{ date | localized_date: "long", "nl" }}
<!-- Force Dutch locale -->
{{ date | localized_date: "short", "fr" }}
<!-- Force French locale -->Relative Time
time_ago_in_words
Display human-readable time difference:
{{ article.published_at | time_ago_in_words }}
<!-- Output: 2 days ago -->
<!-- Output: about 1 month ago -->
<!-- Output: over 3 years ago -->
<p class="timestamp">
Posted {{ comment.created_at | time_ago_in_words }}
</p>Localized Output:
{{ article.created_at | time_ago_in_words }}
<!-- English: "2 days ago" -->
<!-- Dutch: "2 dagen geleden" -->
<!-- French: "il y a 2 jours" -->Date Calculations
Date Arithmetic
Add or subtract time from dates:
<!-- Add days -->
{{ "now" | days_from_now: 7 }}
<!-- 7 days from today -->
{{ event.date | days_from_now: 14 }}
<!-- Subtract days -->
{{ "now" | days_ago: 30 }}
<!-- 30 days ago -->
{{ order.date | days_ago: 7 }}next_day / prev_day
Move forward or backward by one day:
{{ date | next_day }}
<!-- Tomorrow -->
{{ date | prev_day }}
<!-- Yesterday -->next_month / prev_month
Navigate months:
{{ "2025-10-15" | next_month }}
<!-- Output: 2025-11-01 -->
{{ "2025-10-15" | prev_month }}
<!-- Output: 2025-09-01 -->Calendar Helpers
days_in_month
Get number of days in a month:
{{ date | days_in_month }}
<!-- Output: 31 (for October) -->
{% assign days = "2025-02-01" | days_in_month %}
<!-- 28 days (2025 is not a leap year) -->days_in_next_month / days_in_prev_month
{{ date | days_in_next_month }}
{{ date | days_in_prev_month }}Date Parsing
to_datetime
Parse string to datetime:
{{ "2025-10-07" | to_datetime }}
{{ "October 7, 2025" | to_datetime }}
{% assign event_date = params.date | to_datetime %}Practical Examples
Blog Post Metadata
<article>
<header>
<h1>{{ article.title }}</h1>
<div class="meta">
<time datetime="{{ article.published_at | date: '%Y-%m-%d' }}">
{{ article.published_at | localized_date: "long" }}
</time>
<span class="separator">•</span>
<span class="time-ago">
{{ article.published_at | time_ago_in_words }}
</span>
</div>
</header>
{{ article.content }}
</article>Event Calendar
<div class="event-calendar">
{% assign today = "now" | date: "%Y-%m-%d" %}
{% for event in events %}
{% assign event_date = event.start_date | date: "%Y-%m-%d" %}
<div class="event {% if event_date == today %}event-today{% endif %}">
<div class="date">
<div class="month">{{ event.start_date | date: "%b" }}</div>
<div class="day">{{ event.start_date | date: "%d" }}</div>
</div>
<div class="details">
<h3>{{ event.title }}</h3>
<p class="datetime">
{{ event.start_date | localized_date: "full" }}
</p>
{% if event.end_date %}
<p class="duration">
Until {{ event.end_date | localized_date: "long" }}
</p>
{% endif %}
</div>
</div>
{% endfor %}
</div>Countdown Timer
{% assign event_date = event.start_date | to_datetime %}
{% assign now = "now" | to_datetime %}
{% if event_date > now %}
<div class="countdown">
<p>Event starts {{ event.start_date | time_ago_in_words }}</p>
<p class="date">{{ event.start_date | localized_date: "full" }}</p>
</div>
{% else %}
<div class="event-passed">
<p>Event was {{ event.start_date | time_ago_in_words }}</p>
</div>
{% endif %}Order History
<div class="order-history">
{% for order in orders %}
<div class="order">
<div class="order-header">
<span class="order-number">#{{ order.number }}</span>
<time datetime="{{ order.created_at | date: '%Y-%m-%d' }}">
{{ order.created_at | localized_date: "short" }}
</time>
</div>
<div class="order-status">
{% if order.shipped_at %}
<span class="status shipped">
Shipped {{ order.shipped_at | time_ago_in_words }}
</span>
{% elsif order.paid_at %}
<span class="status paid">
Paid {{ order.paid_at | time_ago_in_words }}
</span>
{% else %}
<span class="status pending">Pending</span>
{% endif %}
</div>
</div>
{% endfor %}
</div>Date Range Filter
<div class="filter-bar">
<form method="get">
<label>From:</label>
<input type="date"
name="from"
value="{{ params.from | default: 'now' | days_ago: 30 | date: '%Y-%m-%d' }}">
<label>To:</label>
<input type="date"
name="to"
value="{{ params.to | default: 'now' | date: '%Y-%m-%d' }}">
<button type="submit">Filter</button>
</form>
</div>
{% if params.from or params.to %}
{% scope created_at >= params.from and created_at <= params.to %}
{% for order in orders.all %}
<!-- Filtered orders -->
{% endfor %}
{% endscope %}
{% endif %}Upcoming Events Section
<section class="upcoming-events">
<h2>Upcoming Events</h2>
{% assign today = "now" | to_datetime %}
{% assign next_month = "now" | next_month %}
{% scope start_date >= today and start_date <= next_month %}
{% sort start_date asc %}
{% for event in channels.events.all %}
<div class="event-card">
<h3>{{ event.title }}</h3>
<p class="date">
{{ event.start_date | localized_date: "long" }}
</p>
<p class="countdown">
{% assign days_until = event.start_date | date: "%s" | minus: today | divided_by: 86400 %}
{% if days_until == 0 %}
Today!
{% elsif days_until == 1 %}
Tomorrow
{% else %}
In {{ days_until }} days
{% endif %}
</p>
</div>
{% endfor %}
{% endsort %}
{% endscope %}
</section>Archive Grouping by Date
<div class="blog-archive">
{% assign posts_by_year = blog.articles | group_by_exp: "article", "article.published_at | date: '%Y'" %}
{% for year_group in posts_by_year %}
<div class="year-group">
<h2>{{ year_group.name }}</h2>
{% assign posts_by_month = year_group.items | group_by_exp: "article", "article.published_at | date: '%B'" %}
{% for month_group in posts_by_month %}
<div class="month-group">
<h3>{{ month_group.name }}</h3>
<ul class="article-list">
{% for article in month_group.items %}
<li>
<a href="{{ article.url }}">{{ article.title }}</a>
<time>{{ article.published_at | date: "%d" }}</time>
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
</div>
{% endfor %}
</div>Best Practices
1. Use Semantic HTML
<!-- ✅ Good: Proper datetime attribute -->
<time datetime="{{ article.published_at | date: '%Y-%m-%d' }}">
{{ article.published_at | localized_date: "long" }}
</time>
<!-- ❌ Bad: Missing datetime -->
<span>{{ article.published_at | localized_date: "long" }}</span>2. Localize for Users
<!-- ✅ Good: Respects user locale -->
{{ date | localized_date: "long" }}
<!-- ⚠️ Be careful: Not localized -->
{{ date | date: "%B %d, %Y" }}3. Provide Multiple Formats
<time datetime="{{ event.date | date: '%Y-%m-%d' }}">
<span class="long-format">{{ event.date | localized_date: "full" }}</span>
<span class="relative">{{ event.date | time_ago_in_words }}</span>
</time>4. Handle Timezones
<!-- Dates are stored in UTC, displayed in site timezone -->
{{ order.created_at | localized_date: "full" }}Next Steps
- Numbers & Money - Format currency and numbers
- Text Formatting - String manipulation
- Multilingual - Translation and locale system
- Global Variables - Date/time variables
Work with dates and time effectively in your Nimbu themes!