3

I'm trying to modify some code to use Joda-Time rather than java.sql.Timestamp

Currently the code is using Threadlocal and SimpleDateFormat:

 public static final ThreadLocal<DateFormat> FORMAT_TIMESTAMP = new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
        return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
    }
};

public static String format(Timestamp timestamp) {
    return FORMAT_TIMESTAMP.get().format(timestamp);
}

My understanding is that Joda-time is thread safe, so there is no need to use ThreadLocal

With this in mind I have modified the code to this:

 public static String format(Instant timestamp) {

    Instant formated = Instant.parse(timestamp.toString(), DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssXXX"));

    return formated.toString();
}

If I nned to insert the values into a DB later in the code I plan to use this method.

Assuming I'm going about this the right way, is there anyway to format the DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssXXX") like the

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")

At the moment I'm getting a Invalid format Exception

JTK
  • 1,469
  • 2
  • 22
  • 39
  • I don't understand. In your first example, you are `format`ting a `Timestamp`. In your second example you are attempting to parse the `String` created by `Timestamp#toString` into an `Instant` instance and then return the `Instant#toString` result (which might be different from your `DateTimeFormat`'s format. `DateTimeFormat` does not have a `X` pattern character. Just use `DateTimeFormat#print(timestamp.getTime())`. I didn't notice `timestamp` was a `Instant` in your second example. What happened to `Timestamp`? – Sotirios Delimanolis Dec 17 '15 at 15:37
  • Sorry that was a silly mistake on my part – JTK Dec 17 '15 at 15:39

2 Answers2

3

X is not recognised by Joda. Replacing the XXX by ZZ should do what you need.

Because DateTimeFormat is thread safe, you can share it across threads. So your code could look like this:

private static final DateTimeFormatter FORMAT_TIMESTAMP =
                                      DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ");

public static String format(Instant timestamp) {
    return FORMAT_TIMESTAMP.print(timestamp);
}
assylias
  • 321,522
  • 82
  • 660
  • 783
1

tl;dr

  • No need to define the formatting pattern for standard inputs.
  • Parse directly into java.time objects.

Examples…

// offset-from-UTC
OffsetDateTime.parse( "2016-01-23T12:34:56.123456789-07:00" ) 

// Z = Zulu = UTC
Instant.parse( "2016-01-23T12:34:56.123456789Z" )  

// ISO 8601 format extended with time zone name appended in square brackets.
ZonedDateTime.parse( "2016-01-23T12:34:56.123456789-05:30[Asia/Kolkata]" )  

Details

The Joda-Time project, now in maintenance mode, advises migration to java.time classes.

java.time

No need for ThreadLocal as the java.time classes are inherently thread-safe because of they are immutable objects.

The standard ISO 8601 formats for date-time values are used by default in the java.time classes. So generally no need to specify a formatting pattern for such inputs.

Instant

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

The Instant.parse method can parse standard input strings ending in Z, short for Zulu, meaning UTC.

Instant instant = Instant.parse( 
    "2016-01-23T12:34:56.123456789Z" );

OffsetDateTime

For standard input strings that include a specific offset-from-UTC, use the OffsetDateTime class and its parse method.

OffsetDateTime odt = OffsetDateTime.parse( 
    "2016-01-23T12:34:56.123456789-07:00" );

ZonedDateTime

The ZonedDateTime class with its toString method generates a String in a format that extends beyond the ISO 8601 format by appending the name in square brackets. This is wise, as a time zone is much more than an offset-from-UTC. A time zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).

This class can parse as well as generate such strings.

ZonedDateTime zdt = ZonedDateTime.parse( 
    "2016-01-23T12:34:56.123456789-05:30[Asia/Kolkata]" ) ;

DateTimeFormatter

For non-standard string formats, search Stack Overflow for java.time.format.DateTimeFormatter class.

Database

To send this value to a database through a JDBC driver supporting JDBC 4.2 or later, use the PreparedStatement::setObject method and for fetching, the ResultSet::getObject method.

myPreparedStatement.setObject( … , instant );

If your driver does not comply, fall back to converting to the old java.sql types. Look to the new conversion methods added to the old classes.

java.sql.Timestamp ts = java.sql.Timestamp.from( instant );

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154