0

I have a string of a timestamp in UTC

val x = "2018-09-26T15:05:19.1121042Z"

I would like to have a function like this to convert it to a timestamp object in CST timezone.

def StringToTimeStamp(str: String): Timestamp = {
  val timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
  val timeZone = TimeZone.getTimeZone("America/Chicago")
  timeFormat.setTimeZone(timeZone);
  val now = timeFormat.format(str)
  val ts = java.sql.Timestamp.valueOf(now)
  ts
}

However, I do not know the SimpleDateFormat format for my string, as I can't put in letters like T / Z as they appear in my string x. How would I accomplish this?

test acc
  • 561
  • 2
  • 11
  • 24
  • Did you have a look at the documentaion of `SimpleDateFormat`? `T` and `Z` shoud be explained there. Besides that `timeFormat.format(str)` looks odd: `format()` normally accepts a date and returns a string while you'd first want to `parse()` the string to a date. – Thomas Sep 26 '18 at 15:22
  • I recommend you avoid the `SimpleDateFormat` class. It is not only long outdated, it is also notoriously troublesome. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Sep 26 '18 at 15:38

1 Answers1

3

Zulu time

The Z on the end of your input string means UTC, and is pronounced “Zulu”.

ISO 8601

Your input string is in standard ISO 8601 format. The java.time classes use these standard formats by default when parsing or generating strings.

Instant

Parse your string as an Instant. Instant represents a moment in UTC with a resolution of nanoseconds.

Instant instant = Instant.parse("2018-09-26T15:05:19.1121042Z") ;

Your JDBC driver may be able to take that Instant.

myPreparedStatement.setObject( … , instant ) ;

OffsetDateTime

If not, your JDBC 4.2 or later driver is required to accept OffsetDateTime.

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;

Avoid java.sql.Timestamp

If you have on older JDBC driver before JDBC 4.2, then fall back to using the terrible java.sql.Timestamp. But use these legacy date-time classes only if you absolutely must, as they are an awful mess.

You can convert between the modern and legacy classes by calling new conversion methods added to the old classes.

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

…and…

Instant instant = ts.toInstant() ;

Time zone

Presumably you were asking about java.sql.Timestamp because you are exchanging the value with a database.

Your time zone of Chicago is irrelevant to database work, as most databases store a moment in UTC.

ZonedDateTime

But for presentation to the user, you may want to adjust from UTC to a time zone.

ZoneId z = ZoneId.of( "America/Chicago" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

Generate a string in localized format

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.US ) ;
String output = zdt.format( f ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Just need some clarity: while the driver may take an `Instant` object, that doesn't make the resulting `Timestamp` object correspond to that instant in the required time zone. Or are we assuming that the code will be running on a machine in Chicago? Haven't done jdbc in a while, so all this could be the voice of my ignorance. – ernest_k Sep 26 '18 at 15:51
  • A `java.sql.Timestamp` object is always in UTC, by definition. Ditto for `Instant`. Both carry nanoseconds. `Instant` (and `OffsetDateTime`) replaces `Timestamp`. Your Chicago time zone is irrelevant. – Basil Bourque Sep 26 '18 at 15:55
  • Haha! That's what I didn't know. Thanks! – ernest_k Sep 26 '18 at 15:56