This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

mktime() in nordic calendar example is not taking local time into account?

Given the info here and here...

1. Does this mean that the nordic example here is wrong, and that line 54 should be time_struct.tm_mon = month - 1;  to account for the indexing difference?

2. My understanding is that mktime() should convert a datetime given in local time to unix time based in UTC. However, when I call mktime() with code almost exactly like the above + the corrections you suggested, the value is always 4h early. My timezone is 4 hours behind UTC. I printed using current_time_print() to verify that the local time coming from the phone into the BLE device is correct, so my suspicion is that mktime() is not actually taking into account the local time / instead is treating the local time as if it were UTC. Can you give insight into this structure: 

p_evt->params.current_time.exact_time_256.day_date_time.date_time

to help me understand where the local time / timezone info is encoded in order for mktime() to access it to make a proper conversion? 

Thanks!

Parents
  • Sorry for the delayed response nordev. This is just a demo project from Nordic and not an official example. 

    1) It looks like it is the interpretation logic that the timer_struct.tm_month takes the same indexing as the month. Seems like this does not match what we expect for the tm_month to store.

    2) 

     The calendar example does not have the member p_evt->params.current_time.exact_time_256.day_date_time.date_time as far as i can see it. I am not an expert in thsi example but I think with the given workarounds in the other threads you mentioned, this is being used by many others. I guess the issue here is about the interpretation of data we get rather than the contents.

  • The calendar example does not have the member p_evt->params.current_time.exact_time_256.day_date_time.date_time as far as i can see it.

    This is from the official Nordic CTS Example in the SDK, see excerpt here:

    /**@brief Function for handling the Current Time Service errors.
     *
     * @param[in] p_evt  Event received from the Current Time Service client.
     */
    static void current_time_print(ble_cts_c_evt_t * p_evt)
    {
        NRF_LOG_INFO("\r\nCurrent Time:");
        NRF_LOG_INFO("\r\nDate:");
    
        NRF_LOG_INFO("\tDay of week   %s", (uint32_t)day_of_week[p_evt->
                                                             params.
                                                             current_time.
                                                             exact_time_256.
                                                             day_date_time.
                                                             day_of_week]);
    
        if (p_evt->params.current_time.exact_time_256.day_date_time.date_time.day == 0)
        {
            NRF_LOG_INFO("\tDay of month  Unknown");
        }
        else
        {
            NRF_LOG_INFO("\tDay of month  %i",
                           p_evt->params.current_time.exact_time_256.day_date_time.date_time.day);

    I am not an expert in thsi example

    I really appreciate all your help and the time you spent looking into this for me, but would it be possible in this case to reassign this ticket to someone who is an expert in the time-handling aspects of the SDK? 

    As far as I can tell, mktime() assumes your input is in local time and should take your timezone into account. For example, it is evident from this post on Stackoverflow that in the default C implementation, it should not be possible to interpret the input to mktime() as being from UTC (i.e., strip it of its timezone info) if timezone info is included. 

    If you check this nordic sample function here, you can see that it doesn't take timezone into account; by separating out all the hour, min, etc. variables, the timezone info gets stripped. Ok fine, I can rewrite it to put timezone info back. But in order to rewrite it, I need to know how nordic encodes timezone info when a timestamp comes in over CTS.--> Question 1: where is timezone info encoded in the this structure? 
    p_evt->params.current_time.exact_time_256.day_date_time.date_time

    also: I have printed out the timestamp from this structure when I receive it from CTS, and it is accurate in local time. For example, if it is 14:00 where I am, it shows me 14:00, not whatever time it is in UTC. However, I notice that all of the "adjust reasons" are 0, including "change_of_timezone", so maybe this is part of the problem. But there isn't a lot of documentation on what "adjust reasons" mean (see nordic documentation page here). --> Question 2: under what conditions are each of the 4 "adjust reasons" set to 0 or 1?

    Thank you

  • Hi,

    I think that some of the confusion here is that for the Current Time Service (CTS), timezone information is part of an optional characteristic that is not implemented by our CTS example. As such, any time received over CTS is of unknown time zone.

    mktime, on the other hand, do handle time zones.

    From what I understand, our libraries assume that the time zones of both the local and the external device are in UTC, for the purpose of storing time data and/or converting using e.g. mktime, as the "real" time zone is not known. As long as both the local and the external device operates in the same time zone, this should lead to consistent time tracking.

    Answer to Question 1: I do not find traces of time zone handling in that structure, nor in other related libraries.

    Answer to Question 2: This is specified in the Current Time Service specification from Bluetooth SIG, sections 3.1.2.1 through 3.1.2.4. The same specification also covers the (optional) Local Time Information Characteristic, which handles time zone data.

    Regards,
    Terje

Reply
  • Hi,

    I think that some of the confusion here is that for the Current Time Service (CTS), timezone information is part of an optional characteristic that is not implemented by our CTS example. As such, any time received over CTS is of unknown time zone.

    mktime, on the other hand, do handle time zones.

    From what I understand, our libraries assume that the time zones of both the local and the external device are in UTC, for the purpose of storing time data and/or converting using e.g. mktime, as the "real" time zone is not known. As long as both the local and the external device operates in the same time zone, this should lead to consistent time tracking.

    Answer to Question 1: I do not find traces of time zone handling in that structure, nor in other related libraries.

    Answer to Question 2: This is specified in the Current Time Service specification from Bluetooth SIG, sections 3.1.2.1 through 3.1.2.4. The same specification also covers the (optional) Local Time Information Characteristic, which handles time zone data.

    Regards,
    Terje

Children
  • Hi Terje,

    Thank you very much for the response.

    This is specified in the Current Time Service specification from Bluetooth SIG, sections 3.1.2.1 through 3.1.2.4. The same specification also covers the (optional) Local Time Information Characteristic, which handles time zone data.

    This was a very helpful document. If I want to take advantage of the Local Time Information Characteristic (UUID 00002A0F-0000-1000-8000-00805f9b34fb), assuming that Nordic has not already done so in the SDK, do you have recommendations for how I should modify the Current Time Service client in the SDK to use the Local Time Information Characteristic? 

    As long as both the local and the external device operates in the same time zone, this should lead to consistent time tracking.

    The reason I need the timezone info is that I am building a device that sends data with timestamps back to the phone upon request. The device gets the time in the first place from CTS, but if CTS comes in local time only without timezone info, when the timestamp gets sent back to the phone, which expects it in UTC and converts "back" to local time, it will be wrong. If the phone ever changes time zones, there will also be no way to know exactly when the timestamps stored on the device actually occurred -- they will all be wrong.

    Thanks so much!

  • Hi,

    For extending the CTS with new characteristics, the existing implementation and other services in our SDK can be used for reference. Two examples of services in the SDK that has multiple characteristics are the Device Information Service (DIS) and the Nordic UART Service (NUS). DIS is a Bluetooth SIG specified service that uses 16 bit UUIDs, and NUS is a service specified by us (Nordic Semiconductor). I am most familiar with the NUS implementation, which uses both writing and notifications for its characteristics.

    For more on BLE characteristics and services, and how they tie into the nRF5 SDK, I suggest the following tutorials. They were updated two years ago to work with nRF5 SDK version 15, and should mostly work with the current nRF5 SDK version 17 as there has not been much change in the areas of the SDK that they cover:

    Regards,
    Terje

Related