2

I am trying to parse String date to a particular date format, but when I used options available from SimpleDateFormat I always get different result. This is the string i am trying to parse:

String datetToParse = ""2019-07-04 00:32:08:627158"" into  04-JUL-19 12.32.08.627158000 AM. 

Can i achieve this using simpledateformat or any other date formatter? Any help will be highly appreciated.

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

public class DateFormat {

    public static void main(String[] args) {
        String date = "2019-07-04 00:32:08:627158";

        SimpleDateFormat sf = new SimpleDateFormat("yymmdd");
        Date d = null;
        try {
            d= sf.parse(date);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(d);

    }

}
Mahesh Mishra
  • 39
  • 1
  • 6
  • what output are you expecting ? – Ryuzaki L Dec 06 '19 at 01:21
  • Does your input look like `190704`? Then why are you trying to parse it with that format? Also `mm` is minutes (so that would be `193204`... i.e. your format is not correct). Here's a useful trick: `System.out.println(sf.format(new Date()));` if that doesn't look like your input, then the format is not right. – Elliott Frisch Dec 06 '19 at 01:22
  • @ElliottFrisch yes my format is not correct , I tried many other options from simpedateformat but could not get desire output. this is my desire output:04-JUL-19 12.32.08.627158000 AM. – Mahesh Mishra Dec 06 '19 at 01:25
  • Start with parsing your input before you try to create your output. Word of warning, your format appears to include nanoseconds; that's not going to be easy to parse. – Elliott Frisch Dec 06 '19 at 01:25
  • how do you get `12 AM` in output ? are you looking for this `2019-Jul-04 00:32:08:627158000 AM` @MaheshMishra ? – Ryuzaki L Dec 06 '19 at 01:47
  • 00 = 12 (midnight), I got great answer from elliot. apreciated for your effort deadpool – Mahesh Mishra Dec 06 '19 at 02:04

2 Answers2

5

Instead of the long deprecated SimpleDateFormat and java.util.Date, you should use the new DateTimeFormatter and LocalDateTime in the java.time and java.time.format packages. If for no other reason than SimpleDateFormat does not offer nanosecond resolution (and your input appears to have nanoseconds).

Something like,

String date = "2019-07-04 00:32:08:627158";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
    "yyyy-MM-dd HH:m:ss:nnnnnn");
LocalDateTime ldt = LocalDateTime.parse(date, formatter);
DateTimeFormatter outFormatter = DateTimeFormatter.ofPattern(
    "dd-MMM-yy hh.mm.ss.nnnnnn a");
System.out.println(outFormatter.format(ldt));

Outputs

04-Jul-19 12.32.08.627158 AM

If you want JUL add a toUpperCase() call, and if you need a literal extra three zeros add them in the outFormatter. Like,

DateTimeFormatter outFormatter = DateTimeFormatter.ofPattern(
        "dd-MMM-yy hh.mm.ss.nnnnnn000 a");
System.out.println(outFormatter.format(ldt).toUpperCase());

Outputs

04-JUL-19 12.32.08.627158000 AM

It isn't clear where those three zeros came from, if you wanted more precision I would have used

DateTimeFormatter outFormatter = DateTimeFormatter.ofPattern(
        "dd-MMM-yy hh.mm.ss.nnnnnnnnn a");
System.out.println(outFormatter.format(ldt).toUpperCase());

But that outputs (as I would expect)

04-JUL-19 12.32.08.000627158 AM
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    There are two bugs in your code. It first parses `2019-07-04 00:32:08:627158` into `2019-07-04T00:32:08.000627158`. The fractional digits are shifted 3 positions to the right. It then formats `2019-07-04T00:32:08.000627158` into `04-jul.-19 12.32.08.627158 AM`. This time the same digits are shifted 3 positions to the left. So the two bugs balance out and you didn’t discover. For correct code use `SSSSSS` instead of `nnnnnn` in the first formatter and `SSSSSSSSS` in the second. – Ole V.V. Dec 07 '19 at 12:20
0

If your fractional part is microseconds written as a number between 0 and 6 digits (up to 999,999 microseconds), then you can specify ChronoFIeld.MICRO_OF_SECOND in your formatter:

DateTimeFormatter msecFormatter = new DateTimeFormatterBuilder()
    .appendPattern("yyyy-MM-dd HH:mm:ss:")
    .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, false)
    .toFormatter();

LocalDateTime ldt = LocalDateTime.parse("2019-07-04 00:32:08:627158", msecFormatter);
DateTimeFormatter nsFormatter = DateTimeFormatter.ofPattern("dd-MMM-yy hh.mm.ss.n a");
System.out.println(nsFormatter.format(ldt).toUpperCase());
IronMan
  • 1,854
  • 10
  • 7
  • Your `nsFormatter` is not correct. It gives the correct output in this example, but for example `2019-07-04 00:32:08:007158` is formatted into `04-JUL.-19 12.32.08.7158000 AM`. The fractional digits have been shifted left two positions. – Ole V.V. Dec 07 '19 at 11:55
  • @OleV.V. It's correct. Note the units. This assumes the input format uses *microseconds* (the fractional part is 6 digits) and the output uses ISO-8601 *nanoseconds* (1 us = 1,000 ns). – IronMan Dec 09 '19 at 08:03