web-dev-qa-db-ja.com

androidでUTCタイムスタンプをデバイスの現地時間に変換する方法

サーバーから取得したUTCタイムスタンプをローカルデバイスの時刻に変換する必要があります。現在、時間に5時間の差があります。たとえば、サーバーに投稿すると、投稿時間は1秒前ではなく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);
31
cavallo

あなたの例のコードは一見したところうまく見えます。ところで、サーバーのタイムスタンプがUTCの場合(つまり、エポックタイムスタンプの場合)、現在のタイムゾーンオフセットを適用する必要はありません。つまり、サーバーのタイムスタンプがUTCである場合、システム時刻はUTC(エポック)であるため、サーバーのタイムスタンプとシステム時刻(System.currentTimeMillis())の差を簡単に取得できます。

サーバーから送られるタイムスタンプが期待どおりであることを確認します。サーバーからのタイムスタンプが(ローカルタイムゾーンで)予想される日付に変換されない場合、タイムスタンプと現在のシステム時刻の差は予想どおりにはなりません。

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);
33
pestrella
int offset = TimeZone.getDefault().getRawOffset() + TimeZone.getDefault().getDSTSavings();
long now = System.currentTimeMillis() + offset;
56
prgDevelop

「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;
}
37
madhu sudhan

kotlinExtension Functionsを使用して実行しました

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"

注意:

適切な検証を確認してください。

3
Kasim Rangwala

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 

これが他の人にも役立つことを願っています。

1
Chintan Khetiya

これは、同じ要件を持つ誰かを助けるかもしれません

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;
    }
0
CLIFFORD P Y

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();
}
0
Anand Jagtap

@prgDevelopからの答えは、my Android Marshmallowで0を返します。7200000を返す必要があります。これらの変更により正常に動作します。

int offset = TimeZone.getTimeZone(Time.getCurrentTimezone()).getRawOffset() + TimeZone.getTimeZone(Time.getCurrentTimezone()).getDSTSavings();
0
oml