Problem with time when set to manual

I'm not sure if it's the way a "Moment" is constructed, or the way "Gregorian.Info" converts it to a readable date, but it appears that a Unix timestamp value will convert to different times depending on the system time of the watch. (And I'm taking into account timezone differences.)

In my example, I am using an arbitrary Unix timestamp (value of 1494290000) which is equivalent to May 9 2017 00:33:20 UTC.
In my demo, I create a Gregorian.Info object from var timestruct = Gregorian.info(new Time.Moment(1494290000 ), Time.FORMAT_SHORT);
and then display it using the year, month, day, hour, min and sec functions.
formattedReportTime = timestruct.year
+"-"+ timestruct.month.format("%02u")
+"-"+ timestruct.day.format("%02u")
+"\n"+ timestruct.hour.format("%02u")
+ ":" + timestruct.min.format("%02u")
+ ":" + timestruct.sec.format("%02u");


Under normal circumstances, it correctly displays
May 9 2017 10:33:20 (As I'm in Sydney, UTC=10 )
However,if I manually set my watch 30 mins slow, (change time settings from auto to manual and alter the minutes) it displays
May 9 2017 10:03:20 or 30 minutes earlier.
By messing with the time, I have found that the error in the conversion matches the difference between the watch time and the "true" time, which I believe it gets from the GPS.

I can only demonstrate this on a watch (VA-HR) as it's not possible to mess with the time settings in the emulator.

I'm posting this here, rather than report it as a bug in case it turns out I'm missing something in my logic.
  • Regardless of any of this, I just need to run an app that shows the GPS timestamp value (info.when.value()) when the manual time set to two different times. If the time value in info.when.value() tracks with actual time (monotonically increasing), then there is no problem. If I should find a discontinuity, then there is a problem.
  • It seems that you are expecting the time value to be *different* based on where you are on the globe, but that is not how it works.


    I'm not sure how you are interpreting that way.
    I'm expecting the code in two devices, whether next to each other or on opposite sides of the globe, to receive the same time from the callback, namely a representation of the time on the clock in the satellites at the time the position was established. I don't mind if it's presented as 921184556 seconds since Unix Epoch , or 1999-03-11T20:35:54+00:00 in ISO 8601 - I just don't want to see the value affected by any clock offset introduced by the operator changing the system time on one of the devices.
  • I did the test I mentioned above, and got this result.

    | Timestamp | UTC Time | Local Time | Note
    | | | | Set Time to 12:00am
    | | | | App.onStart
    | 1540827169 | 2018-10-29T15:32:49 | 2018-10-30T00:00:49 |
    | 1540827170 | 2018-10-29T15:32:50 | 2018-10-30T00:00:50 |
    | 1540827171 | 2018-10-29T15:32:51 | 2018-10-30T00:00:51 |
    | 1540827172 | 2018-10-29T15:32:52 | 2018-10-30T00:00:52 |
    | 1540827173 | 2018-10-29T15:32:53 | 2018-10-30T00:00:53 |
    | 1540827174 | 2018-10-29T15:32:54 | 2018-10-30T00:00:54 |
    | 1540827175 | 2018-10-29T15:32:55 | 2018-10-30T00:00:55 |
    | 1540827176 | 2018-10-29T15:32:56 | 2018-10-30T00:00:56 |
    | 1540827178 | 2018-10-29T15:32:58 | 2018-10-30T00:00:58 |
    | 1540827179 | 2018-10-29T15:32:59 | 2018-10-30T00:00:59 |
    | | | | App.onStop
    | | | | Set Time to 12:00pm
    | | | | App.onStart
    | 1540827209 | 2018-10-29T15:33:29 | 2018-10-29T12:00:29 |
    | 1540827210 | 2018-10-29T15:33:30 | 2018-10-29T12:00:30 |
    | 1540827211 | 2018-10-29T15:33:31 | 2018-10-29T12:00:31 |
    | 1540827212 | 2018-10-29T15:33:32 | 2018-10-29T12:00:32 |
    | 1540827213 | 2018-10-29T15:33:33 | 2018-10-29T12:00:33 |
    | 1540827214 | 2018-10-29T15:33:34 | 2018-10-29T12:00:34 |
    | 1540827215 | 2018-10-29T15:33:35 | 2018-10-29T12:00:35 |
    | 1540827216 | 2018-10-29T15:33:36 | 2018-10-29T12:00:36 |
    | 1540827217 | 2018-10-29T15:33:37 | 2018-10-29T12:00:37 |
    | 1540827219 | 2018-10-29T15:33:39 | 2018-10-29T12:00:39 |
    | 1540827220 | 2018-10-29T15:33:40 | 2018-10-29T12:00:40 |
    | 1540827221 | 2018-10-29T15:33:41 | 2018-10-29T12:00:41 |
    | 1540827222 | 2018-10-29T15:33:42 | 2018-10-29T12:00:42 |
    | 1540827223 | 2018-10-29T15:33:43 | 2018-10-29T12:00:43 |
    | | | | App.onStop


    You can see there was a 30 second jump in the timestamp and UTC time while I fumbled around for the setting to change the manual time. During this same period, you can see a 12 hour jump backward in local time. It seems to me that this clearly demonstrates that the manual time offset has no effect on the timestamp (or UTC time).

    FYI, the position information given by Position.getInfo() can be used to get GPS information with a when field that doesn't have the 1024 week offset. This isn't ideal, but you can use this to overwrite the parameter to your GPSData callback and get good data.

    function GPSData(positionInfo) {
    // hack
    positionInfo = Position.getInfo();

    timeSecs = positionInfo.when.value();


  • OK the penny has finally dropped!
    When the user alters the local time, the System deduces a time offset from UTC and uses that, instead of the user's Time Zone to provide a local time.
    So when I format the time for the user passing Location.info.when to
    Code:
    Gregorian.info((new Time.Moment(timeSecs )), Time.FORMAT_SHORT);,
    Gregorian now ignores the user's local Time Zone, and in stead, uses the time offset deduced when the user reset the clock.

    I had been blindsided by the 30 or 20 year date offset in the date component and hadn't focussed on the time component in the data I was exporting as GPX.

    Sorry for taking up so much of your time, but the mechanism wasn't obvious to me.
    As Einstein found out, time ain't simple.
  • Exactly. I thought I had explained that sufficiently in my original post. To be clear for anyone reading this in the future, Time.Moment stores a timestamp that is the offset from the Unix epoch (1970-01-01T00:00:00Z) in UTC time. The Gregorian.info() function converts a Time.Moment into a broken down time structure (year, month, day, hour, minute, second) in *local time*. If you want the broken-down time structure that has not been adjusted for local time (you want UTC time), you need to call Gregorian.utcInfo().

    When you set the time manually, the difference between the time you provide and the actual UTC time is used by the system as the local time zone offset. Every time calculation from UTC time to local time will apply this offset.

  • Hi, 

    I still see 20 years offset in PositionInfo.when.value() on my Forerunner 935 with latest updates.

    example value i get is:

    ::onNewPosition()
    info.when = 940072231
    info.position.toDegrees()[0] = 54.005345

    ::onNewPosition()
    info.when = 940072232
    info.position.toDegrees()[0] = 54.005338

    ::onNewPosition()
    info.when = 940072233
    info.position.toDegrees()[0] = 54.005331

    ::onNewPosition()
    info.when = 940072234
    info.position.toDegrees()[0] = 54.005327


    that converts to : 10/16/1999, 1:10:34 PM - ~20 year ago

    Is that something to be fixed?

    Are there any bugs for timestamps that i can track? I also observe Forerunner 920XT  always return the same when.value() for the app i'm running on both 935 and 920xt

    info.when = 2147483647

    ::onNewPosition()
    info.when = 2147483647
    info.position.toDegrees()[0] = 54.005306

    ::onNewPosition()
    info.when = 2147483647
    info.position.toDegrees()[0] = 54.005305

    ::onNewPosition()
    info.when = 2147483647
    info.position.toDegrees()[0] = 54.005303

    ::onNewPosition()
    info.when = 2147483647
    info.position.toDegrees()[0] = 54.005301

    Position is changing correctly though, info.position.toDegrees()[0] oscillates around my real location.

  • I'm sure  recalls this one and I do to, but I thought it was fixed long ago.  While what should be seen in connect IQ is "unix time" (the number of seconds since Jan 1,1970 00:00 UTC), Garmin at times uses "garmin time" (Jan 1,1990 00:00 - when Garmin was founded) - that's the 20 year difference.

    I'm surprised that this one is still around, but maybe there was a concern about breaking some existing apps.

  • If you're seeing these issues on devices with current firmware, they should be reported in a new topic in the Bug Reports forum area here. If there is anything unusual with your setup, please note those things in the bug reports.

    As Jim mentioned, the 20 year difference is most likely a caused by an epoch handling error. It should be be fixed on all devices by now. 

    The second issue looks like a bug as well as the timestamp you're getting back is the maximum 32-bit signed integer value (0x7FFFFFFF). This special value is used as a sentinel for many fields, and it may be indicating a failure to copy the timestamp value.

  • thanks for explanation, I'll post new bug then, as i'm updating firmware regularly and use latest available