相关文章推荐
眼睛小的生姜  ·  jtextarea_百度百科·  1 月前    · 
非常酷的鼠标垫  ·  java - http ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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);

Java:

int offset = TimeZone.getDefault().getRawOffset() + TimeZone.getDefault().getDSTSavings();
long now = System.currentTimeMillis() - offset;

Kotlin:

val offset: Int = TimeZone.getDefault().rawOffset + TimeZone.getDefault().dstSavings
val now: Long = System.currentTimeMillis() - offset
                To also account for daylight savings: int gmtOffset =  TimeZone.getDefault().getRawOffset() + TimeZone.getDefault().getDSTSavings();
– Farshid T
                Aug 26, 2015 at 12:01
                Sorry, this answer is not correct. Milliseconds since the epoch are always since the epoch. Adjusting them for time zone and/or summer time (DST) does not make sense. If you code ends up giving you the correct result, it has still gone the wrong way there and will be sure to confuse future readers.
– Ole V.V.
                May 31, 2018 at 7:27

Converting a date String of the format "2011-06-23T15:11:32" to our time zone.

private String getDate(String ourDate)
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date value = formatter.parse(ourDate);
        SimpleDateFormat dateFormatter = new SimpleDateFormat("MM-dd-yyyy HH:mm"); //this format changeable
        dateFormatter.setTimeZone(TimeZone.getDefault());
        ourDate = dateFormatter.format(value);
        //Log.d("ourDate", ourDate);
    catch (Exception e)
        ourDate = "00-00-0000 00:00";
  return ourDate;
                This works perfect. But suppose i m trying convert 2018-04-27 12:48:00 UTC time zone to IST time zone. Now here it return after convert   2018-04-27 06:18:00 am instead of 2018-04-27 06:18:00 pm what to do in this scenario? Here if any UTC time come between 12:00:00 to 12:59:59. this return wrong result. In other work perfect.
– Dharmik Mavani
                Apr 26, 2018 at 12:27

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);
thanks @pestrella that gives me a formatted time format but i want to show time like 2 min ago, 1 hour ago .. using the android utils. any workaround for that ....thanks – cavallo Feb 14, 2013 at 5:37 Your code example looks good to me and that should give you the time difference (e.g. 2 min ago). However, I don't believe you should have to apply the rawoffset to the server time (assuming that the server time is in UTC). I need more information to help. As per my code example, did you print the server time, and is it the time you expect? – pestrella Feb 14, 2013 at 11:43 yes ur code gives me the time in standard format,, but i want to show the time like 17 mins ago.... – cavallo Feb 14, 2013 at 12:00 Out of curiosity what is the server timestamp that you are working with? Also, if you change DateUtils.MINUTE_IN_MILLIS to 0 then you will get the elapsed time in seconds (e.g. 2 seconds ago). Could you do another test using 0 instead of MINUTE_IN_MILLIS? Log the server timestamp. What timestamp did you get? and what did your TextView display? – pestrella Feb 14, 2013 at 12:17

I did it using Extension Functions in kotlin

fun String.toDate(dateFormat: String = "yyyy-MM-dd HH:mm:ss", timeZone: TimeZone = TimeZone.getTimeZone("UTC")): Date {
    val parser = SimpleDateFormat(dateFormat, Locale.getDefault())
    parser.timeZone = timeZone
    return parser.parse(this)
fun Date.formatTo(dateFormat: String, timeZone: TimeZone = TimeZone.getDefault()): String {
    val formatter = SimpleDateFormat(dateFormat, Locale.getDefault())
    formatter.timeZone = timeZone
    return formatter.format(this)

Usage:

"2018-09-10 22:01:00".toDate().formatTo("dd MMM yyyy")
Output: "11 Sep 2018"

Note:

Ensure the proper validation.

I have do something like this to get date in local device timezone from UTC time stamp.

private long UTC_TIMEZONE=1470960000;
private String OUTPUT_DATE_FORMATE="dd-MM-yyyy - hh:mm a"
getDateFromUTCTimestamp(UTC_TIMEZONE,OUTPUT_DATE_FORMATE);

Here is the function

 public String getDateFromUTCTimestamp(long mTimestamp, String mDateFormate) {
        String date = null;
        try {
            Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
            cal.setTimeInMillis(mTimestamp * 1000L);
            date = DateFormat.format(mDateFormate, cal.getTimeInMillis()).toString();
            SimpleDateFormat formatter = new SimpleDateFormat(mDateFormate);
            formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date value = formatter.parse(date);
            SimpleDateFormat dateFormatter = new SimpleDateFormat(mDateFormate);
            dateFormatter.setTimeZone(TimeZone.getDefault());
            date = dateFormatter.format(value);
            return date;
        } catch (Exception e) {
            e.printStackTrace();
        return date;

Result :

12-08-2016 - 04:30 PM 

Hope this will work for others.

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Solution using java.time, the modern Date-Time API:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
public class Main {
    public static void main(String[] args) {
        // A sample timestamp as Unix epoch (i.e. seconds from 01-01-1970T00:00:00 GMT)
        long epochSeconds = 1632131465L;
        // Note: Use Instant#ofEpochMilli in case you have timestamp in milliseconds
        Instant instant = Instant.ofEpochSecond(epochSeconds);
        System.out.println(instant);
        LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        System.out.println(ldt);

Output in my timezone, Europe/London:

2021-09-20T09:51:05Z
2021-09-20T10:51:05

ONLINE DEMO

An Instant represents an instantaneous point on the timeline, normally represented in UTC time. The Z in the output is the timezone designator for a zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).

Learn more about the modern Date-Time API from Trail: Date Time.

* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

DateTime dateTimeNew = new DateTime(date.getTime(),
DateTimeZone.forID("Asia/Calcutta"));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String datetimeString = dateTimeNew.toString("yyyy-MM-dd HH:mm:ss");
long milis = 0;
try {
     milis = simpleDateFormat.parse(datetimeString).getTime();
} catch (ParseException e) {
   e.printStackTrace();

The answer from @prgDevelop returns 0 on my Android Marsmallow. Must return 7200000. These changes make it work fine:

int offset = TimeZone.getTimeZone(Time.getCurrentTimezone()).getRawOffset() + TimeZone.getTimeZone(Time.getCurrentTimezone()).getDSTSavings();
private String getDate(long time){
        SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm a");
        String dateString = formatter.format(new Date(time));
        String date = ""+dateString;
        return date;

I had a similar problem. Simply set your utc timestamp to your timezone calendar and format the date. Timestamp is still the same no matter timezone.

val local = Calendar.getInstance()   // get your device timezone calendar
local.timeInMillis = <timestamp>
val sdf = SimpleDateFormat("dd/MM/yyyy HH:mm:ss")
val formatted = sdf.format(Date(local.timeInMillis))
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.