java - como - Convertir UTC a la hora local actual
hora zulu aviacion (7)
Estoy descargando algunos datos JSON de un servicio web. En este JSON tengo algunos valores de Fecha / Hora. Todo en UTC. ¿Cómo puedo analizar esta cadena de fecha para que el objeto Fecha de resultado esté en la configuración regional actual?
Por ejemplo: el servidor devolvió "2011-05-18 16:35:01" y mi dispositivo ahora debería mostrar "2011-05-18 18:35:01" (GMT +2)
Mi código actual:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));
Por lo tanto, desea informar SimpleDateFormat de la zona horaria UTC:
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"));
Para mostrar:
simpleDateFormat.setTimeZone(TimeZone.getDefault());
String formattedDate = simpleDateFormat.format(myDate);
Si tiene una marca de tiempo (Long) como entrada (para la hora UTC), ya que está en Android, puede hacer algo como tal:
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())
}
Ejemplo de uso:
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)}")
Su cadena 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){
}
Tiene un método de zona horaria establecido:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));
¡todo listo!
Un objeto Date siempre es un contenedor alrededor de milisegundos desde época 0 en UTC. Nunca representa la hora local.
Eso significa que debe crear un segundo SimpleDateFormatter que crea una cadena de visualización que está en hora local.
Editar: @Op. Tenga en cuenta que la clase java.text.DateFormat el formato de fecha / hora en Android es java.text.DateFormat
java.time
Me gustaría contribuir con la respuesta moderna. La mayoría de las otras respuestas son correctas y fueron buenas respuestas en 2011. Hoy, SimpleDateFormat
está desactualizado, y siempre SimpleDateFormat
algunas sorpresas. Y hoy tenemos mucho mejor: java.time
también conocido como JSR-310, la moderna API de fecha y hora de Java. Esta respuesta es para cualquiera que acepte una dependencia externa (solo hasta que java.time
llegue a su dispositivo Android) o que ya esté usando Java 8 o posterior.
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);
El resultado de este fragmento de código es lo que se solicitó:
2011-05-18 18:35:01
Indique la zona horaria explícita si puede
He proporcionado una zona horaria explícita de Europa / Zurich. Por favor, sustituya su zona horaria local deseada. Para confiar en la configuración de la zona horaria de su dispositivo, use ZoneId.systemDefault()
. Sin embargo, tenga en cuenta que esto es frágil porque requiere la configuración de zona horaria de la JVM, y esa configuración podría cambiarse bajo nuestros pies por otras partes de su programa u otros programas que se ejecutan en la misma JVM.
Usando java.time en Android
Te prometí una dependencia externa. Para usar lo anterior en Android, necesitas ThreeTenABP, la edición Android de ThreeTen Backport, el backport de JSR-310 a Java 6 y 7. Cómo hacerlo está bien y completamente explicado en esta pregunta: Cómo usar ThreeTenABP en Android Proyecto .
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);
}
¡Aclamaciones!