Skip to content

Timezone controls (optional, default turned on)#1327

Open
cwant wants to merge 20 commits into
ElixirTeSS:masterfrom
cwant:cwant/timezone-controls
Open

Timezone controls (optional, default turned on)#1327
cwant wants to merge 20 commits into
ElixirTeSS:masterfrom
cwant:cwant/timezone-controls

Conversation

@cwant

@cwant cwant commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary of changes

This ports over the timezone controls from Explora to Elixir/TeSS.

Motivation and context

It's helpful to see events in your own timezone. This PR gives a toggle between showing times in the timezone of each event, and showing times in the timezone detected by the webbrowser.

The timezone control widget shows up on any page where there is an event listed (e.g. events#index, events#show, upcoming events, etc.).

The timezone controls can be opened and closed for visibility.

An added feature: the event edit page allows you to enter times in the timezone of the event (rather than having to do the mental math of entering it in GMT and hoping you've done that correctly).

Note : this uses the ffi-icu gem. For our TeSS we use this so that the timezone names appear in the language that is selected in our user interface. E.g. heure d’été du Pacifique nord-américain when French is selected instead of Pacific Daylight Time.

Screenshots

Here is the initial hit on event#index, with option "event timezones" selected by default. Two events with different timezones are shown.

timezones1

Here is the same page, with the timezones controls displayed via the Change... link. (Clicking the x hides the controls again.)

timezones2

Here is the page with my timezone (detected by the browser) is clicked:

timezones3

Here is the editing link for start/end times, done in the timezone selected for the event (converted to GMT when saved to the database):

timezones4

Checklist

  • I have read and followed the CONTRIBUTING guide.
  • I confirm that I have the authority necessary to make this contribution on behalf of its copyright owner and agree to license it to the TeSS codebase under the BSD license.

@kennethrioja

Copy link
Copy Markdown
Contributor

Many thanks @cwant for taking the time to do this PR – really appreciated and really helpful!

Before this PR, I tried on my side to cherry-pick some of your commits from your forked TeSS, so far I picked up almost the same one :

I'll test on my side if everything seems ok for me and if I don't need the last I've added on my side.

I can definitely help review this PR @fbacall – if you want to throw a copilot, please do so.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports “timezone controls” UI and server-side support into TeSS so event times can be displayed either in each event’s own timezone (default) or in the browser-detected timezone, and allows editing event start/end in the event’s specified timezone.

Changes:

  • Added timezone toggle UI + AJAX endpoint to re-render event time blocks and controls.
  • Updated event edit/create flow to interpret entered datetimes as being in the selected event timezone.
  • Added ICU-based localized timezone naming (ffi-icu) and new i18n strings.

Reviewed changes

Copilot reviewed 19 out of 20 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
test/controllers/events_controller_test.rb Adds controller test asserting edit/create respect event timezone for entered datetimes.
Gemfile Adds ffi-icu dependency for localized timezone display names.
Gemfile.lock Locks ffi-icu and dependency graph updates.
config/tess.example.yml Introduces feature.timezone_controls default configuration.
config/routes.rb Adds events#event_time_data route for AJAX timezone updates.
config/locales/en.yml Adds new strings for timezone UI and event form labels.
app/views/static/home/_upcoming_events.html.erb Adds timezone controls to the home “upcoming events” section and localizes the header.
app/views/events/show.html.erb Uses timezone-aware partials when the feature is enabled.
app/views/events/index.html.erb Renders timezone controls above results when enabled.
app/views/events/_form.html.erb Changes labels and assumes start/end are entered in selected timezone.
app/views/events/_event.html.erb Uses timezone-aware time rendering in event cards when enabled.
app/views/events/_event_timezone_control.html.erb New timezone control widget (collapse/choice UI).
app/views/events/_event_time_div.html.erb New per-event “time + timezone” rendering block used for AJAX replacement.
app/views/common/_associated_events.html.erb Adds timezone controls to associated-events blocks when enabled.
app/models/event.rb Updates start_local/end_local conversion logic.
app/helpers/events_helper.rb Localizes date formatting and adds ICU-based timezone display helper.
app/controllers/events_controller.rb Shifts times for edit/save and adds event_time_data JSON endpoint.
app/controllers/application_controller.rb Adds session timezone selection from params/session.
app/assets/stylesheets/application.scss Adds styling for timezone controls.
app/assets/javascripts/events.js Adds client-side AJAX to fetch updated HTML and wire up timezone control behaviors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/controllers/application_controller.rb
Comment thread app/controllers/events_controller.rb Outdated
Comment thread app/controllers/events_controller.rb
Comment thread app/models/event.rb
Comment thread app/models/event.rb
Comment thread app/views/static/home/_upcoming_events.html.erb Outdated
Comment thread app/views/events/_event_timezone_control.html.erb
Comment thread app/helpers/events_helper.rb Outdated
Comment thread app/assets/javascripts/events.js
Comment thread app/views/events/_event_time_div.html.erb Outdated
@kennethrioja

Copy link
Copy Markdown
Contributor

UI functionality

What I checked in the UI

  1. OK ☑️ : When timezone_controls is set to false, it must not show controls in events/event/upcoming_events/test
  2. When timezone_controls is commented or not present, it must not show controls in events/event/upcoming_events/test
    a. ACTION ⚠️ : For now, as the default is set to true on tess.example.yml, when I comment the timezone_controls line, I still see the timezone controls, this is a strange behavior: one might be surprised when pulling from origin/main to see these controls enables without having updated their own tess.yml – Change timezone_controls to false in tess.example.yml to avoid this? But I also understand having it enabled by default, this is a discussion to have with @fbacall
  3. When timezone_controls is set to true, it must show controls in events/event/upcoming_events/test
    a. OK ☑️ : In Events, everything was correct, either in my timezone, either in the timezone in which the event occurs
    b. ACTION ⚠️ : In test it is not showing the box
    i. When you do the test with a content provider, after clicking on ‘Preview’ you see this
    image
  4. When UTC/London, CEST, Pacific, converts well + it is in the db in GMT/UTC
    a. OK ☑️ : I tested with BST, CEST and PDT, it works as expected and saved as GMT/UTC in the db

Testing ingestion

  1. OK ☑️ : When ingesting https://heptraining.cern.ch/events/unit-tests-a-philosophy-and-help-on-our-applications, it displays the right time converted to CEST (detected): 10-11:30, the value in db is 9-10:30

Other Issues

  1. ACTION ⚠️ : When you have a content provider, with no current event, and at least one past event, you see this
image

Questions

  1. ACTION ⚠️ : In app/views/events/show.html.erb, l.62, what is the event_time_div? and why isn’t here in the other places?

Code review

  1. ACTION ⚠️ : Why did you change app/models/event.rb, l.189? I can only see <date>.asctime which is different (asked by copilot)
  2. Nothing to say on the code other than that – maybe if I wanted to be picky, code coverage decreased by .04%

@cwant

cwant commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@kennethrioja Some comments here:

  • I turned off the "on by default" behaviour for the timezone controls in tess.example.yml.
  • I can't really see the images you are posting in your comments. Github shows a small preview that I can't really read very well. I've made some assumptions about the comments from the context that I hope are correct in what follows.
  • The test ingestion view is problematic. This is because it shows partially digested data before things get turned into real event objects. Not sure what to do about that... (the timezone controls need a real event id before they work).
  • I've removed timezone controls from content provider when there are no upcoming events to get rid of that weird grey rectangle.
  • event_time_div in app/events/show.html.erb is this: app/views/events/_event_time_div.html.erb. It renders the event time as separate time and timezone fields. It does show up in a few places (including as ajax output):
$ grep -r event_time_div app 
app/controllers/events_controller.rb:        html = render_to_string partial: 'events/event_time_div',
app/views/events/_event.html.erb:          <%= render partial: 'events/event_time_div', locals: {event: event} %>
app/views/events/show.html.erb:          <%= render partial: 'event_time_div', locals: {event: @event} %>
  • app/models/event.rb, l.189 changed because it was giving the wrong values. It's the conversion to asctime that gives times that don't match with what I expect. I've reworked the code a bit to make it more fault tolerant (as per the advice from Copilot), but kept the asctime out of it.
    I hope this illustrates the issue with the previous implementation:
# UTC as is in the database
datetime = DateTime.parse("2026-01-01 12:00")
=> Thu, 01 Jan 2026 12:00:00 +0000

timezone = "Pacific Time (US & Canada)"

# This is what the old version of `set_to_local` did:
datetime.asctime.in_time_zone(timezone)
=> Thu, 01 Jan 2026 12:00:00.000000000 PST -08:00
# Huh? This shouldn't be 12pm in both Vancouver and GMT

# Here is what the new version of `set_to_local` does:
datetime.in_time_zone(timezone)
=> Thu, 01 Jan 2026 04:00:00.000000000 PST -08:00
# Correct, it is 4am in Vancouver when it's 12pm in GMT
  • Sorry about the test suite. A lot of things are in the front end which is harder to test. I'll see if I can add something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants