Search code examples
androidtimestamputc

How to convert UTC timestamp to device local time in android


I need to convert the UTC time stamp that I get from the server to local device time. Currently, I get 5 hrs difference in my time. For example, when I post to the server, the post time says 5 hours ago instead of a second ago. How could I fix this issue?

Below is the code that I do:

long timestamp = cursor.getLong(columnIndex);
            CharSequence relTime = DateUtils
                    .getRelativeTimeSpanString(timestamp * 1000
                            + TimeZone.getDefault().getRawOffset(),
                            System.currentTimeMillis(),
                            DateUtils.MINUTE_IN_MILLIS);
            ((TextView) view).setText(relTime);

Solution

  • The code in your example looks fine at first glance. BTW, if the server timestamp is in UTC (i.e. it's an epoch timestamp) then you should not have to apply the current timezone offset. In other words if the server timestamp is in UTC then you can simply get the difference between the server timestamp and the system time (System.currentTimeMillis()) as the system time is in UTC (epoch).

    I would check that the timestamp coming from your server is what you expect. If the timestamp from the server does not convert into the date you expect (in the local timezone) then the difference between the timestamp and the current system time will not be what you expect.

    Use Calendar to get the current timezone. Initialize a SimpleDateFormatter with the current timezone; then log the server timestamp and verify if it's the date you expect:

    Calendar cal = Calendar.getInstance();
    TimeZone tz = cal.getTimeZone();
    
    /* debug: is it local time? */
    Log.d("Time zone: ", tz.getDisplayName());
    
    /* date formatter in local timezone */
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
    sdf.setTimeZone(tz);
    
    /* print your timestamp and double check it's the date you expect */
    long timestamp = cursor.getLong(columnIndex);
    String localTime = sdf.format(new Date(timestamp * 1000)); // I assume your timestamp is in seconds and you're converting to milliseconds?
    Log.d("Time: ", localTime);
    

    If the server time that is printed is not what you expect then your server time is not in UTC.

    If the server time that is printed is the date that you expect then you should not have to apply the rawoffset to it. So your code would be simpler (minus all the debug logging):

    long timestamp = cursor.getLong(columnIndex);
    Log.d("Server time: ", timestamp);
    
    /* log the device timezone */
    Calendar cal = Calendar.getInstance();
    TimeZone tz = cal.getTimeZone();
    Log.d("Time zone: ", tz.getDisplayName());
    
    /* log the system time */
    Log.d("System time: ", System.currentTimeMillis());
    
    CharSequence relTime = DateUtils.getRelativeTimeSpanString(
        timestamp * 1000,
        System.currentTimeMillis(),
        DateUtils.MINUTE_IN_MILLIS);
    
    ((TextView) view).setText(relTime);