Convert data to Timezone

Asked

Viewed 2,972 times

6

new Date() in Javascript returns me this format:

Tue Apr 01 2014 13:43:13 GMT-0300 (BRT)

I need to convert this to a java.util.Date. That’s what I’m trying to use SimpleDateFormat but I couldn’t find a Pattern that worked, always returns me:

java.text.Parseexception: Unparseable date: "Tue Apr 01 2014 13:43:13 GMT-0300"

4 answers

6


As you already have the identification of TimeZone correct, that in the case is the BRT you could ignore the part that has the GMT-0300, because putting GMT in format can be problematic unless it is fixed. So I propose 2 solutions.

1) Removing the GMT-0300

public static void main(String[] args) throws ParseException {
    String text = stripGMT("Tue Apr 01 2014 13:43:13 GMT-0300 (BRT)");
    String format = "EEE MMM dd yyyy HH:mm:ss  (zzz)";
    DateFormat dateFormat = new SimpleDateFormat(format);
    System.out.println(dateFormat.parse(text));
}

private static String stripGMT(String text) {
    return text.replaceAll("GMT-\\d{4}", "");
}

2) Keeping GMT as a fixed argument

public static void main(String[] args) throws ParseException {
    String text = "Tue Apr 01 2014 13:43:13 GMT-0300 (BRT)";
    String format = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z (zzz)";
    DateFormat dateFormat = new SimpleDateFormat(format);
    System.out.println(dateFormat.parse(text));
}
  • I tested here and in both is released the Exception: java.text.Parseexception

  • Oops, I installed Simpledateformat with one more parameter. I added Locale.US and it worked. I’m going to try it out a little bit.

1

In addition, there are some details that were not covered in the other answers.

For example, the day of the week and month are in English ("Tue Apr"), and by default SimpleDateFormat uses the language corresponding to default locale jvm, then it is not guaranteed that the codes suggested in another answer always work. For example, in my default locale is pt_BR (Portuguese of Brazil), then the suggested code makes an error, because it tries to do the Parsing of the names in Portuguese.

So he will always consider the names in English, independent of the JVM configuration, just inform the Locale correct in the builder of SimpleDateFormat:

String text = "Tue Apr 01 2014 13:43:13 GMT-0300 (BRT)";
String format = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z (zzz)";
// usando Locale.US (Inglês Americano)
SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.US);
System.out.println(dateFormat.parse(text));

I used Locale.US (American English), so he considers the names in English, regardless of the locale that is configured in JVM.

Another point I disagree with the other answer is about "you already have the identification of TimeZone correct, that in the case is the BRT". Actually those abbreviations like "BRT" are not standardized, and many are ambiguous: there are several of them representing more than one Timezone - see this list, we have the example of "CST" which is used in the United States, Cuba and China, or even "IST", which is used in Ireland, India and Israel. That is to say, not always (in fact almost never) it will be possible to determine the Timezone from the abbreviation.

Even in the case of "BRT", there is more than one Timezone that uses this acronym, as America/Sao_Paulo and America/Recife (the difference between them is that in many years, one adopted summer time, and the other not). It’s okay that during daylight savings the acronym changes to "BRST", but as I said, the abbreviations are ambiguous and non-standard, and anyway, there are many other timezones in Brazil, as America/Belem, America/Rio_Branco, among others, which despite using the same acronym, have different histories regarding when each adopted daylight saving or not. That is, having the abbreviation does not guarantee "the correct Timezone identification" (or you accept the default that SimpleDateFormat uses, or chooses one arbitrarily, as we will see below).

And to better understand what a Timezone is and where these names come from as America/Sao_Paulo and America/Recife, read here.


java.time

Starting with Java 8 (released 2014), it is possible to use the API java.time. The difference that this API is more flexible, and in it it is possible to configure which Timezone you want to use for abbreviation (in the case of SimpleDateFormat, it will use a value default and it is not possible to change it). This flexibility has a price, which is to have to explicitly say what we want:

String text = "Tue Apr 01 2014 13:43:13 GMT-0300 (BRT)";

// timezones usados para "desambiguar" as abreviações
Set<ZoneId> preferredZones = new HashSet<ZoneId>();
preferredZones.add(ZoneId.of("America/Sao_Paulo"));

DateTimeFormatter parser = new DateTimeFormatterBuilder()
    // data, hora e offset
    .appendPattern("EEE MMM dd uuuu HH:mm:ss 'GMT'Z (")
    // usar timezone arbitrário para abreviação
    .appendZoneText(TextStyle.SHORT, preferredZones)
    // usar locale inglês para mês e dia da semana
    .appendLiteral(')').toFormatter(Locale.US);
// faz o parsing da String
ZonedDateTime data = ZonedDateTime.parse(text, parser);
// se precisar de um java.util.Date
Date date = Date.from(data.toInstant());

One of the features of this API is that there are several different classes to represent dates and times, and you can choose the most suitable for each situation. As in this case I have the date, time and Timezone, the best option is a ZonedDateTime.

And if you specifically need a java.util.Date, the above example shows how to do the conversion.

Although it seems more laborious, this API fixes many of the problems and failures of design of Date and Calendar, then in my opinion is a job that in the end is worth it.

0

Set a date pattern in String that Javascript should pass. After that, leave it to Java. A slightly more alternative (just a little) way of doing this would be using the method setTimeZone() of DateFormat as follows:

DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
String strData = "30/05/2014 21:45";

try {
    Date data = df.parse(strData);
    System.out.println(data);
}
catch (ParseException e) {
    e.printStackTrace();
}

The exit would be:

Fri May 30 18:45:00 BRT 2014

But you may wonder, what Timezones are available for use in the method setTimeZone(). You can list all Timezones as follows:

for (String tz : TimeZone.getAvailableIDs()) {
    System.out.println(tz);
}

I will not post here the output because it is a little extensive. But I’m sure the Timezone you are looking for will be on the list.

EDIT: Complementing the response regarding Javascript. You can format the Object Date, through various methods such as getMonth(), getDate(), getMinutes()... This way you format the date as you want to send to Java. See complete object reference Date in Javascript.

-1

As in the ONLY in English

The best way to convert is by using the team in milliseconds, UTC. The Object Javascript Date and
java.util.Date support conversion using milliseconds.

  • Thanks for the help. I need to save with Timezone. I may be wrong, but I think with the milliseconds I can’t get it.

  • With milliseconds Timezone is the default UTC.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.