timetimezonetoit

Time zones in toit


I noticed a certain oddity of local time. My app prints the log using the time class:

time: = Time.now.local

If run app with the toit execute ... command, the following trace appears on the console:

micrcx@micrcx-desktop:~/toit_apps/Hsm2/tests$ toit execute test_hsm_switch_async_4.toit 

18:31:53.532 exec [init INIT 0]
18:31:53.533 exec [switch Q_ENTRY 0]
18:31:53.535 exec [switch Q_INIT 0]
18:31:53.537 exec [off Q_ENTRY 0]
18:31:53.539 exec [off TURN 1]
18:31:53.540 exec [on Q_ENTRY 1]
18:31:53.543 exec [on TURN 2]
18:31:53.544 exec [off Q_ENTRY 2]
18:31:53.546 exec [off TURN 3]
18:31:53.548 exec [on Q_ENTRY 3]
18:31:53.549 exec [on RESET 4]
18:31:53.550 exec [switch Q_INIT 4]
18:31:53.552 exec [off Q_ENTRY 4]
^C
micrcx@micrcx-desktop:~/toit_apps/Hsm2/tests$

If run app with the toit run ... command, the following trace appears on the console:

micrcx@micrcx-desktop:~/toit_apps/Hsm2/tests$ toit run test_hsm_switch_async_4.toit 
2021-04-24T18:34:12.677531Z: <process initiated>

20:34:12.536 exec [init INIT 0]
20:34:12.663 exec [switch Q_ENTRY 0]
20:34:12.705 exec [switch Q_INIT 0]
20:34:12.776 exec [off Q_ENTRY 0]
20:34:12.869 exec [off TURN 1]
20:34:13.055 exec [on Q_ENTRY 1]
20:34:13.160 exec [on TURN 2]
20:34:13.234 exec [off Q_ENTRY 2]
20:34:13.323 exec [off TURN 3]
20:34:13.397 exec [on Q_ENTRY 3]
20:34:13.569 exec [on RESET 4]
20:34:13.776 exec [switch Q_INIT 4]
20:34:13.826 exec [off Q_ENTRY 4]
^C
micrcx@micrcx-desktop:~/toit_apps/Hsm2/tests$ 

My local time:

micrcx@micrcx-desktop:~/toit_apps/Hsm2/tests$ date
Sat 24 Apr 2021 21:37:07 IDT
micrcx@micrcx-desktop:~/toit_apps/Hsm2/tests$ 

So, my local time is ~ 21:00, on ESP32 - 20:00, and on the cloud - 18:00. From 20:00 everything is more or less clear: this time is in Copenhagen, and my time is ahead of it by an hour. I can't say anything about the cloud (really Greenland?), I just state the fact of the discrepancy. I have a simple question: is it possible to bring the time to my local time? In this case, to 21:00. Perhaps there is some function in toit that sets the current time zone? Something like Time.setTimeZone "US/New_York" or Time.setTimeZone "DK/Copenhagen", Time.setTimeZone "IL/Jerusalem", Time.setTimeZone "UK/London" & etc ...

Regards, MK


Solution

  • Update: in Toit v2 (open-source version), the set_tz_ function is now exposed as set_timezone. The following example would set the timezone to Pacific time.

    main:
      set_timezone "PST8PDT,M3.2.0,M11.1.0"
    

    toit exec runs on Toit servers, whereas toit run runs on the device.

    Clearly, the two have different timezones set. The local time of devices is set to CET/CEST, and the one on servers (apparently) to UTC.

    Ideally, there should be a way to set timezones on the device through a configuration file (or in the Toit console). However, that doesn't exist yet.

    In the meantime there is a way to set timezones from within Toit programs. The set_tz_ function in core.time_impl makes it possible to set the TZ variable:

    /**
    Stores the given $rules in the `TZ` environment variable and
      calls `tzset`, thus activating it.
    Valid TZ values can be easily obtained by looking at the last line of the
      zoneinfo files on Linux machines:
    ```
    tail -n1 /usr/share/zoneinfo/Europe/Copenhagen
    ```
    */
    set_tz_ rules/string:
      #primitive.core.set_tz
    

    For example, for Israel one could write:

    import core.time_impl show set_tz_
    
    main:
      set_tz_ "IST-2IDT,M3.4.4/26,M10.5.0"
      print Time.now
    

    Note that this function is private (indicated by the fact that it lives in a _impl.toit file, and that it ends with a _), and is thus not guaranteed to stay stable. For now it's, however, the best (and only) way to achieve what you want. There is also no plan to change it in the near future.

    Also note: setting the timezone this way can leak a tiny bit of memory. That's not an issue if you just set the timezone once, but avoid alternating between two timezones too often.