DocSpring Blog

Timezone Conversion in Liquid Templates, for Ruby on Rails

Our HTML/CSS templates support Shopify’s Liquid syntax to include dynamic data and logic. Liquid supports a lot of filters and tags out of the box, including a function to format dates. However, some of our customers needed to display a date in a specific timezone, and Liquid doesn’t have any built-in support for timezone conversion.

Fortunately, it’s very easy to create your own Liquid filters, and Rails makes it easy to convert dates and times into different timezones.

I saw that some other companies have created their own Liquid filters for timezone conversion, but I couldn’t find any open source filters or blog posts. I’ve decided to share the Liquid filter that we use to provide timezone conversions in a Ruby on Rails application.

  • Add this file to lib/liquid/filters/in_time_zone.rb:
# frozen_string_literal: true

module Liquid
  module Filters
    module InTimeZone
      TIMEZONES = TZInfo::Timezone.all_country_zones.map(&:name).sort.freeze

      def in_time_zone(input, timezone)
        time = if %w[now today].include?(input)
          Time.zone.now
        elsif input.is_a?(String)
          begin
            Time.zone.parse(input)
          rescue StandardError
            nil
          end
        elsif input.is_a?(Time) || input.is_a?(Date)
          input
        end
        return input if time.nil?
        return time unless TIMEZONES.include?(timezone)

        time.in_time_zone(timezone)
      end
    end
  end
end

Liquid::Template.register_filter(Liquid::Filters::InTimeZone)
  • Add an initializer at config/initializers/liquid.rb to require the Liquid filter when your appication boots:
# frozen_string_literal: true

# Require all of our custom Liquid filters and tags
Dir.glob(Rails.root.join('lib', 'liquid', '**', '*.rb')).each do |f|
  require f
end

Now you will be able to use the in_time_zone filter in your Liquid templates.

  • Show a user’s created_at timestamp in the New York timezone:
  {{ user.created_at | in_time_zone: "America/New_York" | date: "%Y-%m-%d %H:%M" }}
  • Show the current time in New York:
  {{ 'now' | in_time_zone: "America/New_York" | date: "%Y-%m-%d %H:%M" }}


We’ve also added a timezone table to our documentation, so you can see all of the available timezones and UTC offsets. I wrote a short Ruby script to generate the table rows:

puts(TZInfo::Timezone.all_country_zones.map { |tz|
  offset = tz.current_period.utc_offset / 3600
  [tz.name, offset]
}.sort_by { |tz| tz[1] }.map { |(tz, offset)|
  "| #{tz} | `UTC#{offset >= 0 ? '+' : ''}#{offset}` |"
}.join("\n"))



If you need to support timezone conversion for Liquid templates in your Rails app, then I hope this post was helpful!