-7

I have a JSON object of date like this:

"date_created": {
    "date": "2016-06-16 11:47:21.000000"}

And my java class:

    protected String doInBackground(String... params){
        try{
            List<NameValuePair> params1 = new ArrayList<>();
            params1.add(new BasicNameValuePair("id", idkbj));
            final JSONObject json = jsonParser.makeHttpRequest(url_kbj + "/" + idkbj + "/", "GET", params1);
            final JSONObject data = json.getJSONObject("data");

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    TextView date = (TextView) findViewById(R.id.date);

                    try{
                        JSONObject date_cre = data.getJSONObject("date_created");
                        String date_d = date_cre.getString("date");

                        date.setText(date_d);

                    }
                    catch (JSONException e){
                        e.printStackTrace();
                    }
                    catch (Exception e){
                        e.printStackTrace();
                    }
                }
                });
    }

How do I parse the date object to display the output to "16 Jun 2016"?

retrospectrum
  • 53
  • 2
  • 13

3 Answers3

0

You can user java.text.SimpleDateFormat for this kind of purposes.

   String a="2016-06-16 11:47:21.000000";
   SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   SimpleDateFormat sdf2=new SimpleDateFormat("dd MMM yyyy");
   Date date=sdf1.parse(a);
   System.out.println(sdf2.format(date));
yılmaz
  • 1,818
  • 13
  • 15
0

SimpleDateFormat has millisecond precision (only 3 digits after the decimal point), but your input has 6. The problem is that this class is also too lenient and tries to parse whatever input you pass to it (not exactly in a good way), even invalid values, leading to unexpected results.

Although it might work this way:

String input = "2016-06-16 11:47:21.000000";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
Date date = sdf.parse(input);

It might lead to unexpected results if the milliseconds are not zero. In a case like this:

String input = "2016-06-16 23:59:00.900000";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
Date date = sdf.parse(input);

SimpleDateFormat sees 6 digits after the decimal point, but as it has only milliseconds precision (3 digits), it does a "smart" thing: it parses everything after the decimal point and treats this value as milliseconds. In the case above, it will consider 900000 milliseconds, which is equivalent to 15 minutes, and it will add this amount to the date, resulting in 2016-06-17 00:14:00.000 (the next day!).

So, it will "work" for lots of cases, but it will also fail for many others. And it won't throw any exception, giving strange results that are very hard to debug.

If you must use this class, the only alternative is to remove the last digits from the String, keeping only 3 digits after the decimal point. You'll lose precision (if the value is not zero), but you also won't have those strange and unexpected results (a fair trade-off, IMO).

You must also use java.util.Locale to force the locale to English, so the month name is formatted correclty. If you don't specify a locale, it'll use the system's default, and it's not guaranteed to always be English (and the default can also be changed without notice, even at runtime, so it's better to always make it explicit which one you're using).

String input = "2016-06-16 11:47:21.000000";
// remove extra digits after decimal point (keep only the first 3 digits after the decimal point)
input = input.replaceAll("(.*\\.\\d{1,3}).*", "$1");
// parse input (now with 3 digits after decimal point)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date date = sdf.parse(input);
// format date (use English locale for the month name)
SimpleDateFormat outputFormat = new SimpleDateFormat("dd MMM yyyy", Locale.ENGLISH);
System.out.println(outputFormat.format(date));

This will output 16 Jun 2016, and also works when milliseconds are not zero.


Java new Date and Time API

If you don't want to manually remove the extra digits, the only alternative is to use Java's new date/time API, because it has nanoseconds precision (9 digits after the decimal point). Not to mention that the old classes (Date, Calendar and SimpleDateFormat) have lots of problems and are being replaced by the new API.

If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.

If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).

The code below works for both. The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.

To parse the input, you need to use a DateTimeFormatter and parse it to a LocalDateTime (a class that represents a date and a time, without timezone - it seems to be the best as you don't have timezone information in your input).

And to produce the output, you use another DateTimeFormatter and set the locale to English to guarantee the correct month name:

String input = "2016-06-16 11:47:21.000000";
// parse the input (with 6 digits after decimal point)
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
// parse the date
LocalDateTime dt = LocalDateTime.parse(input, parser);
// output formatter (use English locale for the month name)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd MMM yyyy", Locale.ENGLISH);
System.out.println(fmt.format(dt));

The output will be:

16 Jun 2016

Community
  • 1
  • 1
-1
 String date="2016-06-16 11:47:21.800000";
    SimpleDateFormat spf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
    Date newDate= null;
    try {
        newDate = spf.parse(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    spf= new SimpleDateFormat("dd MMM yyyy");
    date = spf.format(newDate);
    Log.e("date",date);

EDIT

SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSSSSS");
    SimpleDateFormat destFormat = new SimpleDateFormat("dd MMM, yyyy");

    Date date = null;

        try {
            date = sourceFormat.parse("2016-06-16 11:47:21.000000");
        } catch (java.text.ParseException e) {
            e.printStackTrace();
        }

    String formattedDate = destFormat.format(date);

    Toast.makeText(this, formattedDate, Toast.LENGTH_SHORT).show(); 

both code are working.

jigar savaliya
  • 474
  • 1
  • 8
  • 21