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,

  • 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

Related