-1

I want to get String data after date in an object

Sample Input:
2019-06-06 13:01:53.263Z|abc|alfkdjas|alfjdlaksd|alkjdfs
2019-06-06 13:01:53.264Z|lkjsfadfi|sadofuoif
2019-04-01 16:47:25.327Z|ERROR 7816

Output: [{"date":"2019-06-06 13:01:53.263Z","data":"|abc| ldskjf "},{"date":"2019-06-06 13:01:53.264Z","data":"|lkjsfadfi"}]

Means i want the data after the first date until second date has come..

I tried to seperate data between two dates..

public static String ReadData() {

         BufferedReader reader;
           try {

               reader = new BufferedReader(new FileReader(logfilename));
               String line = reader.readLine();
               JSONArray jason=new JSONArray();
               JSONObject jo=new JSONObject();
               int count=0;
               while (true) {

                   if(line != null) {
                       if(count>0) {

                       }
                       if(isValidDate(line.split("\\|")[0])) {
                           count++;
                           jo.put("date", line.split("\\|")[0]);
jo.put("data",line);
                       }

                       line = reader.readLine();
                   }else {
                       break;
                   }


               }
               reader.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
           return ""; 
     }

This function seperate my dates from the string...

public static boolean isValidDate(String inDate) {

 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss.ms");           
     try {
            dateFormat.parse(inDate);

            } catch (ParseException pe) {
                return false;
            }
            return true;
       }

Input:
2019-06-06 13:01:53.263Z|abc| ldskjf
2019-06-06 13:01:53.264Z|lkjsfadfi

Output:

[{"date":"2019-06-06 13:01:53.263Z","data":"|abc| ldskjf "},{"date":"2019-06-06 13:01:53.264Z","data":"|lkjsfadfi"}]

I have a big size of log file here, and from that log file I want to convert that log file to a JSON array.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Pushpak
  • 77
  • 10
  • Did not understand, you want to extract what data ? – TechFree Jun 06 '19 at 16:47
  • suppose i have a string 2019-06-06 13:01:53.263Z|abc|alfkdjas 2019-06-06 13:01:53.264Z|lkjsfadfi i want to get data between the dates means i want array like [{"date":"2019-06-06 13:01:53.263Z","data":"|abc|alfkdjas|alfjdlaksd|alkjdfs"},{"date":"2019-06-06 13:01:53.264Z","data":"|lkjsfadfi|sadofuoif"}] of above string – Pushpak Jun 06 '19 at 16:51
  • did u get now @TechFree ? – Pushpak Jun 06 '19 at 16:52
  • 1
    I recommend you don’t use `SimpleDateFormat`. That class is notoriously troublesome and long outdated. Instead use `DateTimeFormatter` and other classes from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jun 06 '19 at 17:24
  • 1
    @Pushpak You need to edit your question. Title and desired result. But, first of all, you need to tell us what the format of your input is. Is it multiple Strings, One big String, text from a file? – Soutzikevich Jun 06 '19 at 17:31
  • @P.Soutzikevich I have a big Size of log file here and from that log file i want to convert that log file to json array.. – Pushpak Jun 06 '19 at 17:38
  • I think that you just need `line.split("\\|", 2)`. This will give you a 2 element array with the date in index 0 and everything else in index 1. Next you may use `Instant.parse(inDate.replace(' ', 'T'))` to validate the datetime string. It will throw `DateTimeParseException` if the datetime string is not valid. – Ole V.V. Jun 07 '19 at 08:13

3 Answers3

1

use substring instead

String res = "2019-06-06 13:01:53.263Z|abc|alfkdjas|alfjdlaksd|alkjdfs "
res0.substring(res0.indexOf('|'))  // 2019-06-06 13:01:53.263Z
res0.substring(0,res0.indexOf('|'))// |abc|alfkdjas|alfjdlaksd|alkjdfs 
  • Thank you for your solution but this is like static workaround and my data is dynamic so your solution might not be worked do you have any function or any other solution – Pushpak Jun 06 '19 at 17:06
  • 1
    how can your data change? if you are always expecting date on the first column this is as good as it gets. Do you have any other clarification on how data will change? – Luis Ramirez-Monterosa Jun 06 '19 at 17:21
  • 2019-06-06 13:01:53.263Z|fdf|ewqe|[oewrer-23]|ERROR|||||||5|abclkadsfl;adskfja;sdfkja;sdfjf
    2019-06-06 13:01:53.263Z|wqew|dfadfadf|[wrqer-23]|ERROR|||||||6|sdfsdfervice:?|?|Invalid Entity 2019-06-06 13:01:53.263Z|dsafdds|sdfasdf|[kdjfalds-23]|ERROR|||||||6|sdkjfhasdlfhasljkdf
    – Pushpak Jun 06 '19 at 17:24
  • there are thousands of lines like this so i'm not able to seperate dates with their data... as i already told above...now you got my point? – Pushpak Jun 06 '19 at 17:25
  • are not they separated by end of line character? I'm assumming you are reading a comma separated file, tab or pipe separeted for that matter. Read line by line, and first column is Date. Is not the case? provide more information on the file format you are trying to parse – Luis Ramirez-Monterosa Jun 06 '19 at 17:33
  • I have log file and i want to convert that file to json array. – Pushpak Jun 06 '19 at 17:39
  • there are thousands of logs are there in that file – Pushpak Jun 06 '19 at 17:40
  • if you read using reader.readLine doesn't matter how many lines you have and if you always expect a date to be first column or identify it. obviously you need to incorporate using substring on your code. – Luis Ramirez-Monterosa Jun 06 '19 at 17:51
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/194555/discussion-between-pushpak-and-luis-ramirez-monterosa). – Pushpak Jun 06 '19 at 18:12
1

It seems that you are looking for something like the following.

First, you need a method to read each line from a file. (If it is not line by line, please let me know. This is what I understand from your question).

This method will return an ArrayList containing each line of the input file.

public ArrayList<String> readAllLines(String filename){
    //ArrayList to hold all the lines
    ArrayList<String> lines = null;

    //Get lines of text (Strings) as a stream
    try (Stream<String> stream = Files.lines(Paths.get(filename))){
        // convert stream to a List-type object
        lines = (ArrayList<String>)stream.collect(Collectors.toList());
    }
    catch (IOException ioe){
        System.out.println("\nCould not read lines of text from the file.\n" +
                "Reason: parameter \"" + ioe.getMessage() + "\"");
    }
    catch (SecurityException se){
        System.out.println("Could not read the file provided." +
                "Please check if you have permission to access it.");
    }
    return lines;
}

Next, we need a method to determine if a String is a date, where we will use the method you posted in your own question.

public boolean isValidDate(String inDate) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.ms");
    try {
        dateFormat.parse(inDate);
    }
    catch (ParseException pe) {
        return false;
    }
    return true;
}

Then, we will use a method to convert each String that we parse, into a JSONObject.

public JSONObject convertToJsonObject(String line){
    //Convert String into an ArrayList, split by "|" delimiter
    ArrayList<String> dataParts = new ArrayList<>(Arrays.asList(line.split("\\|")));
    String date=null;
    JSONObject jsonObj = new JSONObject();

    //Get the date, wherever it might be in the String and remove it from the List
    for(int i=0; i<dataParts.size(); i++){
        if (isValidDate(dataParts.get(i))){
            date = dataParts.get(i);
            dataParts.remove(i);
            break;
        }
    }
    //Add the date with key "date"
    jsonObj.put("date", date);
    //Add the rest of the data, with key "data" (while preserving the order)
    jsonObj.put("data", String.join("|", dataParts));

    return jsonObj;
}

Finally, we need the method that will tie all of the above together and produce the desirable result.

public JSONArray extractData(String filename){
    JSONArray jsonArray = new JSONArray();
    ArrayList<String> lines = readAllLines(filename);

    //For each line of the original text file, add the JSONObject to the JSONArray
    for (String line : lines)
        jsonArray.add(convertToJson(line));

    return jsonArray;
}

The usage in the main method would be:

public static void main(String[] a){
    MyClass myClass = new MyClass();
    JSONArray myArray = myClass.extractData("myTextFile.txt");
    System.out.println(myArray.toJSONString());
}

Output:

[{"date":"2019-06-06 13:01:53.263Z","data":"abc|alfkdjas|alfjdlaksd|alkjdfs"},{"date":"2019-06-06 13:01:53.263Z","data":"abc|al"}]

If the date is always the first occurrence in each line, then it would be better to use the String.substring() method to extract the date, just like @Luis Ramirez-Monterosa demonstrates in his answer.

My working, assumes that the date could be in the middle of the input String.

Soutzikevich
  • 991
  • 3
  • 13
  • 29
0

Extracting a date with the method you created isValid(), does not make any sense. That method will return a boolean type object (true or false).

By slightly modifying your method, you can create the following which extracts the date from the String examples you provided and finally returns a Date-type object:

public static Date extractDate(String inDate) {
    Date dt = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.ms");
    try {
        dt = dateFormat.parse(inDate);
    } 
    catch (ParseException pe) {
        pe.printStackTrace();
    }
    return dt;
}

Usage:

Date myDate = extractDate("2019-06-0613:01:53.263Z|abc|alfkdjas|alfjdlaksd|alkjdfs");

Output:

Thu Jun 06 13:03:03 BST 2019

Soutzikevich
  • 991
  • 3
  • 13
  • 29
  • i have already done for date....all i want is to get string data after the first date ... until next date .. got it? – Pushpak Jun 06 '19 at 17:19
  • String str="2019-06-06 13:01:53.263Z|abc|alfkdjas|alfjdlaksd|alkjdfs 2019-06-06 13:01:53.264Z|lkjsfadfi|sadofuoif 2019-04-01 16:47:25.327Z|ERROR 7816 " – Pushpak Jun 06 '19 at 17:21
  • output: [{"date":"2019-06-06 13:01:53.263Z","data":"|abc| ldskjf "},{"date":"2019-06-06 13:01:53.264Z","data":"|lkjsfadfi"}] – Pushpak Jun 06 '19 at 17:21
  • @Pushpak That's an entirely different question. Your initial question is not clear itself. Please re-write everything and keep it simple and understandable – Soutzikevich Jun 06 '19 at 17:23
  • @Pushpak Are you trying to extract all the dates from one big String and convert the dates with the data next to them into a data structure similar to a JavaScript object/json? – Soutzikevich Jun 06 '19 at 17:25
  • Exactly @P.soutzikevich ... that's what i want ... – Pushpak Jun 06 '19 at 17:27
  • @OleV.V. Wow, good eye, I didn't even notice that. What could have caused this? – Soutzikevich Jun 06 '19 at 17:27
  • 1
    @OleV.V. I just copied the OP's method body and didn't notice that he was using capital **D**'s for day. It should be lowercase **d**. Edited ! – Soutzikevich Jun 06 '19 at 17:29
  • You copied the questioner’s incorrect use of uppercase `DD` in the format pattern string. See for example [Java SimpleDateFormat always returning January for Month](https://stackoverflow.com/questions/3560279/java-simpledateformat-always-returning-january-for-month). It’s typical for the old `SImpleDateFormat` that it lets such errors slip through and just gives incorrect results. By contrast java.time, the modern Java date and time API, would usually make you aware of your bug. I recommend we prefer the latter. – Ole V.V. Jun 06 '19 at 17:29