Skip to content

Instantly share code, notes, and snippets.

@henrik
Last active August 27, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henrik/a1b614d1b6421ca164d8 to your computer and use it in GitHub Desktop.
Save henrik/a1b614d1b6421ca164d8 to your computer and use it in GitHub Desktop.
Thoughts on how to show a server-side CET time as CET in a JS client no matter which time zone the browser has.

Option 1: send strings in the API

API changes:

item:
  ends_at_string: "4 maj kl. 12:31 CET"
  bids:
    - timestamp_string_short: "4 maj kl. 12:31"
    - timestamp_string_long: "4 maj 2015 kl. 12:31 CET"
    • Super simple
    • All server side = DRY, cross-browser safe
    • Less flexible on the client side
    • Uglier API with knowledge of presentation concerns

Option 2: get TZ offset from Rails, calculate in JS

Ruby code example:

rails_offset_secs = Time.now.in_time_zone('Stockholm').utc_offset
rails_zone_name = Time.zone.now.strftime("%Z")

API changes (can't be on page-load since we may cross DST boundaries etc):

item:
  time_zone_name: CET
  time_zone_offset_seconds: 7200

JS:

railsOffsetSecs = 7200  # from API
railsZoneName = "CET"  # from API

// Get user local time -> UTC -> Rails local time.
// JS will then still consider it to be in the user's TZ, but it will be correct otherwise.
rightTime = new Date(date.getTime() + date.getTimezoneOffset() * 1000 * 60 + railsOffsetSecs * 1000)
I18n.l("time.formats.human", rightTime) + " " + railsZoneName
    • More complex
    • Server and client must be kept in rather close sync, or we'll show the wrong thing around DST boundaries
  • +- Kind of ugly API, but not concerned with lower-level presentation

Option 3: moment-timezone

Something along these lines, but instead of these replaces we would modify moment-strftime to be compatible with how Rails handles its format strings:

# Ugly replaces
moment.tz(bid.timestamp, "CET").strftime(I18n.t("time.formats").short.replace("%-", "%").replace("kl.", "\\k\\l. %A"))}

# Imagined future
moment.tz(bid.timestamp, "CET").strftime(I18n.t("time.formats").short)}

But then we would have a separate set of translations :/

Option 4: Return UTC-as-CET timestamps from API

Ruby:

my_cet_time = Time.zone.now
timestamp_js = Time.parse(my_cet_time.iso8601.sub(/(T.{8}).*/, '\1Z')).to_i * 1000

API:

timestamp: 1234
timestamp_js: 5678000

JS:

new Date(timestampJs + date.getTimezoneOffset() * 1000 * 60)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment