如何在android中将UTC时间戳转换为设备本地时间

cav*_*llo 33 android timestamp utc

我需要将从服务器获得的UTC时间戳转换为本地设备时间.目前我的时间差5小时.例如,当我发布到服务器的帖子时间说5小时前而不是一秒钟前.如何解决这个问题.谢谢

以下是我的代码

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

prg*_*lop 58

int offset = TimeZone.getDefault().getRawOffset() + TimeZone.getDefault().getDSTSavings();
long now = System.currentTimeMillis() + offset;
Run Code Online (Sandbox Code Playgroud)

  • 还要考虑夏令时:int gmtOffset = TimeZone.getDefault().getRawOffset()+ TimeZone.getDefault().getDSTSavings(); (18认同)
  • 这不应该是负数吗?`long now = System.currentTimeMillis() - gmtOffset` (2认同)
  • 抱歉,此答案不正确。自纪元以来的毫秒数始终是自纪元以来的毫秒数。针对时区和/或夏令时(DST)进行调整没有任何意义。如果您的代码最终为您提供了正确的结果,那么它到那里仍然走错了路,并且一定会引起将来读者的迷惑。 (2认同)

mad*_*527 39

将格式为"2011-06-23T15:11:32"的日期字符串转换为我们的时区.

private String getDate(String ourDate)
{
    try
    {
        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;
}
Run Code Online (Sandbox Code Playgroud)


pes*_*lla 35

您的示例中的代码乍一看似乎很好.顺便说一句,如果服务器时间戳是UTC(即它是一个纪元时间戳),那么你不必应用当前时区偏移量.换句话说,如果服务器时间戳是UTC格式,那么您可以简单地获取服务器时间戳和系统时间(System.currentTimeMillis())之间的差异,因为系统时间是UTC(纪元).

我会检查来自您服务器的时间戳是否符合您的预期.如果来自服务器的时间戳未转换为您期望的日期(在本地时区中),则时间戳与当前系统时间之间的差异将不是您所期望的.

使用Calendar来获得当前的时区.使用SimpleDateFormatter当前时区初始化a ; 然后记录服务器时间戳并验证它是否是您期望的日期:

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);
Run Code Online (Sandbox Code Playgroud)

如果打印的服务器时间不是您所期望的,那么您的服务器时间不是 UTC.

如果打印的服务器时间是您期望的日期,那么您不必将rawoffset应用于它.所以你的代码会更简单(减去所有调试日志记录):

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);
Run Code Online (Sandbox Code Playgroud)


Kas*_*ala 8

我用Extension Functionskotlin

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)
}
Run Code Online (Sandbox Code Playgroud)

用法:

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

Output: "11 Sep 2018"
Run Code Online (Sandbox Code Playgroud)

笔记:

确保正确的验证。