0

How to parse a Java TDate ? i want to parse this into a java Date object. The date value is 2011-11-22T00:00:00-06:00

BlackberryChennai
  • 436
  • 1
  • 5
  • 18

2 Answers2

4

You can use a SimpleDateFormat:

DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
// Set time zone, locale etc

Date date = format.parse(text);

Personally I would strongly recommend that you use Joda Time instead of the built-in Java types, but that's a separate discussion...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • +1: For using JodaTime; I believe the `T` needs to be in single quotes `'T'` And you need a timezone. – Peter Lawrey Oct 20 '11 at 16:19
  • I get `java.lang.IllegalArgumentException: Illegal pattern character 'T'` – Peter Lawrey Oct 20 '11 at 16:38
  • Sorry, it’s wrong. This code doesn’t parse the offset, `-06:00 ` and instead uses the default time zone of the JVM most likely giving an incorrect time. See the correct answer by Arvind Kumar Avinash. And please for your own sake prefer using java.time. – Ole V.V. Jun 10 '21 at 10:03
  • 1
    @OleV.V.: My *guess* is that the question was edited within the first 5 minutes (hence no history) but after I'd written the answer. I agree it doesn't match the value specified in the question, and I think I'd have spotted that. As for preferring java.time - I completely agree, but this was written in 2011... – Jon Skeet Jun 10 '21 at 10:10
0

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*, released in March 2014.

Solution using java.time, the modern Date-Time API:

The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.

Since your Date-Time string, 2011-11-22T00:00:00-06:00 already conforms to ISO 8601 Date-Time format with timezone offset, you can parse it directly to OffsetDateTime.

Demo:

import java.time.OffsetDateTime;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = OffsetDateTime.parse("2011-11-22T00:00:00-06:00");
        System.out.println(odt);
    }
}

Output:

2011-11-22T00:00-06:00

ONLINE DEMO

Learn more about the modern Date-Time API from Trail: Date Time.

Some important notes:

  1. If you are going to deal with JDBC, check this answer and this answer.
  2. If you need to convert this object of OffsetDateTime to an OffsetDateTime object with a different ZoneOffset, you can do so by using OffsetDateTime#withOffsetSameInstant e.g.
OffsetDateTime odtWithOffsetTwoHours = odt.withOffsetSameInstant(ZoneOffset.of("+02:00"));
OffsetDateTime odtInUtc = odt.withOffsetSameInstant(ZoneOffset.UTC);
  1. For any reason, if you need to convert this object of OffsetDateTime to an object of java.util.Date, you can do so as follows:
Date date = Date.from(odt.toInstant());

Solution using the legacy Date-Time API:

As I have already mentioned, you should try your best to avoid the error-prone legacy API. Just for the sake of completeness, I have written below the solution using the legacy API.

Since your Date-Time string has a timezone offset of -06:00, a correct format to parse it would be

y-M-d'T'H:m:sXXX

Note that for parsing, a single y can cater to both two-digit as well as four-digit representation of the year. Similarly, a single m can cater to both single-digit and two-digit month. Other fields also behave in a similar fashion.

Demo:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("y-M-d'T'H:m:sXXX", Locale.ENGLISH);
        Date date = sdf.parse("2011-11-22T00:00:00-06:00");
        // Display in the default format i.e. the value of date#toString
        System.out.println(date);

        // #################Display in custom format and timezone#################
        // At timezone offset of -06:00 hours
        sdf.setTimeZone(TimeZone.getTimeZone("GMT-06:00"));
        System.out.println(sdf.format(date));
        
        // In UTC
        sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
        System.out.println(sdf.format(date));

        // In New York
        sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
        System.out.println(sdf.format(date));
    }
}

Output:

Tue Nov 22 06:00:00 GMT 2011
2011-11-22T0:0:0-06:00
2011-11-22T6:0:0Z
2011-11-22T1:0:0-05:00

ONLINE DEMO

Note that a java.util.Date object is not a real Date-Time object like the modern Date-Time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). Since it does not hold any format and timezone information, it applies the format, EEE MMM dd HH:mm:ss z yyyy and the JVM's timezone to return the value of Date#toString derived from this milliseconds value. If you need to print the Date-Time in a different format and timezone, you will need to use a SimpleDateFormat with the desired format and the applicable timezone as demonstrated using the code above.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110