开发者

Convert UTC to current locale time

开发者 https://www.devze.com 2023-03-07 00:58 出处:网络
I a开发者_JS百科m downloading some JSON data from a webservice. In this JSON I\'ve got some Date/Time values. Everything in UTC.

I a开发者_JS百科m downloading some JSON data from a webservice. In this JSON I've got some Date/Time values. Everything in UTC. How can I parse this date string so the result Date object is in the current locale?

For example: the Server returned "2011-05-18 16:35:01" and my device should now display "2011-05-18 18:35:01" (GMT +2)

My current code:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));


It has a set timezone method:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));

all done!


So you want to inform SimpleDateFormat of UTC time zone:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TimeZone utcZone = TimeZone.getTimeZone("UTC");
simpleDateFormat.setTimeZone(utcZone);
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));

To display:

simpleDateFormat.setTimeZone(TimeZone.getDefault());
String formattedDate = simpleDateFormat.format(myDate);


public static String toLocalDateString(String utcTimeStamp) {
    Date utcDate = new Date(utcTimeStamp);
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    df.setTimeZone(TimeZone.getTimeZone("PST"));
    return df.format(utcDate);
}

Cheers!


java.time

I should like to contribute the modern answer. Most of the other answers are correct and were fine answers in 2011. Today SimpleDateFormat is long outdated, and it always came with some surprises. And today we have so much better: java.time also known as JSR-310, the modern Java date and time API. This answer is for anyone who either accepts an external dependency (just until java.time comes to your Android device) or is already using Java 8 or later.

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
    String dateTimeFromServer = "2011-05-18 16:35:01";
    String localTimeToDisplay = LocalDateTime.parse(dateTimeFromServer, formatter)
            .atOffset(ZoneOffset.UTC)
            .atZoneSameInstant(ZoneId.of("Europe/Zurich"))
            .format(formatter);

The result of this code snippet is what was asked for:

2011-05-18 18:35:01

Give explicit time zone if you can

I have given an explicit time zone of Europe/Zurich. Please substitute your desired local time zone. To rely on your device’s time zone setting, use ZoneId.systemDefault(). However, be aware that this is fragile because it takes the time zone setting from the JVM, and that setting could be changed under our feet by other parts of your program or other programs running in the same JVM.

Using java.time on Android

I promised you an external dependency. To use the above on Android you need the ThreeTenABP, the Android edition of ThreeTen Backport, the backport of JSR-310 to Java 6 and 7. How to go about it is nicely and thoroughly explained in this question: How to use ThreeTenABP in Android Project.


Your String myUTC = "2016-02-03T06:41:33.000Z"

SimpleDateFormat existingUTCFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
SimpleDateFormat requiredFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

try{
Date getDate = existingFormat.parse(myUTC);
String mydate = requiredFormat.format(getDate)
}
catch(ParseException){
}


A Date object is always a wrapper around milliseconds since epoch 0 in UTC. It does never represent local time.

That means that you need to create a second SimpleDateFormatter that creates a display string that is in local time.

Edit: @Op. Note that the preffered class for date/time-formatting on Android is java.text.DateFormat


If you had a timestamp (Long) as input instead (for the UTC time), since this is on Android, you can do something as such:

fun DateFormat.formatUtcEpochSecond(epochSecond: Long): String = format(CalendarEx.getFromEpochSecond(epochSecond).time)

fun DateFormat.formatUtcEpochMs(epochMilli: Long): String = format(CalendarEx.getFromEpochMilli(epochMilli).time)

CalendarEx.kt

object CalendarEx {

    @JvmStatic
    fun getFromEpochMilli(epochMilli: Long): Calendar {
        val cal = Calendar.getInstance()
        cal.timeInMillis = epochMilli
        return cal
    }

    @JvmStatic
    fun getFromEpochSecond(epochSecond: Long): Calendar {
        val cal = Calendar.getInstance()
        cal.timeInMillis = epochSecond * 1000L
        return cal
    }
}

DateHelper.kt

/**
 * gets the default date formatter of the device
 */
@JvmStatic
fun getFormatDateUsingDeviceSettings(context: Context): java.text.DateFormat {
    return DateFormat.getDateFormat(context) ?: SimpleDateFormat("yyyy/MM/dd", Locale.getDefault())
}

/**
 * gets the default time formatter of the device
 */
@JvmStatic
fun getFormatTimeUsingDeviceSettings(context: Context): java.text.DateFormat {
    return DateFormat.getTimeFormat(context) ?: SimpleDateFormat("HH:mm", Locale.getDefault())
}

Example usage:

    val dateFormat = DateHelper.getFormatDateUsingDeviceSettings(this)
    val timeFormat = DateHelper.getFormatTimeUsingDeviceSettings(this)
    val timeStampSecondsInUtc = 1516797000L
    val localDateTime = Instant.ofEpochSecond(timeStampSecondsInUtc).atZone(ZoneId.ofOffset("UTC", ZoneOffset.ofHours(0))).toLocalDateTime()
    Log.d("AppLog", "input time in UTC:" + localDateTime)
    Log.d("AppLog", "formatted date and time in current config:${dateFormat.formatUtcEpochSecond(timeStampSecondsInUtc)} ${timeFormat.formatUtcEpochSecond(timeStampSecondsInUtc)}")
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号