What's the best way to handle a long list in settings?

Hello,

What's the best way to handle a long list in settings?

I am making a watch face where the user can select a time zone or Zulu offset.  There are over 30 different time zones around the globe and I'd rather not do a super long list.  Mainly because I'd have to create over 30 items in the list, then re-create this in strings.  Any thoughts?

I've considered doing 5 different number entries (1st for plus or minus, 2nd & 3rd for hours, 4th and 5th for minutes), but I have no say in the formatting of the settings page (other than <group>) to make it look obvious.  

I tried asking for the hours separate from the minutes (constrained with min-max), but i don't think it was clear what I was looking for.

I could ask for the time zone as a string and then reference a database, but then I'd have to create and maintain a database of currently 117 time zones (https://www.worlddata.info/timezones/index.php).

Thoughts?

Top Replies

All Replies

  • So, If I get rid of the easy DTS answer and go to getDaylightSavingsTimeOffset() and math, I can get the correct answers?

    getDaylightSavingsTimeOffset() is a LocalMoment method.

    1) LocalMoment is only available for System 5 devices. If you need to support older devices, you will have to use another solution instead of or in addition to this

    2) If you are using LocalMoment you already have the local time for whatever location was specified. You shouldn't need to do any math

    See the example here: https://developer.garmin.com/connect-iq/api-docs/Toybox/Time/LocalMoment.html

    The only difference is instead of using a hardcoded time as in the example, you use the actual current time provided by the watch.


    // Determine the local time at a given location
    var now = Time.now();
    var where = new Position.Location({
        :latitude  => //...
        :longitude => //...
        :format => :degrees
    });
    
    var local = Gregorian.localMoment(where, now);
    var info = Gregorian.info(local, Time.FORMAT_SHORT);
    //...

    So basically you map your UI's  "logical timezones" (timezone + DST observance combos) to locations and feed them to the code above. e.g. "Mountain Time" will be split into 2 logical timezones:

    "Arizona" -> some location in AZ

    "Mountain Time" -> some other location in MT, but not AZ (e.g. Denver)

    Other examples:

    "Eastern Time" -> NYC

    "Pacific Time" -> LA

    etc.

    If you look at how Windows PCs (and other devices) work when you select a "timezone" manually, they all list "Arizona" and "Saskatchewan" (for example) as separate "timezones", because those 2 locations do not observe DST.

  • I'm going crawl, walk then run this thing.  I'm going to start by doing my location ONLY with an API of 3.3.0 or better.  When I get my stuff working, then I'll start making it backward compatible, then time zones at large.

  • I'm going to start by doing my location ONLY with an API of 3.3.0 or better. 

    If it's your location only (and the current time), that's super simple and it works with all devices:

    var now = Time.now();
    var info = Gregorian.info(now);

    If you have the user enter/select a time zone offset, and you don't do automatic DST adjustments, it's also fairly simple and should work on all devices.

    Assuming that ClockTime.timeZoneOffset is correct when you call System.getClockTime(), something similar to this should work. Disclaimer, I haven't tried it, so there might be a bug or two, but I think the general idea is correct.

    var otherTzOffset = -5 * 60; // e.g. Eastern Standard Time (the "-5" could come from settings)
    var localTzOffset = System.getClockTime().timeZoneOffset;
    var tzDiff = otherTzOffset - localTzOffset; // time difference between there and here, in seconds
    var nowMoment = Time.now();
    var otherMoment = new Duration(tzDiff).add(nowMoment);
    var otherTimeInfo = Gregorian.info(otherMoment, Time.FORMAT_SHORT);

  • Yes.  That's pretty much the current set-up. 

    Thanks

  • No problem.

    Going back to automatic DST adjustments, the key idea is that instead of asking the user to select a literal time zone, you ask them to select a "time zone" (but it's really a list of locations which belong to a given time zone and observe a certain DST rule).

    Which is why "Mountain Time" and "Arizona" are two different "time zones" in Windows, and why some of the entries in the Windows "time zone" list have an example location in their name.

    If you're going to utilize LocalMoment, the biggest issue here is narrowing down the time zone/location list to a manageable number of locations that you care about. The list in Windows is about ~100 items, which might be too user-unfriendly for a CIQ app that maybe only targets mostly North American users. As a counter-example, the Steam Deck (which is a consumer-focused gaming device that runs Linux) offers 60 "time zones".

    Once you've decide what locations you care about, you just need to find a representative coordinate for each location.

    If you can't utilize LocalMoment (e.g. you have to support older devices), then it's the same approach except you map the time zones/locations you care about to a TZ/DST rule (like the list I posted earlier.)

  • No, windows asks for a TZ, and behind the scenes, it knows if DST is used or not and the dates if it is.  It's not a different TZ.

  • No, windows asks for a TZ, and behind the scenes, it knows if DST is used or not and the dates if it is.  It's not a different TZ.

    No, Windows asks for what it calls a "time zone" but is really a "time zone + DST rule". That's why the list consists of literal time zones (Eastern, Mountain, Pacific, etc.), as well as exceptions to the usual DST rules (e.g. Arizona, Saskatchewan, etc.)

    Again you are extremely hung up on the literal meaning of the phrase "time zone", to the detriment of this discussion. How do you think Windows "knows* if DST is used when you select a time zone manually? It knows because you're not just selecting a literal time zone, you're selecting an item that represents a combination of a time zone *AND* an associated DST rule.

    In the screenshot above, you can see that the dropdown label reads "Time zone" (did you even look at the screenshot?). Yet "Arizona" and "Mountain Time" are two different entries in the "Time zone" list. As you have pointed out multiple times, those are not literally 2 different time zones, yet *somehow*, they are still two different entries in the Windows "time zone" list. Same with other OSs/devices which allow you to select a "time zone" manually. What they present as a list of time zones is really a list of time zone + DST rules, each of which is applicable to a certain set of locations.

    What's actually happening here is that you're selecting a "timezone + DST rule", and *that's* how "behind the scenes", Windows knows whether DST is used and the applicable dates.

    Like in the above screenshot (if you would just look at it), if you select "(UTC -07:00) Arizona", that tells Windows you're in UTC -07:00 (MST) all year long, and if you select "(UTC -07:00) Mountain Time (US & Canada)", that tells Windows that you use MDT (UTC-6) in the summer and MST at other times of the year.

    I already tried to explain multiple times how you could implement this in CIQ (which is the same way I literally implemented this in an embedded Linux system). You create your list of "time zone + DST rule" combos (just like the list in Windows, or in various Linux distros), and map them to hardcoded TZ/DST rules. If you can use LocalMoment, then you map the "time zone + DST rule" list entries to coordinates, so you don't have to hardcode the rules.

    I give up trying to convince you tho.

  • I mean if you don't believe me you can try it for yourself.

    In Mountain Time regions outside of Arizona, it's currently MDT (UTC-6). Arizona is currently on MST (UTC-7).

    At this very moment, it's 6:20 PM in Arizona, and it's 7:20 PM in Denver. 

    Go to your time zone settings in Windows, and manually change the Time Zone from Arizona to Mountain Time. You'll see your clock move one hour ahead. This happens because Windows applies the time zone/DST rules associated with the item you selected from the "Time zone" list.

  • I'm sure this won't convince you, but here's an example of me changing the "time zone" on Windows 11 from "Eastern Time" to "Arizona" to "Mountain Time", which is relevant since Mountain Time locations outside of Arizona are currently on DST, and of course Arizona is not.

    Notice how the current clock time changes with each selection, which should be impossible since "Arizona" and "Mountain Time" aren't "different time zones", as you said.

    Like, yeah, I know they aren't *literally* different time zones, they're different entries in the list of what Window (and some other systems) call "time zones". Choosing a given entry causes BOTH the selected time zone AND the associated DST rule to be applied. There's nothing magical happening behind the scenes, the rules that are applied are directly associated with the "time zone" entry that you select from the list.

    If you have a more technically accurate, yet user-friendly, way of describing that list other than "Time zones", you should suggest it to Microsoft.

  • Here's some non-animated screenshots.

    For anyone reading this thread in the future, it's September, which is "summertime" in the Northern Hemisphere for the purposes of DST.

    - Cities in the Eastern Time zone (such as New York) are currently observing Eastern Daylight Time (UTC-4)

    - Arizona is observing Mountain Standard Time (UTC-7), as it does all year round

    - Locations outside of Arizona, but still in the Mountain Time zone (such as Denver) are currently observing Mountain Daylight Time (UTC-6)

    Curious how you think this happened? Do you think I enabled location services on my desktop PC and flew from Arizona to Denver when I switched the "time zone" from "Arizona" to "Mountain Time" (at which point my clock also jumped ahead by one hour), all in the 20 seconds it took for me to record the video?

    Or could it be that what Windows calls a "time zone" also has a DST rule associated with it, which is why they put location names in several of the "time zone" entries. That's also why "Saskatchewan" has its own entry (separate from "Central Time") - because it's on Central Standard Time (UTC-6) all year round and doesn't observe DST, unlike other locations which observe Central Daylight Time in the summer and Central Standard Time the rest of the year.

    For example:

    - If you select "(UTC-7) Mountain Time" as your "time zone" in Windows, Windows will automatically switch to Mountain Daylight Time / MDT (UTC-6) in the summer. The rest of the year, it will use Mountain Standard Time / MST (UTC-7).

    - If you select "(UTC-7) Arizona" as your "time zone" in Windows, Windows will stay on Mountain Standard Time all year around

    Similarly:

    - If you select "(UTC-6) Central Time" as your "time zone" in Windows, Windows will automatically switch to Central Daylight Time / CDT (UTC-5) in the summer. The rest of the year, it will use Central Standard Time / CST (UTC-6).

    - If you select "(UTC-6) Saskatchewan" as your "time zone" in Windows, Windows will stay on Central Standard Time all year around

    Other systems like Steam Deck work the same way when you manually select what they usually call a "time zone" (which is really "time zone + DST rules").

    Some OSs / systems (like Mac OS / various Linux distros), if you choose to 'manually set a timezone", will alternatively ask you to enter the "nearest location" or "closest city" to where you are, but it's basically the same idea. There's a list of timezone + DST rules associated with locations, and the user selects one of them. The main difference is in the presentation and ease of use.

    EDIT:

    Another data point is that if you look at the standard IANA Time Zone database, it's not *literally* a list of time zones, it's a list of locations/regions/names where certain time zone / daylight saving time rules are in effect. Sometimes the name of a "time zone" in the DB is a city or state (e.g. "US/Arizona"), other times it's the name of the "literal" time zone (e.g. "US/Mountain").

    Like Windows, this database has distinct entries for US/Arizona and US/Mountain, because even though "Arizona" and "Mountain Time" aren't "different time zones" (again according to an extremely literal interpretation of the phrase "time zone"), they do have different DST rules (Arizona doesn't observe DST, everyone else who uses "Mountain Time" does observe DST.)

    [https://en.wikipedia.org/wiki/List_of_tz_database_time_zones]