obtener - Obtén la fecha en la zona horaria actual en java
set zona horaria java (4)
He estado buscando en la red durante las últimas horas para obtener la fecha y hora en mi zona horaria del sistema.
Cuando uso calendar.getTimezone.getDefaultName siempre me devuelve GMT. (idealmente, debería devolver mi zona horaria actual, que es IST). Estoy tratando de convertir esta cadena "2014-02-14T06: 04: 00: 00", que está en GMT a la zona horaria de mi zona horaria. Siempre me devuelve el mismo tiempo en GMT.
Todo lo que veo es que todos están sugiriendo usar la Zona horaria. es decir,
dateFormatter.setTimezone("any_arbitary_timezone");
Punto es mi aplicación será utilizada en diferentes ubicaciones geográficas. No puedo establecerlo en una zona horaria particular. Debe establecerse en la zona horaria del sistema, de modo que pueda mostrarse en cualquier zona horaria en la que el usuario se encuentre actualmente
tl; dr
Usa las clases modernas de java.time .
ZonedDateTime.now( // Capture the current moment in the wall-clock time used by the people of a certain region (a time zone).
ZoneId.systemDefault() // Get the JVM’s current default time zone. Can change at any moment during runtime. If important, confirm with the user.
) // Renders a `ZonedDateTime` object. To see the same moment in UTC, extract a `Instant` object by calling `ZonedDateTime::getInstant`.
Puede omitir la llamada explícita a ZoneId.systemDefault
.
ZonedDateTime.now() // Capture the current moment in the JVM’s current default time zone.
Analice su cadena como LocalDateTime
y LocalDateTime
a la zona horaria deseada.
LocalDateTime.parse( "2014-02-14T06:04:00:00" ) // Parse a string lacking any indicator of time zone or offset-from-UTC. *Not* a specific point on the timeline.
.atOffset( ZoneOffset.UTC ) // Apply UTC as we are certain that offset-from-UTC of zero was intended by the supplier of that input string. Returns a `OffsetDateTime` object.
.atZoneSameInstant( // Adjust into another time zone. The `sameInstant` part means the same moment, different wall-clock time.
ZoneId.of( "Africa/Tunis" ) // Specify the particular zone of interest to you.
) // Returns a `ZonedDateTime` object.
Evite java.util.Date
& .Calendar
Estas clases heredadas son notoriamente problemáticas. Sun / Oracle agregó el paquete java.time en Java 8 para suplantarlos. Ese paquete fue inspirado por Joda-Time .
Entre los problemas de las clases heredadas se encuentra este comportamiento confuso: mientras que java.util.Date no tiene información de zona horaria, su implementación toString
aplica la zona horaria predeterminada actual de la JVM al generar una Cadena. Así que te engaña al parecer que tiene una zona horaria cuando no lo tiene.
java.time
Estoy tratando de convertir esta cadena "2014-02-14T06: 04: 00: 00", ...
Su cadena de entrada carece de cualquier indicador de zona horaria o offset-from-UTC. Así que analizamos como LocalDateTime
, que carece de cualquier concepto de zona / desplazamiento.
Un LocalDateTime
no representa un momento, no es un punto en la línea de tiempo. La palabra "Local" aquí no significa una localidad específica. Significa "ninguna localidad específica en absoluto". Sin el contexto de una zona / desplazamiento, no tiene un significado real.
LocalDateTime ldt = LocalDateTime.parse( "2014-02-14T06:04:00:00" ) ;
... que está en GMT ...
Usted dice que está seguro de que el proveedor de esa cadena de entrada pretende UTC como el contexto. Podemos aplicar un offset-from-UTC de cero, o UTC, para obtener un objeto OffsetDateTime
. Un OffsetDateTime
es un momento, un punto en la línea de tiempo. Podemos especificar el ZoneOffset
usando la constante para UTC, ZoneOffset.UTC
.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
… A mi hora horaria
Al parecer, desea ajustar ese momento en otra zona horaria, para ver la hora del reloj de pared utilizada por las personas de una región en particular. Necesitamos aplicar una zona horaria ( ZoneId
) para obtener un ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.atZone( z ) ;
En lugar de especificar una zona horaria, puede solicitar a su JVM su zona horaria predeterminada actual. Cuidado: la zona horaria predeterminada actual de la JVM se puede cambiar en cualquier momento por cualquier código en cualquier subproceso de cualquier aplicación dentro de esa JVM.
ZoneId z = ZoneId.systemDefault() ;
ZonedDateTime zdt = odt.atZone( z ) ;
Punto es mi aplicación será utilizada en diferentes ubicaciones geográficas.
Simplemente especifique sus zonas horarias deseadas / esperadas explícitamente. Esta es siempre una buena práctica, en mi opinión. La zona horaria predeterminada queda fuera de su control como programador, lo que lo hace poco confiable.
Especifique un nombre de zona horaria adecuado en el formato de continent/region
, como America/Montreal
, Africa/Casablanca
o Pacific/Auckland
. Nunca use la abreviatura de 3 a 4 letras, como EST
o IST
ya que no son zonas horarias verdaderas, no están estandarizadas y ni siquiera son únicas (!).
Otro consejo: trabajar, pensar, almacenar e intercambiar en UTC. Olvídese de su propia zona horaria parroquial, ya que la traducción de ida y vuelta a su zona de origen lo volverá loco. Piense en UTC como el One True Time , y otras zonas / compensaciones no son más que meras variaciones.
Instant instant = Instant.now() ; // Capture current moment in UTC.
ZoneId zAuckland = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdtAuckland = instant.atZone( zAuckland ) ;
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtKolkata = instant.atZone( zKolkata ) ;
ZoneId zCasablanca = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdtCasablanca = instant.atZone( zCasablanca ) ;
Ahí tenemos cuatro formas ( instant
, zdtAuckland
, zdtKolkata
, zdtCasablanca
) de mirar el mismo momento simultáneo, el mismo punto en la línea de tiempo.
instant.toString (): 2018-05-08T20: 55: 14.761721Z
zdtAuckland.toString (): 2018-05-09T08: 55: 14.761721 + 12: 00 [Pacífico / Auckland]
zdtKolkata.toString (): 2018-05-09T02: 25: 14.761721 + 05: 30 [Asia / Calcuta]
zdtCasablanca.toString (): 2018-05-08T21: 55: 14.761721 + 01: 00 [África / Casablanca]
Zona vs Offset
Un desplazamiento desde UTC es simplemente una cantidad de horas, minutos y segundos. Nada más y nada menos. Cualquier número de zonas horarias puede compartir un desplazamiento particular en un momento particular.
Una zona horaria es una historia de cambios pasados, presentes y futuros en la compensación utilizada por las personas de una región en particular. Por ejemplo, el horario de verano es una práctica en la que las personas de una región (de manera inexplicable) deciden cambiar su compensación dos veces al año.
Por lo tanto, una zona horaria siempre es preferible a un simple desplazamiento. Tener una zona nos permite sumar o restar el tiempo de una manera significativa, para tener en cuenta los cambios en el desplazamiento en el historial de esa región.
Acerca de java.time
El marco java.time está integrado en Java 8 y java.time posteriores. Estas clases sustituyen a las antiguas y problemáticas clases 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 las clases java.time .
Para obtener más información, consulte el Tutorial de Oracle . Y busca para muchos ejemplos y explicaciones. La especificación es JSR 310 .
Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No se necesitan cadenas, no se necesitan clases java.sql.*
.
¿Dónde obtener las clases java.time?
- Java SE 8 , Java SE 9 , Java SE 10 y posteriores
- Incorporado.
- Parte de la API de Java estándar con una implementación en paquete.
- Java 9 agrega algunas características menores y correcciones.
- Java SE 6 y Java SE 7
- Gran parte de la funcionalidad de java.time está respaldada a Java 6 y 7 en ThreeTen-Backport .
- Android
- Versiones posteriores de las implementaciones de paquetes de Android de las clases java.time.
- Para Android anterior (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Vea Cómo usar ThreeTenABP… .
El proyecto ThreeTen-Extra extiende 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 more .
Tiempo de joda
ACTUALIZACIÓN: El proyecto Joda-Time está ahora en modo de mantenimiento. El equipo aconseja la migración a las clases java.time. Salta a la sección java.time más abajo en esta respuesta.
El paquete Joda-Time tiene un buen soporte claro para las zonas horarias. A diferencia de java.util.Date, un Joda-Time DateTime sabe su propia zona horaria asignada. Si no especifica una zona horaria, la zona horaria predeterminada actual de la JVM se asigna implícitamente.
DateTime dateTime = DateTime.now(); // Applies JVM’s default time zone implicitly.
Recomiendo no confiar en la zona horaria predeterminada de forma implícita. Hacerlo lleva a confusión y errores al realizar el trabajo de fecha y hora.
DateTime dateTime = DateTime.now( DateTimeZone.getDefault() ); // Explicitly using default time zone.
Si es necesario, puede asignar una zona horaria.
DateTime dateTimeKolkata = DateTime.now( DateTimeZone.forID( "Asia/Kolkata" ) ); // Specify a time zone.
Para el trabajo del lado del servidor, la mejor práctica es hacer lógica de negocios y almacenamiento de base de datos en UTC .
DateTime dateTimeUtc = DateTime.now( DateTimeZone.UTC ); // Assign UTC (GMT) time zone.
Puede convertir de la zona horaria asignada a otra, incluida la zona horaria predeterminada actual de la JVM.
DateTime dateTime = dateTimeUtc.withZone( DateTimeZone.getDefault() );
Inmutable
Para la seguridad de los hilos, Joda-Time utiliza objetos inmutables . En lugar de modificar un objeto, los métodos como withZone
crean una nueva instancia basada en el original.
Cadena de análisis
Para analizar una cadena como DateTime, debe tener en cuenta si la cadena incluye un desplazamiento de UTC y / o una zona horaria. El tuyo no. Por lo tanto, debe especificar una zona horaria para interpretar esa cadena. Si no especifica, la zona horaria predeterminada actual de la JVM se utilizará durante el análisis.
En su Pregunta, usted dijo que la Cadena representa una fecha y hora en UTC ( GMT ).
DateTime dateTimeUtc = new DateTime( "2014-02-14T06:04:00:00", DateTimeZone.UTC );
Después de analizar, puede asignar otra zona horaria si es necesario. Mismo momento en la línea de tiempo del Universo, pero muestra una hora de reloj de pared diferente.
DateTime dateTimeDefaultZone = dateTimeUtc.withZone( DateTimeZone.getDefault() );
Así que note que esto fue un proceso de dos pasos. Primero analizamos su Cadena utilizando nuestro conocimiento externo de la zona horaria prevista de esa Cadena porque carecía de representación interna de esa zona horaria o desplazamiento. En segundo lugar, ajustamos la zona horaria a otra (la zona predeterminada de JVM).
Si su String hubiera incluido un desplazamiento de +00:00
o la Z
habitual, podríamos haber colapsado esos dos pasos en uno.
DateTime dateTimeDefaultZone = new DateTime( "2014-02-14T06:04:00:00Z", DateTimeZone.getDefault() ); // Apply time zone adjustment *after* parsing.
Tenga en cuenta que este constructor DateTime se parece al de arriba, pero en realidad es bastante diferente. Este argumento de zona horaria se aplica después del análisis, en lugar de durante el análisis. Aquí el argumento de la zona horaria se usa para ajustar el DateTime ya analizado. Esa Z
al final hace un mundo de diferencia.
Fuente de la zona horaria predeterminada
La JVM inicialmente obtiene su zona horaria predeterminada del sistema operativo host. Pero tenga en cuenta que un programador puede anular esto al:
- Pase un argumento en la línea de comandos cuando inicie la JVM.
- Llame a
java.util.TimeZone.setDefault
.
Hacer esta anulación afecta a todos los subprocesos de todas las aplicaciones que se ejecutan en esa JVM. Por lo tanto, debe saber que la zona horaria predeterminada de la JVM suele ser la misma que la del sistema operativo host, pero no necesariamente la misma.
Aquí hay una manera de obtener la identificación de un TimeZone
que coincida con la compensación del reloj de su sistema local,
Calendar cal = Calendar.getInstance();
long milliDiff = cal.get(Calendar.ZONE_OFFSET);
// Got local offset, now loop through available timezone id(s).
String [] ids = TimeZone.getAvailableIDs();
String name = null;
for (String id : ids) {
TimeZone tz = TimeZone.getTimeZone(id);
if (tz.getRawOffset() == milliDiff) {
// Found a match.
name = id;
break;
}
}
System.out.println(name);
Creo que lo que estás buscando es la biblioteca de Joda . Tiene una funcionalidad mejor que las clases de Calendario o Fecha como se especifica en la respuesta here .
Esta función debería ser particularmente útil.
private String receivedFormat = "yyyy-MM-dd''T''HH:mm:ss", expectedFormat = "dd-MM-yyyy HH:mm:ss"; //Globall variables
//Write these three lines in your Test Class and below 2 methods
String dateString = "2018-08-14T07:00:00:00";
String returnString = correctDateFormat(dateString, receivedFormat, expectedFormat);
String result = getTimeInSelectedLocale(returnString);
Log.i("Ayaz", "Date: " +result);
/**
* @param receivedDate
* @param givenFormat
* @param expectedFormat
* @return returns date time in expected format
*/
public static String correctDateFormat(String receivedDate, String givenFormat, String expectedFormat) {
if (TextUtils.isEmpty(receivedDate)) {
return "";
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(givenFormat);
Date newDate = null;
try {
newDate = simpleDateFormat.parse(receivedDate);
} catch (ParseException e) {
e.printStackTrace();
}
simpleDateFormat = new SimpleDateFormat(expectedFormat);
receivedDate = simpleDateFormat.format(newDate);
return receivedDate;
}
/**
* @param dateString
* @return passed string date in different locale, My Db is in IST so I an converting IST in different locale
*/
public String getTimeInSelectedLocale(String dateString) {
if (TextUtils.isEmpty(dateString)) {
return dateString;
}
SimpleDateFormat sdf = new SimpleDateFormat(expectedFormat);
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata")); //We want Indian time to change in different locale, so this line is compulsory, you can replace with your country
Date date1 = null;
try {
date1 = sdf.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
//below this line -> TimeZone.getTimeZone(TimeZone.getDefault().getID(), will return current locale for example for India "Asia/Kolkata" for UAE "Asia/Dubai"
sdf.setTimeZone(TimeZone.getTimeZone(TimeZone.getDefault().getID())); //This line chooses current local in which you want time
String localDate = sdf.format(date1);
return localDate;
}
//I am converting the IST time "2018-08-14T07:00:00:00" into UAE(Duabai) "14-08-2018 05:30:00" and other countries