Convert String with date to Datetime in Java

Asked

Viewed 7,105 times

5

I have a CSV file and in it has a column with String:

"Sun Oct 05 20:59:57 BRT 2014"

I need to pass the CSV data to a Mysql table. Therefore, I need to convert this string to Datetime format so I can insert this string as a Datetime in Mysql.

How to make this conversion?

  • 1

    You’ve tried something before and made a mistake?

3 answers

10


The first thing you need to do is look at the date formatting documentation. You can do this by looking at the documentation for Simpledateformat. Below, the meaning only of the patterns that will be needed in our case:

  • E: name of the day in the week;
  • M: month of the year;
  • d: day of the month
  • H: time of day, from 0 to 24, we will use HH;
  • m: minute in time, being mm;
  • s: second in the minute, being ss;
  • z: time zone;
  • y: year, in your case as it is represented with 4 digits, we need to use yyyy;

Then we would generate the following pattern:

EEE MMM d HH:mm:ss zzz yyyy

Beyond this pattern, when creating the Simpledateformat we will need to inform the locale, because by default is recovered the locale standard for formatting (Locale.getDefault(Locale.Category.FORMAT)). In the pattern we could use any locale of the English language, as below:

final DateFormat df = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy", Locale.ENGLISH);

A complete example generating a Date instance would look like this:

final String dateStr = "Sun Oct 05 20:59:57 BRT 2014";
final DateFormat df = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy", Locale.ENGLISH);
final Date date = df.parse(dateStr);
// faça o que for preciso com "date"

With a Date in hand you can insert it into the bank, for example building a Timestamp from him:

final Timestamp ts = new Timestamp(date.getTime());

5

Basically you need to parse datetime, like this example:

public void Dados(String dado) {  // Obtem o time em Wed, etc..
    try {  
        this.dado = new SimpleDateFormat("dd/MM/yyyy")  
                          .format(new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy", Locale.US).parse(dado));  // Faz o Parser de resposta

To get the team with days of the week in PT-BR remove the ', Locale.US), so the script will get Timezone of the request made.

A String must have the name of the day in the set language, For example in BRT: Wed, Fri, Sab

Otherwise the 'z' can be removed and the Timezone already set in the script, Making the request normally seen as the Timezone Value;

As for example using: a = Timezone.getTimeZone("BRT")

If not set, a locale will be used to assign to another Timezone the value of the team.

Reference: http://www.guj.com.br/java/245280-resolvido-erro-ao-converter-string-para-data

1

Just to update the answers (which are not wrong), from Java 8 you can use the API java.time to manipulate dates.

This API works in a similar way, but there is some important differences in relation to Date and SimpleDateFormat. The main one is that there are fewer implicit behaviors (many common with SimpleDateFormat) and so the first impression is that it is more "complicated" by requiring a greater understanding of how the dates work.

For example, the abbreviation of Timezone ("BRT", which corresponds to "Brasília Time" - the famous Time of Brasilia) is an ambiguous information. Therefore the abbreviations are not considered timezones in fact, precisely because they are not standardized and there is a lot of ambiguity. Examples include "IST", which is used in India, Ireland and Israel, or "CST", which is used in China, Cuba and the United States.

Because they have many ambiguous abbreviations, it is not always possible to obtain a single corresponding Timezone. The only way to not have an ambiguous Timezone is to use the nomenclature of IANA. The abbreviation BRT, for example, corresponds to Timezone America/Sao_Paulo (the IANA uses the name of the continent and the region’s most populous city to name the timezones), but also corresponds to America/Recife, which during part of the year is equal to America/Sao_Paulo, but it’s different during summer time - in fact, during summer time the abbreviation changes to BRST (Brasilia Summer Time), but only in states that follow the same rules of America/Sao_Paulo. Those who follow America/Recife continues to be BRT, as these do not have summer time (according to current rules).

As they present these differences during the year, IANA considers that America/Sao_Paulo and America/Recife are two different timezones. The fact that they have the same time - and the same abbreviation - for part of the year is just a detail.

Anyway, I just said all this because SimpleDateFormat simply assume some Timezone when an abbreviation is passed (and in cases of ambiguity there is no way to control which will be used). Already in the new API we have to specify which Timezone we want to use.


Another difference is that there are several different types to represent dates: one only with the day, month and year, another only with the time, another with date, time and Timezone, etc. So one should choose the appropriate type according to the data you are working on.

In this case, the input string has date, time and Timezone, so the type indicated is java.time.ZonedDateTime. To transform the string into a date, use a java.time.format.DateTimeFormatter. And to configure the Timezone to be used (because the abbreviation is ambiguous and we should set a Timezone), we use a java.time.format.DateTimeFormatterBuilder.

To set the Timezone, use a java.time.ZoneId with the name of Timezone in the format of IANA. It is possible to pass several timezones, so these are placed in a java.util.Set:

// timezone a ser usado para a abreviação
Set<ZoneId> zones = new HashSet<>();
zones.add(ZoneId.of("America/Sao_Paulo"));

// criar o DateTimeFormatter
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // data e hora
    .appendPattern("EEE MMM dd HH:mm:ss ")
    // abreviação do timezone (usar java.time.format.TextStyle)
    .appendZoneText(TextStyle.SHORT, zones)
    // ano
    .appendPattern(" uuuu")
    // usar locale inglês para o dia da semana e mês
    .toFormatter(Locale.ENGLISH);
// transformar a string em data
ZonedDateTime datetime = ZonedDateTime.parse("Sun Oct 05 20:59:57 BRT 2014", fmt);

Notice I used the java.util.Locale corresponding to the English language, because the day of the week and the month are in English. If you do not specify a locale, the configuration will be used default JVM, and may not always be the language you need. It is best to set locale if you already know which language is used.

To better understand what letters are EEE MMM ..., see the documentation. A lot of attention because not everything is equal to SimpleDateFormat. Some letters work the same way, others in a similar way, others in a completely different way, etc.


To save in bank, you can convert to a java.sql.Timestamp, for example. In Java 8 conversion methods have been added for ease. The method from gets a java.time.Instant, which may be obtained from ZonedDateTime using the method toInstant():

// converter para java.sql.Timestamp
Timestamp ts = Timestamp.from(datetime.toInstant());

And to convert back to ZonedDateTime, we use the method toInstant(), that returns a Instant, and then the method atZone, that converts the Instant for the Timezone indicated:

// converter Timestamp para ZonedDateTime
ZonedDateTime zdt = ts.toInstant().atZone(ZoneId.of("America/Sao_Paulo"));

And you can get the original string using the same DateTimeFormatter to format the date:

String dateStr = zdt.format(fmt);

If the bank you are using has a driver compatible with the JDBC 4.2, it is possible to work directly with the Instant, using the methods setObject class java.sql.PreparedStatement and getObject class java.sql.ResultSet:

PreparedStatement ps = ...
// seta o java.time.Instant
ps.setObject(1, datetime.toInstant());

// obter o Instant do banco
ResultSet rs = ...
Instant instant = rs.getObject(1, Instant.class);
// converter o instant para o timezone
ZonedDateTime zdt = instant.atZone(ZoneId.of("America/Sao_Paulo"));

Browser other questions tagged

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