Jump to content
Sign in to follow this  
erva

Date in Android call log

Recommended Posts

I'am reading calls from Android call log. Date format is something that Delhi don't recognise. Date is returned like this: "1587377791601".

 

Any idea what this number means and how to get date and time from it?

 

Here's code what works, i have commented out lines what i don't want use. In commented lines is (StringToJString(...)) but it must be ( TJCallLog_Calls.JavaClass....) :

 

var
  cursor: JCursor;
  uri: Jnet_Uri;
  CACHED_FORMATTED_NUMBER, CACHED_LOOKUP_URI, CACHED_MATCHED_NUMBER, CACHED_NAME,
  CACHED_NORMALIZED_NUMBER, CACHED_NUMBER_LABEL, CACHED_NUMBER_TYPE, CACHED_PHOTO_ID,
  CONTENT_ITEM_TYPE, CONTENT_TYPE, COUNTRY_ISO, DATA_USAGE, DATE, DEFAULT_SORT_ORDER, DURATION,
  EXTRA_CALL_TYPE_FILTER, FEATURES, IS_READ, LIMIT_PARAM_KEY, NEW, NUMBER, NUMBER_PRESENTATION,
  OFFSET_PARAM_KEY, PHONE_ACCOUNT_COMPONENT_NAME, PHONE_ACCOUNT_ID, TRANSCRIPTION, TYPEX, VOICEMAIL_URI : integer;
  msgunixtimestampms:int64;
  CACHED_FORMATTED_NUMBERx, CACHED_LOOKUP_URIx, CACHED_MATCHED_NUMBERx, CACHED_NAMEx,
  CACHED_NORMALIZED_NUMBERx, CACHED_NUMBER_LABELx, CACHED_NUMBER_TYPEx, CACHED_PHOTO_IDx,
  CONTENT_ITEM_TYPEx, CONTENT_TYPEx, COUNTRY_ISOx, DATA_USAGEx, DATEx, DEFAULT_SORT_ORDERx, DURATIONx,
  EXTRA_CALL_TYPE_FILTERx, FEATURESx, IS_READx, LIMIT_PARAM_KEYx, NEWx, NUMBERx, NUMBER_PRESENTATIONx,
  OFFSET_PARAM_KEYx, PHONE_ACCOUNT_COMPONENT_NAMEx, PHONE_ACCOUNT_IDx, TRANSCRIPTIONx, TYPEXx, VOICEMAIL_URIx : string;
  CallTime: TDateTime;
  Result: String;
begin
  uri:=StrToJURI('content://call_log/calls');
  cursor := SharedActivity.getContentResolver.query(uri, nil, nil,nil,nil);
//  CACHED_FORMATTED_NUMBER:=cursor.getColumnIndex(StringToJstring('CACHED_FORMATTED_NUMBER'));
//  CACHED_LOOKUP_URI:=cursor.getColumnIndex(StringToJstring('CACHED_LOOKUP_URI'));
//  CACHED_MATCHED_NUMBER:=cursor.getColumnIndex(StringToJstring('CACHED_MATCHED_NUMBER'));
    CACHED_NAME:=cursor.getColumnIndex( TJCallLog_Calls.JavaClass.CACHED_NAME );
//  CACHED_NORMALIZED_NUMBER:=cursor.getColumnIndex(StringToJstring('CACHED_NORMALIZED_NUMBER'));
//  CACHED_NUMBER_LABEL:=cursor.getColumnIndex(StringToJstring('CACHED_NUMBER_LABEL'));
//  CACHED_NUMBER_TYPE:=cursor.getColumnIndex(StringToJstring('CACHED_NUMBER_TYPE'));
//  CACHED_PHOTO_ID:=cursor.getColumnIndex(StringToJstring('CACHED_PHOTO_ID'));
//  CONTENT_ITEM_TYPE:=cursor.getColumnIndex(StringToJstring('CONTENT_ITEM_TYPE'));
//  CONTENT_TYPE:=cursor.getColumnIndex(StringToJstring('CONTENT_TYPE'));
//  COUNTRY_ISO:=cursor.getColumnIndex(StringToJstring('COUNTRY_ISO'));
//  DATA_USAGE:=cursor.getColumnIndex(StringToJstring('DATA_USAGE'));
    DATE:=cursor.getColumnIndex( TJCallLog_Calls.JavaClass.DATE );
//  DEFAULT_SORT_ORDER:=cursor.getColumnIndex(StringToJstring('DEFAULT_SORT_ORDER'));
    DURATION:=cursor.getColumnIndex( TJCallLog_Calls.JavaClass.DURATION );
//  EXTRA_CALL_TYPE_FILTER:=cursor.getColumnIndex(StringToJstring('EXTRA_CALL_TYPE_FILTER'));
//  FEATURES:=cursor.getColumnIndex(StringToJstring('FEATURES'));
//  IS_READ:=cursor.getColumnIndex(StringToJstring('IS_READ'));
//  LIMIT_PARAM_KEY:=cursor.getColumnIndex(StringToJstring('LIMIT_PARAM_KEY'));
//  NEW:=cursor.getColumnIndex(StringToJstring('NEW'));
//  NUMBER:=cursor.getColumnIndex(StringToJstring('NUMBER'));
//  NUMBER_PRESENTATION:=cursor.getColumnIndex(StringToJstring('NUMBER_PRESENTATION'));
//  OFFSET_PARAM_KEY:=cursor.getColumnIndex(StringToJstring('OFFSET_PARAM_KEY'));
//  PHONE_ACCOUNT_COMPONENT_NAME:=cursor.getColumnIndex(StringToJstring('PHONE_ACCOUNT_COMPONENT_NAME'));
//  PHONE_ACCOUNT_ID:=cursor.getColumnIndex(StringToJstring('PHONE_ACCOUNT_ID'));
//  NUMBER_PRESENTATION:=cursor.getColumnIndex(StringToJstring('NUMBER_PRESENTATION'));
//  TRANSCRIPTION:=cursor.getColumnIndex(StringToJstring('TRANSCRIPTION'));
//  TYPEX:=cursor.getColumnIndex(StringToJstring('TYPE'));
 while (cursor.moveToNext) do begin
//  CACHED_FORMATTED_NUMBERx:=JStringToString(cursor.getString(CACHED_FORMATTED_NUMBER));
//  CACHED_LOOKUP_URIx:=JStringToString(cursor.getString(CACHED_LOOKUP_URI));
//  CACHED_MATCHED_NUMBERx:=JStringToString(cursor.getString(CACHED_MATCHED_NUMBER));
    CACHED_NAMEx:=JStringToString(cursor.getString(CACHED_NAME));
//  CACHED_NORMALIZED_NUMBERx:=JStringToString(cursor.getString(CACHED_NORMALIZED_NUMBER));
//  CACHED_NUMBER_LABELx:=JStringToString(cursor.getString(CACHED_NUMBER_LABEL));
//  CACHED_NUMBER_TYPEx:=JStringToString(cursor.getString(CACHED_NUMBER_TYPE));
//  CACHED_PHOTO_IDx:=JStringToString(cursor.getString(CACHED_PHOTO_ID));
//  CONTENT_ITEM_TYPEx:=JStringToString(cursor.getString(CONTENT_ITEM_TYPE));
//  CONTENT_TYPEx:=JStringToString(cursor.getString(CONTENT_TYPE));
//  COUNTRY_ISOx:=JStringToString(cursor.getString(COUNTRY_ISO));
//  DATA_USAGEx:=JStringToString(cursor.getString(DATA_USAGE));
    DATEx:=JStringToString(cursor.getString(DATE));
//  DEFAULT_SORT_ORDERx:=JStringToString(cursor.getString(DEFAULT_SORT_ORDER));
    DURATIONx:=JStringToString(cursor.getString(DURATION));
//  EXTRA_CALL_TYPE_FILTERx:=JStringToString(cursor.getString(EXTRA_CALL_TYPE_FILTER));
//  FEATURESx:=JStringToString(cursor.getString(FEATURES));
//  IS_READx:=JStringToString(cursor.getString(IS_READ));
//  LIMIT_PARAM_KEYx:=JStringToString(cursor.getString(LIMIT_PARAM_KEY));
//  NEWx:=JStringToString(cursor.getString(NEW));
//  NUMBERx:=JStringToString(cursor.getString(NUMBER));
//  NUMBER_PRESENTATIONx:=JStringToString(cursor.getString(NUMBER_PRESENTATION));
//  OFFSET_PARAM_KEYx:=JStringToString(cursor.getString(OFFSET_PARAM_KEY));
//  PHONE_ACCOUNT_COMPONENT_NAMEx:=JStringToString(cursor.getString(PHONE_ACCOUNT_COMPONENT_NAME));
//  PHONE_ACCOUNT_IDx:=JStringToString(cursor.getString(PHONE_ACCOUNT_ID));
//  NUMBER_PRESENTATIONx:=JStringToString(cursor.getString(NUMBER_PRESENTATION));
//  TRANSCRIPTIONx:=JStringToString(cursor.getString(TRANSCRIPTION));
//  TYPEXx:=JStringToString(cursor.getString(TYPEX));

    CallTime := StrToDateTime(DATEx); <- THIS DON'T WORK!
    Result := CACHED_NAMEx + ' ' + FormatDateTime('dd.mm.yyyy hh:mm:ss', CallTime) + ' ' + DURATIONx;
    ShowMessage(Result);
    end;


 

  • Thanks 1

Share this post


Link to post
program Test;
uses
  SysUtils, DateUtils;

const
  USec: Int64 = 1587377791601;

var
  dt: TDateTime;
begin
  dt := UnixToDateTime(Usec);
  Writeln(FormatDateTime('yyyy.mm.dd hh:nn:ss,zzz', dt));
end.

spits out 52272.01.01 03:26:41,000

Are you sure that you wrote an actual example value?

Share this post


Link to post

Yes, i get same like results in app with real data with several calls DATEx what comes from call_log. 

Share this post


Link to post

Solved the problem. Code is not "optimised" but works:    

 

    CallTimeDouble := StrToInt64(DATEx) / 1000; //Gives seconds
    CallTimeDouble := CallTimeDouble / 60; //Gives Minutes
    CallTimeDouble := CallTimeDouble / 60; //Gives hours
    CallTimeDOuble := CallTimeDouble / 24; //Gives dates
    CallTimeDouble := CallTimeDouble + 25569; //01.01.1970 - 30.12.1899
    CallTimeDouble := CallTimeDouble + 0.125; //Added +3h to GMT, Finland


    Result := CACHED_NAMEx + ' ' + NUMBERx + ' ' + FormatDateTime('dd.mm.yyyy hh:mm:ss', CallTimeDouble) + ' ' + DURATIONx;

    ShowMessage(Result);

Share this post


Link to post

Aha - I assumed the UnixToDateTime did milliseconds - but it also requires seconds. 
If you change your code to

  CallTimeDouble := UnixToDateTime(Round(StrToInt64(DATEx)/1000), false);

you should get local time, which for you is UTC + 3 ?
So '1587377791601' is 2020.04.20 13:16:32,000

  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×