Convertir fecha / hora para una zona horaria determinada - java

80

Quiero convertir esta marca de tiempo GMT a GMT + 13:

2011-10-06 03:35:05

He probado alrededor de 100 combinaciones diferentes de DateFormat, TimeZone, Date, GregorianCalendar, etc. para intentar hacer esta tarea MUY básica.

Este código hace lo que quiero para la HORA ACTUAL:

Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");    
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));  

String newZealandTime = formatter.format(calendar.getTime());

Pero lo que quiero es establecer la hora en lugar de usar la hora actual.

Descubrí que cada vez que trato de establecer la hora de esta manera:

calendar.setTime(new Date(1317816735000L));

se utiliza la zona horaria de la máquina local. ¿Porqué es eso? Sé que cuando "nueva fecha ()" devuelve la hora UTC + 0, entonces, ¿por qué cuando establece la hora en milisegundos, ya no asume que la hora está en UTC?

Es posible que:

  1. Establecer la hora en un objeto (Calendario / Fecha / Marca de hora)
  2. (Posiblemente) Establezca la zona horaria de la marca de tiempo inicial (calendar.setTimeZone (...))
  3. Formatee la marca de tiempo con una nueva zona horaria (formatter.setTimeZone (...)))
  4. Devuelve una cadena con la nueva zona horaria. (formatter.format (calendar.getTime ()))

Gracias de antemano por cualquier ayuda: D

travega
fuente
Demasiadas preguntas en una publicación ...
Barmaley
Las mismas 2 preguntas formuladas solo la segunda se formula por segunda vez con un algoritmo de escenario para mayor claridad. Gracias por la entrada aunque:?
travega
Parece que el único problema es que 1317816735000Lla marca de tiempo es incorrecta 2011-10-06 03:35:05 GMT. De lo contrario, su enfoque es correcto.
augurar
1
Para su información, las problemáticas clases antiguas de fecha y hora como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y versiones posteriores. Consulte el tutorial de Oracle .
Basil Bourque

Respuestas:

62

Para mí, la forma más sencilla de hacerlo es:

Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

//Here you say to java the initial timezone. This is the secret
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
//Will print in UTC
System.out.println(sdf.format(calendar.getTime()));    

//Here you set to your timezone
sdf.setTimeZone(TimeZone.getDefault());
//Will print on your default Timezone
System.out.println(sdf.format(calendar.getTime()));
charlestón
fuente
1
@Charleston ¿Cuál es la reviewlíneadate = sdf.parse(review);
09Q71AO534
1
@Charleston Pero no existe tal tipo de método en SDF, sdf.parse(DateObject)no está definido en Java que estoy usando JDK.1.7.
09Q71AO534
Lo siento mucho por mi segunda respuesta. ¡Ni siquiera lo probé! ¡Pero ahora está probado y funcionando!
Charleston
1
¿Cómo se obtiene una fecha real en lugar de una cadena?
Tulains Córdova
1
Quizás debería ser: SimpleDateFormat ("aaaa-MM-dd hh: mm: ss")
Marcos
31

Comprender cómo funciona el tiempo en la computadora es muy importante. Dicho esto, estoy de acuerdo en que si se crea una API para ayudarlo a procesar el tiempo de la computadora como en tiempo real, entonces debería funcionar de tal manera que le permita tratarlo como en tiempo real. En su mayor parte, este es el caso, pero hay algunos descuidos importantes que necesitan atención.

De todos modos estoy divagando !! Si tiene su compensación UTC (es mejor trabajar en UTC que en las compensaciones GMT), puede calcular el tiempo en milisegundos y agregarlo a su marca de tiempo. Tenga en cuenta que una marca de tiempo de SQL puede variar de una marca de tiempo de Java, ya que la forma en que se calcula el tiempo transcurrido desde la época no siempre es la misma, depende de las tecnologías de base de datos y también de los sistemas operativos.

Le aconsejaría que use System.currentTimeMillis () como sus marcas de tiempo, ya que se pueden procesar de manera más consistente en Java sin preocuparse por convertir las marcas de tiempo SQL en objetos de fecha de Java, etc.

Para calcular su compensación, puede intentar algo como esto:

Long gmtTime =1317951113613L; // 2.32pm NZDT
Long timezoneAlteredTime = 0L;

if (offset != 0L) {
    int multiplier = (offset*60)*(60*1000);
    timezoneAlteredTime = gmtTime + multiplier;
} else {
    timezoneAlteredTime = gmtTime;
}

Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(timezoneAlteredTime);

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");

formatter.setCalendar(calendar);
formatter.setTimeZone(TimeZone.getTimeZone(timeZone));

String newZealandTime = formatter.format(calendar.getTime());

¡Espero que esto sea útil!

Mukul Goel
fuente
@ user726478 ¿Es esto correcto cuando conocemos la cadena de zona horaria? long timezoneAlteredTime = gmtTime + TimeZone.getTimeZone ("Asia / Calcuta"). getRawOffset (); "
Kanagavelu Sugumar
4
No está bien. El desplazamiento de zona horaria no es constante. Depende de la fecha real.
Dmitry Trifonov
1
¿Cómo se obtiene una fecha real en lugar de una cadena?
Tulains Córdova
@KanagaveluSugumar aquí la compensación es horas
MI
25

Como siempre, recomiendo leer este artículo sobre fecha y hora en Java para que lo entienda.

La idea básica es que 'bajo el capó' todo se hace en milisegundos UTC desde la época. Esto significa que es más fácil si opera sin usar zonas horarias en absoluto, con la excepción del formato de cadena para el usuario.

Por lo tanto, omitiría la mayoría de los pasos que ha sugerido.

  1. Establezca la hora en un objeto (fecha, calendario, etc.).
  2. Establezca la zona horaria en un objeto formateador.
  3. Devuelve una cadena del formateador.

Alternativamente, puede usar Joda time . He oído que es una API de fecha y hora mucho más intuitiva.

Bringer128
fuente
Hola, Bringer128, gracias por tu respuesta, me parece ridículo que no haya una forma sencilla de ajustar una marca de tiempo para una zona horaria determinada. ¿Por qué incluir la funcionalidad si todo lo que hace es alterar la etiqueta de zona horaria en la cadena formateada? Probaré la hora de Joda. Gracias
travega
@travega Hay una manera simple, si representa su hora como UTC y la formatea con SimpleDateFormat. No es solo la parte 'Z' (la etiqueta de zona horaria) la que se modifica, toda la fecha sí. Verifique los resultados de tener dos objetos SimpleDateFormat diferentes con diferentes zonas horarias configuradas cuando formatean la misma fecha.
Bringer128
¿Cómo se obtiene una fecha real en lugar de una cadena?
Tulains Córdova
@ TulainsCórdova Creo que tendrás que explicarlo con más detalle. ¿Puede crear una pregunta o buscar para encontrar una pregunta relacionada que pueda resolver su pregunta específica?
Bringer128
19

tl; dr

Instant.ofEpochMilli( 1_317_816_735_000L )
    .atZone( ZoneId.of( "Pacific/Auckland" ) )
    .format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( new Locale( "en" , "NZ" ) ) )

…además…

LocalDateTime.parse( "2011-10-06 03:35:05".replace( " " , "T" ) )
    .atZone( ZoneId.of( "Pacific/Auckland" ) )

java.time

La Pregunta y la mayoría de las Respuestas utilizan clases de fecha y hora obsoletas de las primeras versiones de Java. Estas viejas clases han demostrado ser problemáticas y confusas. Evítales. En su lugar, use las clases java.time.

ISO 8601

Su cadena de entrada tiene casi el formato estándar ISO 8601. Simplemente reemplace el ESPACIO en el medio con un T.

String input = "2011-10-06 03:35:05".replace( " " , "T" );

LocalDateTime

Ahora analice como a LocalDateTimeporque la entrada carece de información sobre el desplazamiento desde UTC o la zona horaria. A LocalDateTimeno tiene concepto de desplazamiento ni de zona horaria, por lo que no representa un momento real en la línea de tiempo.

LocalDateTime ldt = LocalDateTime.parse( input );

ZoneOffset

Parece estar diciendo que, desde el contexto empresarial, sabe que la intención de esta cadena es representar un momento 13 horas antes de UTC. Así que instanciamos a ZoneOffset.

ZoneOffset offset = ZoneOffset.ofHours( 13 ); // 13 hours ahead of UTC, in the far east of the globe.

OffsetDateTime

Aplicarlo para obtener un OffsetDateTimeobjeto. Este se convierte en un momento real en la línea de tiempo.

OffsetDateTime odt = ldt.atOffset( offset);

ZoneId

Pero luego mencionas Nueva Zelanda. Así que tenías en mente una zona horaria específica. Una zona horaria es un desfase de UTC más un conjunto de reglas para manejar anomalías como el horario de verano (DST). Por tanto, podemos especificar un ZoneIda un en ZonedDateTimelugar de un simple desplazamiento.

Especifique un nombre de zona horaria adecuado . Nunca use la abreviatura de 3-4 letras como ESTo ISTya que no son zonas horarias verdaderas, no están estandarizadas y ni siquiera son únicas (!). Por ejemplo Pacific/Auckland,.

ZoneId z = ZoneId.of( "Pacific/Auckland" );

ZonedDateTime

Aplicar el ZoneId.

ZonedDateTime zdt = ldt.atZone( z );

Puede ajustarse fácilmente a otra zona para el mismo momento en la línea de tiempo.

ZoneId zParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis );  // Same moment in time, but seen through lens of Paris wall-clock time.

Contar desde la época

Recomiendo encarecidamente no manejar los valores de fecha y hora como un recuento de la época, como milisegundos desde el comienzo de 1970 UTC. Pero si es necesario, cree un a Instantpartir de ese número.

Instant instant = Instant.ofEpochMilli( 1_317_816_735_000L );

Luego asigne una zona horaria como se ve arriba, si lo desea, para alejarse de UTC.

ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = instant.atZone( z );

Tu valor de 1_317_816_735_000Les:

  • 2011-10-05T12:12:15Z (Mié, 05 de Octubre de 2011 12:12:15 GMT)
  • 2011-10-06T01:12:15+13:00[Pacific/Auckland] (Jueves 06 de octubre de 2011 01:12:15 en Auckland Nueva Zelanda).

Generar cadenas

Para generar una cadena en formato estándar ISO 8601 , simplemente llame toString. Tenga en cuenta que ZonedDateTimeprudentemente amplía el formato estándar agregando el nombre de la zona horaria entre corchetes.

String output = zdt.toString();

Para otros formatos, busque Stack Overflow para la DateTimeFormatterclase. Ya cubierto muchas veces.

Especifique ay FormatStylea Locale.

Locale l = new Locale( "en" , "NZ" );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l );
String output = zdt.format( f );

Tenga en cuenta que la zona horaria no tiene nada que ver con la configuración regional. Puede hacer que Europe/Parisse muestre una fecha y hora en el idioma japonés y las normas culturales, o una Asia/Kolkatafecha y hora en el idioma portugués y las normas culturales de Brasil.

Acerca de java.time

El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases sustituyen a las clases de fecha y hora viejas problemáticas tales como java.util.Date, .Calendar, y java.text.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.

Gran parte de la funcionalidad de java.time se ha actualizado a Java 6 y 7 en ThreeTen-Backport y se ha adaptado aún más a Android en ThreeTenABP (consulte Cómo utilizar… ).

El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y mucho más.

Albahaca Bourque
fuente
10

La solución es bastante simple (Java puro, simple):

System.out.println(" NZ Local Time: 2011-10-06 03:35:05");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localNZ = LocalDateTime.parse("2011-10-06 03:35:05",formatter);
ZonedDateTime zonedNZ = ZonedDateTime.of(localNZ,ZoneId.of("+13:00"));
LocalDateTime localUTC = zonedNZ.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime();
System.out.println("UTC Local Time: "+localUTC.format(formatter));

LA SALIDA ES:

 NZ Local Time: 2011-10-06 03:35:05
UTC Local Time: 2011-10-05 14:35:05
JS Raggio
fuente
1
Esto se resolvió hace 4 años y su solución no agrega nada nuevo.
travega
1
Creo que este es un nuevo enfoque que usa Java 8, pero la calidad de respuesta es baja.
Przemek
6

Eché un vistazo y no creo que haya una zona horaria en Java que sea GMT + 13. Así que creo que debes usar:

Calendar calendar = Calendar.getInstance();
//OR Calendar.getInstance(TimeZone.getTimeZone("GMT"));

calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY)+13);

Date d = calendar.getTime();

(Si lo hay, cambie "GMT" a esa zona horaria y elimine la segunda línea de código)

O

SimpleDateFormat df = new SimpleDateFormat();
df.setTimeZone(TimeZone.getTimeZone("GMT+13"));
System.out.println(df.format(c.getTime()));

Si desea establecer una fecha / hora específica, también puede usar:

    calendar.set(Calendar.DATE, 15);
calendar.set(Calendar.MONTH, 3);
calendar.set(Calendar.YEAR, 2011);
calendar.set(Calendar.HOUR_OF_DAY, 13); 
calendar.set(Calendar.MINUTE, 45);
calendar.set(Calendar.SECOND, 00);

fuente
1
Hola Craig, gracias por tu respuesta. Java no admite / no admite estándares de tiempo ISO GMT es un estándar de tiempo global moderado independientemente de Java. El horario / calendario Apis se adhiere al estándar y GMT + 13 se refiere al NZDT o al horario de verano en cualquier zona GMT + 12. Con respecto a su código de muestra, tengo su escenario funcionando sin ningún problema, como se menciona en mi IP. El problema al que me enfrento es definir una marca de tiempo y generar variantes precisas específicas de la zona horaria de la marca de tiempo original, NO derivaciones de la hora actual, que es lo que hace su código. Gracias T
travega
3

Podemos manejar esto usando el valor de compensación

 public static long convertDateTimeZone(long lngDate, String fromTimeZone,
        String toTimeZone){
    TimeZone toTZ = TimeZone.getTimeZone(toTimeZone);
    Calendar toCal = Calendar.getInstance(toTZ);        

    TimeZone fromTZ = TimeZone.getTimeZone(fromTimeZone);
    Calendar fromCal = Calendar.getInstance(fromTZ);
    fromCal.setTimeInMillis(lngDate);
    toCal.setTimeInMillis(fromCal.getTimeInMillis()
            + toTZ.getOffset(fromCal.getTimeInMillis())
            - TimeZone.getDefault().getOffset(fromCal.getTimeInMillis()));      
    return toCal.getTimeInMillis();
}

Fragmento de código de prueba:

 System.out.println(new Date().getTime())
 System.out.println(convertDateTimeZone(new Date().getTime(), TimeZone
                .getDefault().getID(), "EST"));

Salida: 1387353270742 1387335270742

DeepaGanesh
fuente
2

He probado este código

try{
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss Z");
            Date datetime = new Date();

            System.out.println("date "+sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

            System.out.println("GMT "+ sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("GMT+13"));

            System.out.println("GMT+13 "+ sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

            System.out.println("utc "+sdf.format(datetime));

            Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

            DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");    
            formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));  

            String newZealandTime = formatter.format(calendar.getTime());

            System.out.println("using calendar "+newZealandTime);

        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

y obteniendo este resultado

date 06-10-2011 10:40:05 +0530
GMT 06-10-2011 05:10:05 +0000 // here getting 5:10:05
GMT+13 06-10-2011 06:10:05 +1300 // here getting 6:10:05
utc 06-10-2011 05:10:05 +0000
using calendar 06 Oct 2011 18:10:05 GMT+13:00
Pratik
fuente
Hola pratik, gracias por tu entrada, pero te estás perdiendo el punto. Como se menciona en mi IP, lo tengo funcionando para una marca de tiempo actual. El problema es establecer una marca de tiempo y luego generar una salida específica de zona horaria precisa.
travega
sí, también funciona si cambias la hora. La zona horaria se estableció en el objeto de formato, por lo que la hora que pasó se basará en la zona horaria que se especificó en el objeto de formato
Pratik
Hmmmm ... He intentado agregar: datetime.setTime (Timestamp.valueOf ("2011-10-06 03:35:05"). GetTime ()); Y todavía no funciona. ¿Cómo crees que funciona cuando estableces la hora?
travega
@Pratik: ¿Cómo puedo obtener la zona horaria de AST?
Ved Prakash
2

Joda-Time

Las clases java.util.Date/Calendar son un desastre y deben evitarse.

Actualización: el proyecto Joda-Time está en modo de mantenimiento. El equipo aconseja la migración a las clases java.time.

Aquí está su respuesta usando la biblioteca Joda-Time 2.3. Muy fácil.

Como se indica en el código de ejemplo, le sugiero que utilice zonas horarias con nombre siempre que sea posible para que su programación pueda manejar el horario de verano (DST) y otras anomalías.

Si hubiera colocado un Ten el medio de su cadena en lugar de un espacio, podría omitir las dos primeras líneas de código, tratando con un formateador para analizar la cadena. El constructor DateTime puede tomar una cadena en formato ISO 8601 .

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Parse string as a date-time in UTC (no time zone offset).
DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat.forPattern( "yyyy-MM-dd' 'HH:mm:ss" );
DateTime dateTimeInUTC = formatter.withZoneUTC().parseDateTime( "2011-10-06 03:35:05" );

// Adjust for 13 hour offset from UTC/GMT.
DateTimeZone offsetThirteen = DateTimeZone.forOffsetHours( 13 );
DateTime thirteenDateTime = dateTimeInUTC.toDateTime( offsetThirteen );

// Hard-coded offsets should be avoided. Better to use a desired time zone for handling Daylight Saving Time (DST) and other anomalies.
// Time Zone list… http://joda-time.sourceforge.net/timezones.html
DateTimeZone timeZoneTongatapu = DateTimeZone.forID( "Pacific/Tongatapu" );
DateTime tongatapuDateTime = dateTimeInUTC.toDateTime( timeZoneTongatapu );

Elimina esos valores ...

System.out.println( "dateTimeInUTC: " + dateTimeInUTC );
System.out.println( "thirteenDateTime: " + thirteenDateTime );
System.out.println( "tongatapuDateTime: " + tongatapuDateTime );

Cuando se ejecuta ...

dateTimeInUTC: 2011-10-06T03:35:05.000Z
thirteenDateTime: 2011-10-06T16:35:05.000+13:00
tongatapuDateTime: 2011-10-06T16:35:05.000+13:00
Albahaca Bourque
fuente
2

mostrar fecha y hora para todas las zonas horarias

import java.util.Calendar;
import java.util.TimeZone;
import java.text.DateFormat;
import java.text.SimpleDateFormat;



static final String ISO8601 = "yyyy-MM-dd'T'HH:mm:ssZ";
DateFormat dateFormat = new SimpleDateFormat(ISO8601);
Calendar c = Calendar.getInstance();
String formattedTime;
for (String availableID : TimeZone.getAvailableIDs()) {
    dateFormat.setTimeZone(TimeZone.getTimeZone(availableID));
    formattedTime = dateFormat.format(c.getTime());
    System.out.println(formattedTime + " " + availableID);
}
Krzysztof Dziuba
fuente
1

Podemos obtener la marca de tiempo UTC / GMT de la fecha indicada.

/**
 * Get the time stamp in GMT/UTC by passing the valid time (dd-MM-yyyy HH:mm:ss)
 */
public static long getGMTTimeStampFromDate(String datetime) {
    long timeStamp = 0;
    Date localTime = new Date();

    String format = "dd-MM-yyyy HH:mm:ss";
    SimpleDateFormat sdfLocalFormat = new SimpleDateFormat(format);
    sdfLocalFormat.setTimeZone(TimeZone.getDefault());

    try {

        localTime = (Date) sdfLocalFormat.parse(datetime); 

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
                Locale.getDefault());
        TimeZone tz = cal.getTimeZone();

        cal.setTime(localTime);

        timeStamp = (localTime.getTime()/1000);
        Log.d("GMT TimeStamp: ", " Date TimegmtTime: " + datetime
                + ", GMT TimeStamp : " + localTime.getTime());

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return timeStamp;

}

Devolverá la hora UTC según la fecha pasada.

  • Podemos revertir como la marca de tiempo UTC a la fecha y hora actuales (viceversa)

        public static String getLocalTimeFromGMT(long gmtTimeStamp) {
                 try{
                        Calendar calendar = Calendar.getInstance();
                        TimeZone tz = TimeZone.getDefault();
                        calendar.setTimeInMillis(gmtTimeStamp * 1000);
        //              calendar.add(Calendar.MILLISECOND, tz.getOffset(calendar.getTimeInMillis())); 
                        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
                        Date currenTimeZone = (Date) calendar.getTime();
                        return sdf.format(currenTimeZone);
                    }catch (Exception e) {
                    }
                    return "";  
                }
    

Espero que esto ayude a otros. ¡¡Gracias!!

Jagdish
fuente
1

Una forma rápida es:

String dateText ="Thu, 02 Jul 2015 21:51:46";
long hours = -5; // time difference between places

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(E, dd MMM yyyy HH:mm:ss, Locale.ENGLISH);     
LocalDateTime date = LocalDateTime.parse(dateText, formatter);        
date = date.with(date.plusHours(hours));

System.out.println("NEW DATE: "+date);

Salida

NUEVA FECHA: 2015-07-02T16: 51: 46

Ev.
fuente
1

Su enfoque funciona sin ninguna modificación.

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
// Timestamp for 2011-10-06 03:35:05 GMT
calendar.setTime(new Date(1317872105000L));

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); 
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));

// Prints 2011-10-06 16:35:05 GMT+13:00
System.out.println(formatter.format(calendar.getTime()));
augurar
fuente
1
public Timestamp convertLocalTimeToServerDatetime(String dt,String timezone){

    String clientDnT = dt ;// "2017-06-01 07:20:00";
    try{
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = sdf.parse(clientDnT);
    TimeZone tz = TimeZone.getTimeZone(timezone.trim()); // get time zone of user
    sdf.setTimeZone(tz);

    // Convert to servertime zone 
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    TimeZone tzInAmerica = TimeZone.getDefault();
    sdf1.setTimeZone(tzInAmerica);

    // assign date to date
    String serverDate = sdf1.format(date);

    // Convert to servertime zone to Timestamp
    Date date2 =  sdf.parse(serverDate);
    Timestamp tsm = new Timestamp(date2.getTime());
    return  tsm;
    }
    catch(Exception e){
        System.err.println(e);
    }

    return null;
}
Sourav Barman
fuente
por favor pase la fecha y el cliente de zona horaria , a continuación, el servidor devuelve el método de marca de hora .. JavaScript var _timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; y en Java TimeZone tz = TimeZone.getDefault(); tz.getID()
Sourav Barman
1

Para encontrar la duración o el intervalo de tiempo con dos zonas horarias diferentes

import org.joda.time.{DateTime, Period, PeriodType}

val s1 = "2019-06-13T05:50:00-07:00"
val s2 = "2019-10-09T11:30:00+09:00"    

val period = new Period(DateTime.parse(s1), DateTime.parse(s2), PeriodType dayTime())

period.getDays
period.getMinutes
period.getHours

período de salida = P117DT13H40M

days = 117
minutes = 40
hours = 13
Abhishek Singha
fuente
1

Me gustaría dar la respuesta moderna.

Realmente no debería querer convertir una fecha y hora de una cadena en un desplazamiento GMT a una cadena en un desplazamiento GMT diferente y con un formato diferente. Más bien, en su programa, mantenga un instante (un punto en el tiempo) como un objeto de fecha y hora adecuado. Solo cuando necesite dar una salida de cadena, formatee su objeto en la cadena deseada.

java.time

Analizando la entrada

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter();

    String dateTimeString = "2011-10-06 03:35:05";
    Instant instant = LocalDateTime.parse(dateTimeString, formatter)
            .atOffset(ZoneOffset.UTC)
            .toInstant();

Para la mayoría de los propósitos, Instantes una buena opción para almacenar un punto en el tiempo. Si necesita dejar explícito que la fecha y la hora provienen de GMT, use un OffsetDateTime.

Conversión, formato e impresión de resultados

    ZoneId desiredZone = ZoneId.of("Pacific/Auckland");
    Locale desiredeLocale = Locale.forLanguageTag("en-NZ");
    DateTimeFormatter desiredFormatter = DateTimeFormatter.ofPattern(
            "dd MMM uuuu HH:mm:ss OOOO", desiredeLocale);

    ZonedDateTime desiredDateTime = instant.atZone(desiredZone);
    String result = desiredDateTime.format(desiredFormatter);
    System.out.println(result);

Este impreso:

06 de octubre de 2011 16:35:05 GMT + 13: 00

Especifiqué la zona horaria Pacífico / Auckland en lugar de la compensación que mencionaste, +13: 00. Entendí que querías la hora de Nueva Zelanda, y Pacific / Auckland mejor le dice esto al lector. La zona horaria también tiene en cuenta el horario de verano (DST), por lo que no es necesario que lo tenga en cuenta en su propio código (para la mayoría de los propósitos).

Dado que Octestá en inglés, es una buena idea darle al formateador una configuración regional explícita. GMTtambién puede estar localizado, pero creo que solo se imprime GMTen todas las configuraciones regionales.

OOOOen la cadena de patrones de formato es una forma de imprimir el desplazamiento, lo que puede ser una mejor idea que imprimir la abreviatura de la zona horaria que obtendría, zya que las abreviaturas de la zona horaria son a menudo ambiguas. Si lo desea NZDT(para el horario de verano de Nueva Zelanda), colóquelo zallí.

Tus preguntas

Responderé a sus preguntas numeradas en relación con las clases modernas en java.time.

Es posible:

  1. Establecer la hora en un objeto

No, las clases modernas son inmutables. Debe crear un objeto que tenga la fecha y hora deseadas desde el principio (esto tiene una serie de ventajas, incluida la seguridad de subprocesos).

  1. (Posiblemente) Establezca la zona horaria de la marca de tiempo inicial

El atZonemétodo que utilizo en el código devuelve un ZonedDateTimecon la zona horaria especificada. Otras clases de fecha y hora tienen un método similar, a veces llamado atZoneSameInstanto con otros nombres.

  1. Dar formato a la marca de tiempo con una nueva zona horaria

Con java.time, la conversión a una nueva zona horaria y el formateo son dos pasos distintos, como se muestra.

  1. Devuelve una cadena con la nueva zona horaria.

Sí, convierta a la zona horaria deseada como se muestra y formatee como se muestra.

Descubrí que cada vez que trato de establecer la hora de esta manera:

calendar.setTime(new Date(1317816735000L));

se utiliza la zona horaria de la máquina local. ¿Porqué es eso?

No es la forma en que piensas, lo que sirve para mostrar solo un par de los (muchos) problemas de diseño con las clases antiguas.

  • A Dateno tiene zona horaria. Solo cuando lo imprime, su toStringmétodo toma su zona horaria local y lo usa para representar la cadena. Esto también es cierto para new Date(). Este comportamiento ha confundido a muchos, muchos programadores durante los últimos 25 años.
  • A Calender tiene una zona horaria. No cambia cuando lo haces calendar.setTime(new Date(1317816735000L));.

Enlace

Tutorial de Oracle: Fecha y hora que explica cómo usar java.time.

Ole VV
fuente