Как преобразовать метку времени UTC в местное время устройства в android
Мне нужно преобразовать отметку времени 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);
7 ответов
код в вашем примере выглядит отлично на первый взгляд. Кстати, если метка времени сервера находится в UTC (т. е. это метка времени эпохи), вам не нужно применять текущее смещение часового пояса. Другими словами, если метка времени сервера находится в UTC, вы можете просто получить разницу между меткой времени сервера и системным временем (System.currentTimeMillis()
), поскольку системное время находится в UTC (epoch).
Я бы проверил, что метка времени, поступающая с вашего сервера, - это то, что вы ожидаете. Если время от сервер не преобразуется в ожидаемую дату (в локальном часовом поясе), тогда разница между меткой времени и текущим системным временем не будет такой, как вы ожидаете.
использовать Calendar
получить текущий часовой пояс. Инициализировать SimpleDateFormatter
с текущим часовым поясом; затем войдите в метку времени сервера и убедитесь, что это дата, которую вы ожидаете:
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);
если серверное время, которое печатается не что вы ожидаете, то ваше время сервера не в 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);
int offset = TimeZone.getDefault().getRawOffset() + TimeZone.getDefault().getDSTSavings();
long now = System.currentTimeMillis() + offset;
преобразование строки даты формата "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;
}
Я сделал что-то вроде этого, чтобы получить дату в часовом поясе локального устройства от отметки времени UTC.
private long UTC_TIMEZONE=1470960000;
private String OUTPUT_DATE_FORMATE="dd-MM-yyyy - hh:mm a"
getDateFromUTCTimestamp(UTC_TIMEZONE,OUTPUT_DATE_FORMATE);
здесь функция
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;
}
результат :
12-08-2016 - 04:30 PM
надеюсь, это сработает для других.
локальный в UTC
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();
}
Это может помочь кому-то с тем же требованием
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;
}
Я сделал это с помощью Extension Functions
на 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)
}
использование:
"2018-09-10 22:01:00".toDate().formatTo("dd MMM yyyy")
Output: "11 Sep 2018"
Примечание:
обеспечить надлежащую проверку.