Daylight saving time (dst) wrong

My Time Zone is Central European Summer Time according to my tablet on which I run Garmin’s Connect App.

This is +2 hour from GMT now, but +1 in the winter.

On the simulator System.getClockTime().dst  is 3600 seconds as it should, but on my vivoactive3 watch System.getClockTime().dst   is 0.

getClockTime().timeZoneOffset is in both cases 7200 so for today it gives the right local time, but when I try to convert a winter time unixtime value  to local time, the time is +2 GMT instead of +1 as it should.

On the simulator the right local time it given.

Gregorian.info(new Time.Moment(1583843230), Time.FORMAT_MEDIUM).hour gives on my watch 14 instead of 13 is it gives on the simulator.

I have uploaded the source of a test program.

dst.zip

  • This is something that's been around for some time, and I believe it's related to how "time" is obtained.  In general on a device vs a pc/mac), you don't really need to check dst as it's handled in different ways between the sim and a device.

    When you're dealing with "unix time", that's always the count of seconds since Jan 1 1970, 00:00:00 UTC regardless of timezone/dst.

    You may find things are easier if you use Time.now() instead of System.getClockTime().

    What is it you're trying to do?

  • As I said it is no problem when I want to display the current time, but when I want to display a previous time. I have saved previous times in the unix time. When I now display these times using:

    var unixsecs= 1583843236;

    Gregorian.info(new Time.Moment(unixsecs), Time.FORMAT_SHORT).hour;

    it gives the wrong hour. Because System.getClockTime().dst wrongly gives zero I have no way of knowing how to convert a winter unix time to local time.

  • When you display a previous time using "unix time" it will always be adjusted based on the current dst.  No where is the date of the change maintained, and that date varies based where you are. As I said, "unix time" is always a count of seconds since jan 1 1970 00:00:00 UTC and when it's converted to local time, today's settings are used - tz, dst for example.. 

    If you want to store the actual time, instead of saving unix time, save it as hhmm or something.

  • When you display a previous time using "unix time" it will always be adjusted based on the current dst

    While this is what actually happens, I'm pretty confident that this is not what should happen.

    The system should account for the time zone and daylight time offsets based on the given Moment. Essentially, Gregorian.info() and Gregorian.moment() should behave like localtime and mktime do in C.

  • I've have to play around with some old c code of mine, but I think mktime and localtime use the current day's dst and not the dst from a past or future date.

    On garmin devices, there's the tzmap file that indicates the dates for dst at the actual location, and that gets updated a couple times a year as things change (if I recall, this year, there's no dst in Brazil).  There's no history of when dst occurred in the past available.

    So, for something like new Time.Moment(1583843230) where a "unix time" is used, there's no way of knowing if on the date for it, if dst was on or off, as it's in the past, and tzmap could have changed, so the setting for "today" is used.

    On a pc in the sim, same thing.  No history of when dst started/ended, just what it is today.

  • #include <time.h>
    #include <stdlib.h>
    #include <iostream>
    using namespace std;


    void printtime(time_t t) {
    cout<<"GMT: "<<asctime(gmtime(&t));
    cout<<"Localtime: "<<ctime(&t);
    }
    int main(int argc,char ** argv) {
    setenv( "TZ","Europe/Amsterdam",1);
    if(argc!=1)
    printtime(atoi(argv[1]));
    else {
    time_t winter=1583843230,summer=1586863098;
    printtime(winter);
    cout<<endl;
    printtime(summer);
    }

    }

  • The problem is you don't know if winter or summer is correct for a time from the past.

    Consider this.  Let's say that dst started at midnight and it's currently 8:00.  Is 1 day ago 8:00 or 7:00? 24 hours would be 7:00 (there was that skipped hour) but you might think that 8:00 today would be 8:00 yesterday.

  • As I mentioned before if you want to have it show the time as it was on the day in the past, instead of using unix time, you could save the time as something like

    var t=1200;

    and you could then show it as 12:00 during dst or not.