Cómo analizar la fecha desde GMT TimeZone a IST TimeZone y viceversa en Android

Estoy trabajando en un proyecto que recupera Fecha / Hora desde el backend en IST (Hora estándar india) como se muestra "2013-01-09T19:32:49.103+05:30" . Sin embargo, cuando lo analizo usando el siguiente DateFormat

 DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); 

seguido de análisis …

 Date date = sdf.parse("2013-01-09T19:32:49.103+05:30"); System.out.println("XYZ ==============>"+date); 

su fecha de visualización en formato GMT como salida, es decir,

 Wed Jan 09 14:02:49 GMT+00:00 2013. 

Lo he intentado usando la clase TimeZone como …

 TimeZone timeZone=TimeZone.getTimeZone("IST"); sdf.setTimeZone(timeZone); 

pero no tiene efecto …

¿Cómo podría obtener un Objeto de clase Fecha que tenga Fecha en formato IST en lugar de GMT …?

Proporcione una solución adecuada …

EDITAR:

Así es como se ve el código:

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); TimeZone timeZone=TimeZone.getTimeZone("IST"); sdf.setTimeZone(timeZone); Date date = sdf.parse("2013-01-09T19:32:49.103+05:30"); String formattedDate=sdf.format(date); System.out.println("XYZ ==============>"+formattedDate); 

La fecha no tiene ninguna zona horaria. Es solo un titular de la cantidad de milisegundos desde el 1 de enero de 1970, 00:00:00 GMT. Tome el mismo DateFormat que usó para analizar, establezca la zona horaria IST y formatee su fecha como en el siguiente ejemplo

  DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); Date date = sdf.parse("2013-01-09T19:32:49.103+05:30"); sdf.setTimeZone(TimeZone.getTimeZone("IST")); System.out.println(sdf.format(date)); 

salida

 2013-01-09T19:32:49.103+05:30 

Tenga en cuenta que el patrón XX X se utiliza para la zona horaria ISO 8601 (-08: 00) desde 1.7. Si estás en 1.6 prueba Z Consulte la API SimpleDateFormat para obtener detalles sobre los patrones de formato

¿Cómo podría obtener un Objeto de clase Fecha que tenga Fecha en formato IST en lugar de GMT …?

No puedes. Date no tiene un formato o una zona horaria. Simplemente representa un número de milisegundos desde la época de Unix de la medianoche del 1 de enero de 1970 UTC. En cambio, Date.toString() siempre usa la zona horaria predeterminada.

Para usar un formato y una zona horaria específicos, use DateFormat lugar de Date.toString() . Puede establecer la zona horaria con DateFormat.setTimeZone() y luego convertir una Date en una String utilizando DateFormat.format() . DateFormat sí tiene algunos métodos de fábrica para la creación, o puede usar SimpleDateFormat si desea especificar un patrón en particular.

Como dice Abu, Joda Time es una API de fecha / hora mucho mejor que la incorporada, aunque solo para formatear una fecha / hora la biblioteca estándar no funciona mal. Solo tenga en cuenta que DateFormat y sus subclases generalmente no son seguros para subprocesos.

tl; dr

 OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" ) // Parsed. .toInstant() // Adjusted to UTC. 

Vea el código en vivo en IdeOne.com .

ISO 8601

Su cadena de entrada de 2013-01-09T19:32:49.103+05:30 pasa a estar en formato estándar ISO 8601. El +05:30 al final indica un desplazamiento desde el UTC de cinco horas y media más adelante, utilizado en India.

java.time

Está utilizando antiguas clases problemáticas de fecha y hora, ahora heredadas, suplantadas por las clases java.time.

Las clases java.time utilizan formatos ISO 8601 de forma predeterminada al analizar / generar cadenas que representan valores de fecha y hora. Entonces no es necesario especificar un patrón de formateo.

Como su entrada representa un momento en la línea de tiempo con un desplazamiento desde UTC, lo analizamos como un objeto OffsetDateTime .

 OffsetDateTime odt = OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" ); 

odt.toString (): 2013-01-09T19: 32: 49.103 + 05: 30

Para obtener un objeto simple en valor UTC , extraiga un Instant . Esta clase Instant es una clase básica de java.time. La clase Instant representa un momento en la línea de tiempo en UTC con una resolución de nanosegundos (hasta nueve (9) dígitos de una fracción decimal).

Puede pensar en OffsetDateTime como un Instant más un ZoneOffset .

 Instant instant = odt.toInstant(); // UTC. 

Al llamar a String se genera un objeto String en formato estándar ISO 8601. La Z en el extremo es corta para Zulu y significa UTC.

instant.toString (): 2013-01-09T14: 02: 49.103Z

Un Instant está limitado de varias maneras, como cuando se generan cadenas en varios formatos. Por lo tanto, es posible que desee trabajar con un OffsetDateTime ajustado en UTC como su desplazamiento; un desplazamiento de cero, en otras palabras. La clase ZoneOffset contiene una constante para UTC, ZoneOffset.UTC .

 OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC ); 

También puede aplicar un desplazamiento (o zona horaria) a un Instant . Llamar atOffset o atZone .

La clase Instant es la clase básica de building-block de java.time. Probablemente se use con frecuencia en su código como práctica recomendada para hacer la mayor parte de su trabajo en UTC.

 OffsetDateTime odt = instant.atOffset( ZoneOffset.ofHoursMinutes( 5 , 30 ) ); 

Zona horaria

Tenga en cuenta que una compensación desde UTC no es una zona horaria. Un huso horario es un desplazamiento más un conjunto de reglas, pasadas y presentes, para manejar anomalías como el horario de verano (DST) . Por lo tanto, siempre es preferible una zona horaria a una mera compensación si está seguro de la zona correcta.

Especifique un nombre de zona horaria adecuada en el formato continent/region , como America/Montreal , Africa/Casablanca o Pacific/Auckland . Nunca utilice la abreviatura de 3-4 letras, como EST o IST ya que no son zonas horarias verdaderas, no están estandarizadas y ni siquiera son únicas (!).

Si conoce la zona horaria prevista, aplique un ZoneId para obtener un objeto ZonedDateTime . Pero nunca asum sin verificar con la fuente de sus datos de entrada. Muchas zonas diferentes pueden compartir un desplazamiento particular. Por ejemplo, en el caso de nuestra entrada aquí, la compensación +05:30 se usa hoy en día tanto en India ( Asia/Kolkata ) como en Sri Lanka ( Asia/Colombo ). Esas dos zonas horarias pueden tener reglas diferentes para anomalías diferentes en su pasado, presente o futuro.

 ZoneId z = ZoneId.of( "Asia/Kolkata" ); ZonedDateTime zdt = odt.atZoneSameInstant( z ); 

El método toString de ZonedDateTime amplía el formato estándar ISO 8601 de forma inteligente al agregar el nombre de la zona horaria entre corchetes. En este caso, [Asia/Kolkata] .

zdt.toString (): 2013-01-09T19: 32: 49.103 + 05: 30 [Asia / Kolkata]


Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases heredadas de fecha y hora como java.util.Date , Calendar y SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a java.time.

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

¿Dónde obtener las clases de java.time?

  • Java SE 8 y SE 9 y posteriores
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Androide
    • El proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente) específicamente para Android.
    • Vea Cómo usar …

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y más .

Puedes hacer esto simplemente con el uso de la clase Calender. Por favor revisa los siguientes fragmentos:

 Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(TimeZone.getTimeZone("GMT")); calendar.setTimeInMillis(<--time stamp-->); //calendar.setTime(<--date object of gmt date-->); SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy 'at' hh:mm a"); sdf.setTimeZone(TimeZone.getDefault()); String result=sdf.format(calendar.getTime());