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

Current Time Service: Unix time stamp gives incorrect value

Hello,

I am using a custom nRF52840 ( SDK 14.2.0, SoftDevice S140) based board to connect with an iOS(v 13.3) phone. 

I am running a custom application which uses the Current Time Service.

When I convert the unix time I get from the phone, I get the current time, but the date is incorrect(off by a few weeks).

Function called on BLE_CTS_C_EVT_CURRENT_TIME client event:

static void current_time_print(ble_cts_c_evt_t * p_evt)
{

    uint32_t year, month, day, hour, minute, second;

    year = p_evt->params.current_time.exact_time_256.day_date_time.date_time.year;
    month = p_evt->params.current_time.exact_time_256.day_date_time.date_time.month;
    day = p_evt->params.current_time.exact_time_256.day_date_time.day_of_week;
    hour = p_evt->params.current_time.exact_time_256.day_date_time.date_time.hours;
    minute = p_evt->params.current_time.exact_time_256.day_date_time.date_time.minutes;
    second = p_evt->params.current_time.exact_time_256.day_date_time.date_time.seconds;

    nrf_cal_set_time(year, month, day, hour, minute, second);
}

function which calculates unix time:

void nrf_cal_set_time(uint32_t year, uint32_t month, uint32_t day, uint32_t hour, uint32_t minute, uint32_t second)
{
    static time_t uncal_difftime, difftime, newtime;
    time_struct.tm_year = year - 1900;
    time_struct.tm_mon = month;
    time_struct.tm_mday = day;
    time_struct.tm_hour = hour;
    time_struct.tm_min = minute;
    time_struct.tm_sec = second;   
    newtime = mktime(&time_struct);
    //CAL_RTC->TASKS_CLEAR = 1;  
    
    // Calculate the calibration offset 
    if(m_last_calibrate_time != 0)
    {
        difftime = newtime - m_last_calibrate_time;
        uncal_difftime = m_time - m_last_calibrate_time;
        m_calibrate_factor = (float)difftime / (float)uncal_difftime;
    }
    
    // Assign the new time to the local time variables
    m_time = m_last_calibrate_time = newtime;
     
}  

For example, right now I got "1585828164" which converts to April 2, 2020 11:49:24 AM.

Whereas I should get something around the range of 1585068996.

What might be happening?

Please help, 

Thanks,

Parents
  • Hi,

    In your current_time_print() function, you have (at least) two bugs:

    1. You read the day-of-week out of the event structure, instead of reading day-of-month. (Should use "day_date_time.date_time.day" instead of "day_date_time.day_of_week".)
    2. In the Bluetooth date_time format, months start on index 1 for January, while for time_t months start on index 0 for January.

    The combination of the above, means if you tested this on a Tuesday in March, the month gets incremented by one (because of index offset), and the day is set to 2 (which is the Bluetooth day_of_week index for Tuesday.) Hence April 2.

    In addition to the above issues, please note that value 0 in most of the fields means the value is unknown. An application should handle value 0 in an appropriate manner without failing, as devices are expected to use this value when not having complete (or accurate) time data.

    I suggest having a look at the Current Time Application example in the SDK, as it implements a full current_time_print() function that takes into account unknown values (0 values) for fields, as well as conforms to the proper indexing of Months as defined by the Bluetooth SIG.

    Regards,
    Terje

Reply
  • Hi,

    In your current_time_print() function, you have (at least) two bugs:

    1. You read the day-of-week out of the event structure, instead of reading day-of-month. (Should use "day_date_time.date_time.day" instead of "day_date_time.day_of_week".)
    2. In the Bluetooth date_time format, months start on index 1 for January, while for time_t months start on index 0 for January.

    The combination of the above, means if you tested this on a Tuesday in March, the month gets incremented by one (because of index offset), and the day is set to 2 (which is the Bluetooth day_of_week index for Tuesday.) Hence April 2.

    In addition to the above issues, please note that value 0 in most of the fields means the value is unknown. An application should handle value 0 in an appropriate manner without failing, as devices are expected to use this value when not having complete (or accurate) time data.

    I suggest having a look at the Current Time Application example in the SDK, as it implements a full current_time_print() function that takes into account unknown values (0 values) for fields, as well as conforms to the proper indexing of Months as defined by the Bluetooth SIG.

    Regards,
    Terje

Children
Related