views:

412

answers:

4

Can somebody please explain to me how I can convert

2009-10-27 14:36:59.580250

into

27.10.2009, 14:36 ?

The first date is available as a string and the second one should be a string as well ;) Up to now I'm not so into date conversion within Java...

Thanks in advance!

+2  A: 

Check out SimpleDateFormat. You can use this to both parse and format. I would suggest parsing the above into a Date object using one SimpleDateFormat, and then formatting to a String using a 2nd SimpleDateFormat.

Note that SimpleDateFormat suffers from threading issues, and so if you're using this in a threaded environment, either create new SimpleDateFormats rather than used static versions, or use the corresponding but thread-safe classes in Joda.

Brian Agnew
Good hint concerning the threading issue. But BalusC got the "accepted" answer since he provided a code example which led me faster to my goal. But thanks as well!
Marcus
That's entirely reasonable :-)
Brian Agnew
Marcus: Nice of you to accept an answer with a buggy code example, when other people (like me :-/) tried to help you with a correct answer.
jarnbjo
I gave you both an upvote. Now friends again?
BalusC
It's worth checking out Joda time btw. Threading aside it parses quicker then the JDK version.
reccles
@jarnbjo - sometimes an answer you see gives you an insight without necessarily being the most *correct*. Don't get hassled by it :-(
Brian Agnew
+7  A: 

You can use java.text.SimpleDateFormat for this. First step is to parse the first string into a java.util.Date object using SimpleDateFormat based on the pattern of the first string. Next step is to format the obtained java.util.Date object into a string based on the pattern of the second string. For example:

String datestring1 = "2009-10-27 14:36:59.580250";
Date date1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(datestring1);
String datestring2 = new SimpleDateFormat("dd.MM.yyyy HH:mm").format(date1);
System.out.println(datestring2);

Edit: I've removed the .SSSSSS part from the first pattern because it failed. But in my opinion it should in theory have worked with "yyyy-MM-dd HH:mm:ss.SSS" and "yyyy-MM-dd HH:mm:ss.SSSSSS" as well, but it is calculating them as seconds! I consider this as a buggy implementation in SimpleDateFormat. The JodaTime handles the millis/micros perfectly with those patterns.

BalusC
Thanks! It works perfectly ;)
Marcus
You're welcome.
BalusC
This code definitely does not work as expected. "S" is the format pattern for milliseconds, but the input value obviously contains microseconds, so that the output of the code example will be "27.10.2009 14:46" (it adds 580.250 seconds instead of 0.58250 secs).
jarnbjo
I didn't test it, but you're right about the influence of the micros. Updated answer.
BalusC
jarnbjo your right! I did oversee this but now it works ;) Thanks for the hint ^^
Marcus
SimpleDateFormat is not buggy, because it parses "580250" as 580250ms with an "SSS" pattern. For number fields, the formatter prints at least the number of digits (0 prefixed) corresponding to the number of pattern characters. When parsing, the number of pattern characters is irrelevant, except for the year field, for which the number of characters has a specific meaning. The patterns "yyy-M-d H:m:s.S" and "yyyy-MM-dd HH:mm:ss.SSSSSS" are hence identical for the parser.
jarnbjo
OK then I'd call it an unwanted feature :)
BalusC
+3  A: 

You can use SimpleDateFormat. Although there's no format specification for micro-seconds (the last fragment of your input), you can make use of the fact that the parser ignores the rest of the string if it has already managed to match the configured pattern:

SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd HH:mm");
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy HH:mm");
System.out.println(formatter.format(parser.parse("2009-10-27 14:36:59.580250")));

The parser will in this case simply ignore the last part ":59.580250" of the input string.

jarnbjo
The format spec for millis is `S`. Also see the API doc.
BalusC
But there's indeed none for micros. Oddily the `.SSS` also doesn't work nicely, it still takes the micros into account.
BalusC
BalusC: Sorry, this is really embarrasin. I'm ranting over you and am not even able to write my own response properly, mixing up millis and micros. I ment micro, wrote milli and have corrected it now :)
jarnbjo
A: 

Keep in mind when you do this that you are losing precision. Depending on your specific application, this may or may not matter.

If you already have the original date saved somewhere, this is not an issue. However, if the source date is from a transient source (e.g., streaming in from a physical sensor of some sort), it may be a good idea to persist the interim Date object (output of SimpleDateFormat#parse(String)) somewhere.

Just thought I'd point that out.

Jack Leow