Conversión de fechas UTC a otras zonas horarias

Estoy convirtiendo una hora UTC a otra zona horaria, usando este método:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date parsed = format.parse("2011-03-01 15:10:37"); TimeZone tz = TimeZone.getTimeZone("America/Chicago"); format.setTimeZone(tz); String result = format.format(parsed); 

Entonces la entrada es 2011-03-01 15:10:37 pero el resultado de esto (valor de resultado) es 2011-03-01 05:40:37 . Mientras que parece apagado, y de acuerdo con este enlace , debería ser 2011-03-01 09:10:37 .

¿Qué estoy haciendo mal?

Resultó que el código era casi correcto, lo que no tuve en cuenta fue que al analizar el String para obtener inicialmente un objeto Date , usa el TimeZone predeterminado del sistema, por lo que la fecha de origen no estaba en UTC como esperaba.

El truco fue establecer la zona horaria al analizar la fecha en UTC y luego establecerla en el TimeZone destino. Algo como esto:

 SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); sourceFormat.setTimeZone(TimeZone.getTimeZone("UTC")); Date parsed = sourceFormat.parse("2011-03-01 15:10:37"); // => Date is in UTC now TimeZone tz = TimeZone.getTimeZone("America/Chicago"); SimpleDateFormat destFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); destFormat.setTimeZone(tz); String result = destFormat.format(parsed); 

Convertir una cadena de fecha del formato “2011-06-23T15: 11: 32” a la zona horaria.

  private String getDate(String dateString) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); formatter.setTimeZone(TimeZone.getTimeZone("UTC")); Date value = null; try { value = formatter.parse(dateString); } catch (ParseException e) { e.printStackTrace(); } SimpleDateFormat dateFormatter = new SimpleDateFormat("dd/MM/yyyy hh:mmaa"); dateFormatter.setTimeZone(TimeZone.getDefault()); String dt = dateFormatter.format(value); return dt; } 

Debe tener en cuenta el horario de verano. Lo hago resolviendo el desplazamiento (a partir de UTC) en milisegundos. Algo como esto debería funcionar.

 int currentOffsetFromUTC = tz.getRawOffset() + (tz.inDaylightTime(parsed) ? tz.getDSTSavings() : 0); String result = format.format(parsed.getTime() + currentOffsetFromUTC); 

El inDayLightTime(...) devuelve un booleano y debe pasarse un objeto Date para que decida si esa ‘fecha’ representa uno durante un período de DST o no.

Puede analizar el formato de fecha y la zona horaria de acuerdo con sus requisitos. Prueba este fragmento de código, espero que sea útil para ti.

 private String getFormattedDate(String OurDate) { try { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); // According to your Server TimeStamp formatter.setTimeZone(TimeZone.getTimeZone("UTC")); //your Server Time Zone Date value = formatter.parse(OurDate); // Parse your date SimpleDateFormat dateFormatter = new SimpleDateFormat("MM-dd-yyyy"); //this format changeable according to your choice dateFormatter.setTimeZone(TimeZone.getDefault()); OurDate = dateFormatter.format(value); } catch (Exception e) { OurDate = "00-00-0000 00:00"; } return OurDate; } 

El siguiente código funciona bien para mí para cambiar una fecha de un tz a otro. Considera el DayLightSaving también.

 public static Calendar changeTimezoneOfDate(Date date, TimeZone fromTZ, TimeZone toTZ) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); long millis = calendar.getTimeInMillis(); long fromOffset = fromTZ.getOffset(millis); long toOffset = toTZ.getOffset(millis); long convertedTime = millis - (fromOffset - toOffset); Calendar c = Calendar.getInstance(); c.setTimeInMillis(convertedTime); return c; }