Daylight Saving Time Mismatch between Simulator and Device

We live in UTC+1:00 Timezone.

In Summer (lfrom Mar 27 to Okt 30) comes additional hour to this ("Summertime").

The Simulator taks care of summer or wintertime and get local time correct. On Device the getting of a time from the other timearea become 1 hour defference, which is wrong:

  • If now is summer and I want to get correct Gregorian representation of a epoch from winter, it diffs 1 hour from correct time
  • If now is winter and I want to get correct Gregorian representation of a epoch from summer, it diffs 1 hour from correct time

Consider the following Code based on Unix Epochs:

    function test_time(dc as G.Dc) {
        var location = new Position.Location({
                                            :latitude  =>  51.338248,
                                            :longitude => 12.362537,
                                            :format    => :degrees,
                                        });
        var text = "";
        // var m = Time.Gregorian.moment({ :year => 2015, :month => 10, :day => 15, :hour => 14, :minute => 0, :second => 0 });
        // var i = Time.Gregorian.info(m, Time.FORMAT_MEDIUM);
        // var s = Lang.format("$1$ $2$ $3$ $4$:$5$:$6$", [i.month, i.day, i.year, i.hour.format("%02d"), i.min.format("%02d"), i.sec.format("%02d")]);
        // Sys.println(s);

        // m = Time.Gregorian.moment({ :year => 2015, :month => 11, :day => 15, :hour => 14, :minute => 0, :second => 0 });
        // i = Time.Gregorian.info(m, Time.FORMAT_MEDIUM);
        // Sys.println(Lang.format("$1$ $2$ $3$ $4$:$5$:$6$", [i.month, i.day, i.year, i.hour.format("%02d"), i.min.format("%02d"), i.sec.format("%02d")])); 
    
        // Sys.println("");

        Sys.println("\n *************** test_time *****************");
        Sys.println("summer=1667023200");
        Sys.println("  should GMT: Sat Oct 29 2022 06:00:00 GMT+0000");
        Sys.println("  should loc: Sat Oct 29 2022 08:00:00 GMT+0200 (Mitteleuropäische Sommerzeit)");
        var m = new Time.Moment(1667023200);
        var i = Time.Gregorian.utcInfo(m, Time.FORMAT_SHORT);
        var s = Lang.format("utc: $1$ $2$ $3$ $4$:$5$:$6$", [i.month, i.day, i.year, i.hour.format("%02d"), i.min.format("%02d"), i.sec.format("%02d")]);
        text += s;
        Sys.println(s); 
        i = Time.Gregorian.info(m, Time.FORMAT_SHORT);
        s = Lang.format("inf: $1$ $2$ $3$ $4$:$5$:$6$", [i.month, i.day, i.year, i.hour.format("%02d"), i.min.format("%02d"), i.sec.format("%02d")]);
        text += "\n" + s;
        Sys.println(s);

        text += "\n";

    
        Sys.println("");
        Sys.println("winter=1667113200");
        Sys.println("  should GMT: Sun Oct 30 2022 07:00:00 GMT+0000");
        Sys.println("  should loc: Sun Oct 30 2022 08:00:00 GMT+0100 (Mitteleuropäische Normalzeit)");
        m = new Time.Moment(1667113200);
        i = Time.Gregorian.utcInfo(m, Time.FORMAT_SHORT);
        s = Lang.format("utc: $1$ $2$ $3$ $4$:$5$:$6$", [i.month, i.day, i.year, i.hour.format("%02d"), i.min.format("%02d"), i.sec.format("%02d")]);
        text += "\n" + s;
        Sys.println(s); 
        i = Time.Gregorian.info(m, Time.FORMAT_SHORT);
        s = Lang.format("inf: $1$ $2$ $3$ $4$:$5$:$6$", [i.month, i.day, i.year, i.hour.format("%02d"), i.min.format("%02d"), i.sec.format("%02d")]);
        text += "\n" + s;
        Sys.println(s);  

        
        
        var myTextArea = new WatchUi.TextArea({
            :text=>text,
            :color=>Graphics.COLOR_BLACK,
            :font=>[Graphics.FONT_MEDIUM, Graphics.FONT_XTINY, Graphics.FONT_XTINY],
            :locX =>WatchUi.LAYOUT_HALIGN_CENTER,
            :locY=>WatchUi.LAYOUT_VALIGN_CENTER,
            :width=>220,
            :height=>200
        });
        myTextArea.draw(dc);
    }

on Log it prints:

Info: Okt 29 ist the last day of summertime (UTC+2:00), Okt 30 ist the first day with wintertime (UTC+1:00)

*************** test_time *****************
summer=1667023200
  should GMT: Sat Oct 29 2022 06:00:00 GMT+0000
  should loc: Sat Oct 29 2022 08:00:00 GMT+0200 (Mitteleuropäische Sommerzeit)
utc: 10 29 2022 06:00:00
inf: 10 29 2022 08:00:00

winter=1667113200
  should GMT: Sun Oct 30 2022 07:00:00 GMT+0000
  should loc: Sun Oct 30 2022 08:00:00 GMT+0100 (Mitteleuropäische Normalzeit)
utc: 10 30 2022 07:00:00
inf: 10 30 2022 08:00:00

Here the Screenshot of Simulator and real Device:

It is so that the simulator takes into account the correct time zone offset of the given time:

  • in summer 2 hours are added (UTC+2:00)
  • in winter 1 hour is added (UTC+1:00)


But the same call on the clock ALWAYS takes into account the CURRENT timezone offset at runtime of the program.

I can correct this manually in the codee, but this leads to a wrong display in the simulator and works only for Central European Time. The problem cannot be solved satisfactorily for mic. Since my watchface represents the course of the sun and additionally the shortest and longest day, it is always displayed incorrectly, since times must always be calculated from the other time (summer and winter).

This then looks like this:

The simulator calculates (we are NOW in summer time UTC+2:00) the sunrises and sunsets for winter (blue line with UTC+1:00) correctly.

The real device calculates the times in coming winter with the TODAY SHIFT (UTC+2:00) and therefore wrong.

How can I solve the Probelem? To me it looks like a bug in the API.

  • Problem is that on sim api calls windows/linux api and it returns good values

    Agreed. We can all agree that the sim works properly, and we all agree that Windows and Linux know how to display time properly, even for other dates and time zones.

    On device probably there is no library to handle it. But from time to time in express I can see info about updating of DST zones so it means there is an bug in CIQ.

    Ok so you just contradicted yourself. If there's no library to handle TZ/DST then:

    - How is the current local time displayed properly?

    - Why would Garmin load TZ/DST information on to the watch if it's not used?

    Again, given that Garmin can display the current local time on your watch and it syncs (universal) time with GPS, all without being connected to the internet, we know for sure that:

    - the watch has timezone/DST information stored locally

    - the watch uses this information to display the current time properly

    Even without that reasoning, like you said, Garmin Express itself says that timezone information has been updated.

    Even if there was no library/tzmap, I don't really care, it's still a bug. But there must be a library/tzmap since it works properly for the current date/time. The problem is when you ask for a different UTC date/time to be translated to local time.

    All I'm asking is that if you believe it's a bug, please upvote the bug report so perhaps Garmin will take it a bit more seriously. But you don't have to, I've already given up hope on so many bugs and design issues ever being fixed.

  • Also, if there was really no internal library to handle any of stuff, then the CIQ API shouldn't have all kinds of time functions which deal with both local and UTC time.

    But obviously those functions exist, and obviously Garmin devices are able to show local time, despite not necessarily being connected to the internet, despite syncing universal time with GPS, and despite the user's ability to travel to any time zone they want.

    If this stuff didn't exist, then users would complain immediately if they flew to another time zone and the watch didn't automatically adjust the time after syncing with GPS.

  • Time on watch can be correct because can be obtained from:

    - phone (when you travel to different zone and you connect watch to phone time changes on watch)

    - maybe from gps.

    And we can see good values it in getClockTime.

    But problem is with Time module.

    I can't contradict myself because I really know how it works :)
    Question is: should time module handle dst/utc. If answer is
    - yes there is the bug
    - no - no bug and it means "handle utc/dst yourself"

    Let's look into example from doc, https://developer.garmin.com/connect-iq/api-docs/Toybox/Time.html

    They want 2003-05-16 00:00 and manually moves hours!!! So it means time module doesn't handle utc.

    I've been wondering about that lately, what  does mean epoch (UTC) time (because e.g. open weather returns a lot of epochs)

    And it means UTC (UTC+0), GMT

    So if you use value() to compare  there is no problem but if for displaying there is a problem.

    If you have epoch time its number of seconds form time for UTC=0 to current time in UTC+0 zone so you have convert it to your dst/utc!

    But yes, if you create moment for today from epoch (or maybe for any day I haven't tested it) CIQ probably use CURRENT utc offset and I can see good time only for those days with the same utc/dst. But probably there will be wrong time when
    - connect phone to watch at 22:00 the day before time is changed due to winter time
    - watch has good time/utc
    - disconnect
    - show any time for today - good - A
    - show any time for today - bad - B
    - time is changed on phone - I don't know if watch show good time, It should...
    - connect to phone at 08:00 next day A will be bad and B good

    BTW, connect settings

    There is no settings on phone/connect to change DST/UTC - it means system gets this data from phone, profile - nobody knows.

  • It's close to midnight where I live and I don't want to get into another ridiculously long argument over DST/UTC. I'll just speak my piece one last time, and you can agree or disagree.

    Just my (educated) opinion, but:

    - You did contradict yourself. You said Garmin Express's update mentioned DST rules, but you also said that the watch doesn't know how to apply the DST offset (without connecting to the phone/internet)

    - I don't think you understand how it works

    - I don't think you understand the example. Gregorian.moment actually takes a UTC time as input. The example uses 6:00 AM, because they want to demonstrate converting it to midnight local time (in CST, which is UTC-6). To be fair I think that example is badly explained. It's also funny that the old docs incorrectly said Gregorian.moment() takes a local time as input -- shows that Garmin doesn't understand their own API. But at least they fixed the docs now.

    https://developer.garmin.com/connect-iq/api-docs/Toybox/Time/Gregorian.html#moment-instance_function

      Each option value is assumed to be in the UTC time zone.

    - I don't think you addressed my point that the watch doesn't have to stay constantly connected to the phone or internet to show the correct current time, when you travel across timezones or when DST starts or stops.

    If you ever travel across timezones with your Garmin watch or if you know someone who travels, turn off bluetooth/wifi and see that the time will still be adjusted properly once you get a GPS fix. Or if you live somewhere that observes DST, turn off bluetooth/wifi near the date/time of transition and see that the time will still be adjusted properly

    (As usual, you absolutely don't have to believe me. ^^^ Here's a test that you can do yourself or ask someone else to do, although the travelling part isn't easy. I guess if you live in Japan it's also a problem since it doesn't observe DST. But you can ask a user who lives in a DST-observing timezone to do the test that I mentioned.)

    - There's nothing preventing the tzmap from also having information about DST. Like we discussed in the other thread for 10 pages, that's how TZ databases work on other operating systems, not to mention the standard TZ database. And if you're short on space, you can omit historical data like I did for an embedded system running a cut-down version of linux.

    - Ask yourself why Garmin would be so stupid as to constantly query the internet to find out what the DST offset is, when they can just store the rules to determine that information on the device, just like everyone else? Again, if they're low on space they can omit historical data, since the most important thing is to display the current time properly. That doesn't mean they can't apply the correct *rule* to a date in the past or the future. (Of course, if they don't have historical data or the rule changes in the future, they'll still be wrong sometimes, but that's better than being wrong almost all the time.)

    There is no settings on phone/connect to change DST/UTC

    Yeah, you don't need that, same as you don't need it Linux or Windows (although there's an option to opt-out of DST, which is something else.)

    It's very simple:

    - The watch either keeps time internally in UTC or in local time (probably UTC imo). Either way, it needs to always know the correct TZ offset + DST offset. That allows it to sync time with GPS, which also uses universal time (not quite UTC tho), and display the local time correctly. Explanation:

    - Say the watch keeps internal clock time in UTC. Now you acquire time from GPS and the internal clock is updated. But without knowing the TZ offset and DST offset, it's impossible to display the local time properly. Again, the watch is not constantly connected to the internet, so Garmin has to store that data locally

    - Say the watch keeps internal clock time in local time. Now you acquire time from GPS -- but without knowing the TZ offset and DST offset (offline), it's impossible to update the clock.

    - Assuming the watch keeps time internally in UTC: In order to display local time properly, the watch needs to know where you are. This can be accomplished by getting a GPS fix

    - Once the watch knows where you are, it can look in the TZMAP to determine both the timezone offset and the DST offset. I already explained what the current rules for EST/EDT are above, for example). Like you said, Garmin Express's changelog mentioned DST rules. And why would Garmin store timezone information on the device without also storing DST rules? That would be stupid, because you need both timezone offsets *and* DST rules to display local time. That goes back to the huge thread about time zones where I argued over and over again that the standard timezone database is actually "timezone + DST rules". You can't deny it, it's right in the database. And anyone who uses Linux, Windows or any other device which lets you choose a "timezone" manually can see that the DST rules are also there

    - If you travel somewhere else and get a GPS fix, the watch can automatically adjust to display the correct local time (taking both TZ offset and DST into account)

    All of that should work without connecting to the internet, since the obvious design philosophy of Garmin watches is that they don't need a constant internet connection. If I'm wrong about that, please show me an example where the time was wrong until someone connected to their phone. If you look at old complaints in the forums about time problems, ppl said the time was wrong until they got a GPS fix.

    Even if it works the way you say it works, it's still a bug. Like who cares how hard it is for Garmin to fix? (I think it's pretty easy, but of course I could be wrong.) It's still a bug and it deserves to be reported, and it should be fixed.

  • There is no settings on phone/connect to change DST/UTC - it means system gets this data from phone, profile - nobody knows.

    Like I said, you (or another user) can do one of the following tests.

    1) Disable bluetooth/wifi on watch (so there's no communication with watch or internet)

    2a) Travel to another timezone (and get a GPS fix). Preferably a timezone that observes DST

    2b) Or wait for DST to start/stop

    3) If I'm right, the watch will display the correct local time. If you're right, it won't.

    I think I'm right. I live in an area that observes DST, and I've never seen the time become incorrect when DST starts or stops. I don't constantly sync with bluetooth or wi-fi either.

    Even if I'm not, it's still a bug.

  • Going back to the example:

    Gregorian.moment() takes broken-down time in UTC, and gives you a Time.Moment() (which is number of seconds since the Unix epoch, which is also UTC)

    Gregorian.info() displays a Time.Moment() in local time. In order to do so, the watch has to somehow know what the current TZ offset and DST offset are, based on your location and the DST rules for your location and time of year.

    The API definitely handles both UTC and local time. Most API calls deal with Time.Moment() which is inherently based on UTC.

    https://developer.garmin.com/connect-iq/api-docs/Toybox/Time/Moment.html

    Internally, Moment objects are stored as 32-bit integers representing the number of seconds since the UNIX epoch (January 1, 1970 at 00:00:00 UTC).

  • I've traveled recently to different zone and I'm almost sure this steps

    - going out of plane

    - off plane mode in phone

    - phone obtains new time from mobile opearator (somebody has to know valid time/utc/dst)

    - connect watch to phone and new time on watch (and there is a bug because at midnight watch returns to previous summer :-))

    So to change time you have to have a good source of new data.

    or course you can start manually time synchronisation using gps (I don't think starting activity or fixing gps automatically changes the time but haven't tested).

    I've mentioned that you need information about zone for which you want to show time. No matter it can be a list, text box, mobile operator...

  • There arw 2 functions

    - info() - Get Info for a Moment in local time.

    - utcInfo() - Get Info for a Moment in UTC time.I

    probably info use utc from current time, ll make some tests soon...

  • Like I said, I could be wrong, but that doesn't change the fact that it would be a bug either way. The fact that the sim and watch work differently (and that the sim returns the correct data) already proves that.

    You still didn't explain how a Garmin watch can automatically adjust the current local time for today when DST changes without an internet connection but it can't do so for a date 6 months in the past or future.

    You realize that when DST starts or stops, the watch doesn't need an internet connection to adjust the time? If you live in a place like Japan which doesn't have DST, you wouldn't have seen that for yourself.

    Consider this:

    - Today is September 24, 2022, I'm in the Eastern Time zone, and DST is in effect

    - My Garmin currently displays the correct time

    - DST ends on November 6, 2022 2:00 AM

    - I can put my watch in airplane mode, wait until November 6, and the watch will automatically adjust for the end of DST by falling back one hour. This is the part you obviously don't believe, but you can ask any Garmin user who lives in a DST-observing area. The start and end of DST is a more seamless transition than travelling between time zones, since the watch doesn't need new information (your new location) to adjust the time. Most users would expect that to happen instantly and automatically without user intervention.

    If you use logic and critical thinking, you will realize that the watch must know that DST in my time zone ends on November 6 based on something stored locally, like the TZ map / database. This must be the case because I didn't need an internet connection / phone sync for the watch to adjust for the end of DST.

    The next logical step is if I ask the watch right now to convert a UTC time on November 7, 2022 (the future) to local time, it can use the same information as above to give me the correct answer. Except it doesn't.

    Same as how DST started on March 13, 2022 2:00 AM and my watch automatically adjusted for that. If it didn't, I would've noticed that my watch was displaying the wrong time until I synced with the phone or GPS. (I only do this when necessary -- I keep bluetooth disabled by default, to save battery life. I usually only sync with wi-fi or bluetooth after I do an activity.)

    By the same logic, if I ask the watch to convert a UTC time/date in the past (March 12, 2022) to local time, it can use the same information as above to give me the right answer.

    The fact that it gives the wrong answer in both cases is a bug, whether you accept my argument about how it probably works or not.

    phone obtains new time from mobile opearator (somebody has to know valid time/utc/dst)

    Even if you look at a phone without considering Garmin, you will see that:

    1) you can select the timezone/location manually

    2) if you change the timezone/location manually, the time changes, even without an internet/mobile connection. This means that there is timezone information stored locally on the phone

    3) if DST starts/ends in your timezone, your phone adjusts the time even without an internet/mobile connection

    I literally did this test on my iPhone:

    - Turned on airplane mode and turned off wi-fi

    - Selected Time / Date > Set Timezone Manually

    - Changed the timezone (which is presented as a location) to a different city in a different time zone

    - The time automatically changed, despite having no network connection

    Displaying the correct time is something basic that even phones can do without having a constant connection to the internet.

    But like I said, you don't have to believe me.

    1) Turn off bluetooth and wifi on watch

    2) Travel to different timezone

    3) Get GPS fix

    - Settings > System >Time > Sync with GPS (why do you think this option is here if the watch can't display the current time by syncing with GPS and not connecting to the internet?)

    or

    - Open activity like Run and wait for sync

    4) See if watch displays the correct time

    Then you can see for yourself how it works. Obviously nothing I can ever say will ever convince you, so next time you travel, just do the test.

    I told you that I don't sync with my phone constantly. I only do so when after an activity. If it was the case that a phone sync is necessary to get the correct time after a TZ/DST change, I would definitely notice that the time is wrong until I sync with the phone, and so would everyone else. In my case I notice that the time is wrong until I get a GPS sync.

    Again, I already explained how it can work without having internet/phone connection at the time that the TZ/DST changes.

    1) The watch's internal clock is in UTC, like most modern internet-connected devices

    2) The watch knows what location / time zone you're in (based on GPS fix).

    3) The timezone/DST rules are stored locally on the watch (and updated every now and then). This works because the rules don't change every day.

    - phone obtains new time from mobile opearator (somebody has to know valid time/utc/dst)

    Getting a GPS fix does change the time. Like I said, there have been threads in the Garmin forums where people complained that their time was out of sync until they got a GPS fix. Syncing with the phone actually didn't set the time in that case, but that behavior may have changed since those old threads.

    The default setting for time sync is auto, which uses GPS. You will also see there's the Settings > System > Time > Sync with GPS option on the watch.

    I've mentioned that you need information about zone for which you want to show time. No matter it can be a list, text box, mobile operator...

    Sure, it can also be a literal location. If you set your time zone manually in macOS or iOS, you're asked to select a city. The real question is where do the DST/TZ rules come from? Like I said, those can be stored on a DB in the phone (the timezone map or timezone database), because that information doesn't change all the time.

    There's two related, but not identical things here:

    1) Information about *which* zone you're in (e.g. Eastern Time / New York). This can come from the location

    2) Information about the TZ offset and DST for your zone. This can come from the tzmap / tz database stored on the device.

    It's just like the other thread where we talked about how Linux and Windows ask you to select a time zone (e.g. Eastern Time, Mountain Time or Mountain Time (Arizona). They don't ask you to enter all details about when DST start and stops, or what the timezone offset is, because they already know that.

    I would bet there's no system which is constantly asking for TZ/DST information (like every minute, hour or day). I'm sure almost every system just has a locally stored database (like the official IANA TZ database) which is updated periodically.

    I mean you said it yourself: in Garmin Express there are TZ map updates, and there's also a message which says that timezones were updated.

    There arw 2 functions

    I realize that.I already typed too much, so I didn't want to mention utcInfo. I thought it should've been enough to point out that Time.Moment is UTC and Gregorian.info() returns local time.

    Again, this is something where you admit you're somewhat unfamiliar with the API / how it works (since you want to run tests), but you already said you're sure how it works.¯\_(ツ)_/¯. Like I already opened a bug over a year ago about how it's broken, and coincidentally I said the exact same thing that OP said. You shouldn't even have to run tests to have an idea of how it *should* work - the documentation should be enough. Testing the API should only be necessary if the docs are unclear or if you think something is broken.

    Both functions actually take an arbitrary Moment, which represents a UTC time. It doesn't have to be current time, it can be any moment you want.

  • Also, consider the new function Gregorian.localMoment() which takes UTC time and a location, and gives you back local time with timezone and DST information, as a Gregorian.LocalMoment.

    How do you think that works, unless there's TZ/DST information for the whole world stored locally on the device (this is the TZ map or TZ database)? You can pass in any location you want.

    There's no way that Garmin will implement a function that only works if you have an internet connection at that exact moment. It goes against the design philosophy of Garmin devices and everything we've seen about the way they work. You don't need to run with your phone (for example), and you don't need to be constantly syncing with your phone for the device to work. I could get away with syncing every two weeks if I wanted to.

    Even an iPhone doesn't need an internet connection to continue to display the correct time, if you manually change the time zone.