Time zone conversion cheat sheet at the shell with Ruby

Why would you need a command line time zone conversion?

Imagine that you’re troubleshooting a problem. Add that your team is distributed across multiple timezones. Now add that database times are generally recorded in UTC, but your alerting all displays in local time.

If you’re trying to pinpoint when an event happened and comparing notes across systems and observations, you’re going to be doing some time zone conversion to validate that all the observations are related to the same time period. That can be a bit tedious, especially if you’re already juggling a lot of details about the problem. For me, I wrote a quick script to be a time converter calculator to as a guide to help me align time stamps from different sources.

Parsing the time

Once require 'time' is added to the script, Time.parse(time_string) will work. But I also wanted to support if you had a date or time offset, such as 2022-04-20 11:09 -0500 without having to put the argument in quotes, so I joined the arguments:

# support calling as "convert_time 2022-04-20 11:09 -0500"
arg_time=ARGV.join(' ')

The resultant parsed time will be interpreted as a local time unless a time zone offset was specified.

Making things pretty

I’m using the colorize gem for coloring the output. Note: Windows Terminal or similar is required for full color output.

Converting timezones

(tzinfo-data gem is required for Windows or else you’ll end up with a TZInfo::DataSourceNotFound)

I’m using the tzinfo gem to convert times to specified times by grabbing a TZInfo::Timezone and calling to_local

string="#{k}: => #{tz.to_local(the_time)}"


I look through a hash of all of my “locations” (keys) and respective time zone representations (values) in time_zone_hash and present times for each as a time zone chart:

time zone conversion for a parsed time and then time zones for each location I want to display
convert_times output on Windows Terminal

The Time Zone Conversion Code

#!/usr/bin/env ruby
require 'time'
require 'tzinfo'
require 'colorize'
def usage
puts %q(
convert_times {time string to parse, spaces ok}
convert_times 13:30 # parses as local time "today"
convert_times 2022-04-21 13:30 # parse as local time
convert_times 2022-04-21 13:30 -0500 # parse as -0500 offset
if ARGV.length == 0
arg_time=ARGV.join(' ')
puts ("=" * 80).colorize(:light_white)
puts "Input time: #{the_time}".colorize(:light_white)
puts ("=" * 80).colorize(:light_white)
# keys are the description of the time for display
# values are time zone identifiers
# (use TZInfo::Timezone.all_identifiers to find a valid time zone identifier)
time_zone_hash = {
"UTC" => 'Etc/GMT',
"Brazil" => 'America/Sao_Paulo',
"Your time" => LOCAL_TIME,
"Datadog" => LOCAL_TIME,
"Slack alerts" => LOCAL_TIME,
"Database" => 'Etc/GMT',
"Kansas City" => 'America/Chicago',
"Denver" => 'America/Denver',
"New York" => 'America/New_York',
"Seattle" => 'America/Los_Angeles'
puts "database timestamps are in UTC".colorize(:light_red)
time_zone_hash.each do |k,v|
string="#{k}: => #{tz.to_local(the_time)}"
case k
when "UTC"
puts string.colorize(color: :black, background: :light_green)
when "Your time"
puts string.colorize(:light_green)
puts string
view raw convert_times hosted with ❤ by GitHub

Next Steps

I just had this in a script to call when comparing timestamps, but it could be bundled and the hash itself could be in a configuration or yaml file to clean up the time zone conversion.

Leave a Reply

%d bloggers like this: