Cómo obtener la fecha actual y el huso horario en formato de números
Quiero imprimir la fecha actual en este formato 2017/06/05
> Year/Month/Day
y junto a él, la zona horaria actual en este formato +3
He utilizado este código
- Cómo comprobar si EditText tiene un valor en Android / Java
- Ejemplo de OpenCV Template Matching en Android
- Opciones para la comunicación del servidor cliente en Android
- ¿Cómo agregar desplazamiento a la vista cuando se cambia la orientación de la pantalla a paisaje?
- Problemas con la tarjeta SD de Android
String DateToday = DateFormat.getDateInstance().format(new Date()); String TZtoday = DateFormat.getTimeInstance().getTimeZone().getDisplayName(); txt.setText(DateToday + " | "+ TZtoday );
Pero, se muestra así:
Jun 5, 2017 | Hora estándar de Arabia
Lo quiero así:
2017/06/05 | +3
- UnsatisfiedLinkError (Método nativo no encontrado)
- Barra lateral de Android como facebook o firefox
- (OpenCV) no puede encontrar Core.line en Android Studio
- ¿Cómo puedo convertir de binario a decimal en java (usando android studio)
- Diferencia entre ActionBarSherlock y ActionBar Compatibilidad
- ¿Por qué Google eligió Java para el sistema operativo Android?
- NullPointerException con string-array en Spinner
- java.lang.NullPointer Excepción en getResources (). getString (R.string.value);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd | X"); System.out.println(sdf.format(new Date()));
se acerca, pero la zona horaria se imprime con un cero a la izquierda:
2017/06/05 | +03
Supongo que podría eliminar los ceros principales de la zona horaria, si es necesario:
SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd"); SimpleDateFormat zone = new SimpleDateFormat("ZZZZZ"); // = +03:00 String tz = zone.format(new Date()).split(":")[0] .replaceAll("^(\\+|-)0", "$1"); // = +3 System.out.println(sdf.format(new Date()) + " | " + tz);
lo que da:
2017/06/05 | +3
Sé que estás en Android, y sé que lo que se ofrece incorporado en Android son las clases anticuadas como DateFormat
, SimpleDateFormat
, Date
y Calendar
. Todavía digo, si usted está haciendo algo con fechas y / o tiempos y / o zonas horarias, usted debe considerar seriamente saltar estas clases y pasar a sus reemplazos modernos. Esto requerirá que obtenga ThreeTenABP . Entonces sugiero de esta manera:
ZonedDateTime date = ZonedDateTime.now(ZoneId.systemDefault()); String tzToday = date.format(DateTimeFormatter.ofPattern("uuuu/MM/dd | x")); tzToday = tzToday.replaceFirst("(?<=\\+|-)0", "");
Resultado en mi computadora:
2017/06/05 | +2
Resultado en la zona horaria de Asia / Katmandú puede no ser exactamente lo que quería:
2017/06/05 | +545
Usted puede pensar que mi fragmento de código no es muy ventajoso sobre el uso de las antiguas clases. Usted puede tomar mi palabra cuando digo que hay tantos casos donde las clases viejas le dan sorpresas negativas, por lo que cuanto antes pueda empezar a usar los nuevos, mejor. O puede hacer un error tipográfico en la cadena de patrón de formato, por ejemplo, y observe cómo obtiene un resultado sorprendente con las clases antiguas sin signo de que algo está mal, mientras que las más nuevas intentarán juntar un mensaje de error significativo.
Otro detalle a tener en cuenta es que estoy leyendo el reloj del sistema y la zona horaria de JVM sólo una vez (pasando la zona horaria de nuevo a now()
para asegurarse de que se utiliza para el tiempo). Su código en la pregunta formatea la fecha primero, luego lee la zona horaria. Si alguien cambia la zona horaria entre los dos, el resultado será inconsistente. Muy poco probable, pero esto también significa que será muy poco probable que alguien será capaz de averiguar lo que pasó.
El (?<=\\+|-)
en la expresión regular es un lookbehind: Estoy reemplazando un 0
precedido por +
o -
con la cadena vacía. Busqué en vano una forma de formatear el desplazamiento de la zona como +3
como replaceFirst
, así que recurrí al método replaceFirst
.
Enlace adicional: Cómo utilizar ThreeTenABP en Android Project .
Simplemente complementando la respuesta de @Ole VV , he encontrado otra forma de hacerlo usando ThreeTenABP , pero sin necesidad de un reemplazo de regex (aunque no creo que sea mucho más simple, más sobre eso a continuación).
Utilizando el DateTimeFormatterBuilder
puede utilizar un HashMap
que asigna los valores de los desplazamientos a una String
. Por lo tanto, para horas completas de desplazamiento (como +03:00
), puede asignar el valor respectivo a la cadena +3
y así sucesivamente.
El único problema es que el ZoneOffset
tiene precisión segundos . Y los valores mínimo y máximo son, respectivamente, UTC-18:00:00
y UTC+18:00:00
. Así que todos los valores posibles son UTC-18:00:00
, UTC-17:59:59
, UTC-17:59:58
y así sucesivamente. Y el formateador requiere que todos los valores posibles se asignen (de lo contrario, mostrará el valor de los segundos del offset), por lo que el mapa tendrá más de 120K entradas!
Para construir este mapa, he hecho 2 bucles:
- El primer bucle mapea los desplazamientos de toda la hora (
+01:00
a+1
,-02:00
a-2
y así sucesivamente) - El segundo bucle mapea todos los otros valores (permanecen sin cambios):
- horas enteras> = 10 (como
+10:00
) - no-horas enteras (como
+05:30
)
- horas enteras> = 10 (como
El código para crear el formateador:
// builds a hashmap to map all offset values Map<Long, String> map = new HashMap<>(); // First loop: Map whole hours from 1 to 9 and from -9 to -1 // So a "+01:00" offset is displayed as "+1" for (int i = 1; i <= 9; i++) { long seconds = ZoneOffset.ofHours(i).getTotalSeconds(); // 1 hour offset maps to "+1" and so on map.put(seconds, "+" + i); // -1 hour offset maps to "-1" and so on map.put(-seconds, "-" + i); } // second loop: Need to map all other possible values for not-whole hours // offsets like "+10:00" and "+01:30" are not changed int minOffset = ZoneOffset.MIN.getTotalSeconds(); int maxOffset = ZoneOffset.MAX.getTotalSeconds(); for (long i = minOffset; i <= maxOffset; i++) { // the map already contains whole hours, don't need to overwrite the values if (!map.containsKey(i)) { // uses default String representation (like "+05:30") map.put(i, ZoneOffset.ofTotalSeconds((int) i).getId()); } } // create the formatter DateTimeFormatter formatter = new DateTimeFormatterBuilder() // year/month/day and the "|" .appendPattern("uuuu/MM/dd | ") // use the map of custom values (offset will use the values in the map) .appendText(ChronoField.OFFSET_SECONDS, map) // create formatter .toFormatter();
Algunas pruebas:
LocalDateTime dt = LocalDateTime.of(2017, 5, 1, 10, 0); ZonedDateTime z = ZonedDateTime.of(dt, ZoneId.of("America/Sao_Paulo")); // UTC-03:00 System.out.println(formatter.format(z)); // 2017/05/01 | -3 // just picking some timezone in Arabia Stardard Time // (there are more than one timezone in AST: https://en.wikipedia.org/wiki/UTC%2B03:00#Arabia_Standard_Time) // I don't know in which one you are z = ZonedDateTime.of(dt, ZoneId.of("Asia/Qatar")); // UTC+03:00 System.out.println(formatter.format(z)); // 2017/05/01 | +3 // 2-digit offset z = ZonedDateTime.of(dt, ZoneId.of("Asia/Vladivostok")); // UTC+10:00 System.out.println(formatter.format(z)); // 2017/05/01 | +10:00 // not whole hour z = ZonedDateTime.of(dt, ZoneId.of("Asia/Kathmandu")); // UTC+05:45 System.out.println(formatter.format(z)); // 2017/05/01 | +05:45
La salida es:
2017/05/01 | -3
2017/05/01 | +3
2017/05/01 | +10: 00
2017/05/01 | +05: 45
Notas:
- No sé si tener un mapa de 120K-entradas es mejor que usar expresiones regulares (depende de usted decidir). Este enfoque crea un mapa grande, pero al menos no requiere la salida de post-procesamiento (no estoy seguro si eso es un trade-off razonable)
- Si desea que las compensaciones de hora entera> = 10 se muestren como
+10
,+11
y así sucesivamente, simplemente cambie la primerafor
bucle afor (int i = 1; i <= maxOffsetYouWant; i++)
– recordando que el máximo valor posible paramaxOffsetYouWant
es 18 .
Utilice la siguiente lógica para obtener el formato de fecha deseado.
public static void main(String[] args) { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, 1); SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd"); System.out.println(cal.getTime()); // Output "Wed Sep 26 14:23:28 EST 2012" String formatted = format1.format(cal.getTime()); String formattedmain=formatted.replace("-","/"); System.out.println(formatted); // Output "2012-09-26" System.out.println(formattedmain); //Output :- 2017/06/06 }