将日期JSON对象解析为Java

时间:2017-08-02 09:38:58

标签: java android json date simpledateformat

我有一个日期的JSON对象:

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

我的java课程:

    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();
                    }
                }
                });
    }

如何解析日期对象以显示输出到"16 Jun 2016"

3 个答案:

答案 0 :(得分:0)

您可以出于此类目的使用java.text.SimpleDateFormat。

   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));

答案 1 :(得分:0)

SimpleDateFormatmillisecond precision(小数点后只有3位数),但你的输入有6个。问题是这个类太宽松了,试图解析传递给它的任何输入(不完全是一种好的方式),甚至是无效的值,导致意想不到的结果。

虽然它可能会这样:

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);

如果毫秒不为零,则可能导致意外结果。在这种情况下:

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在小数点后面看到6位数,但因为它只有毫秒精度(3位数),所以它做了一个“聪明”的事情:它解析小数点后的所有内容并将此值视为毫秒。在上面的情况中,它将考虑900000毫秒,相当于15分钟,并且此金额添加到日期,从而产生2016-06-17 00:14:00.000(第二天) !)。

因此,它会在很多情况下“起作用”,但对许多其他情况也会失败。它不会抛出任何异常,给出非常难以调试的奇怪结果。

如果必须使用此类,唯一的选择是删除String中的最后一位数字,小数点后只保留3位数。你将失去精确度(如果值不为零),但你也不会有那些奇怪和意想不到的结果(公平的权衡,IMO)。

您还必须使用java.util.Locale强制将语言环境强制为英语,因此月份名称的格式为correclty。如果你没有指定一个语言环境,它将使用系统的默认值,并且不能保证总是英语(并且默认也可以在没有通知的情况下进行更改,即使在运行时也是如此,因此最好总是明确指出哪一个你正在使用。)

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));

这将输出16 Jun 2016,并且在毫秒不为零时也有效。

Java新的日期和时间API

如果您不想手动删除额外的数字,唯一的选择是使用Java的新日期/时间API,因为它具有纳秒精度(小数点后9位)。更不用说旧类(DateCalendarSimpleDateFormat)有lots of problems,并且正在被新API替换。

如果您使用的是 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs

如果您使用的是 Java&lt; = 7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,有ThreeTenABP(更多关于如何使用它here)。

以下代码适用于两者。 唯一的区别是包名称(在Java 8中为java.time,在ThreeTen Backport(或Android的ThreeTenABP)中为org.threeten.bp),但类和方法名称是相同的

要解析输入,您需要使用DateTimeFormatter并将其解析为LocalDateTime(一个代表日期和时间的类,没有时区 - 它似乎是最好的,因为你您的输入中没有时区信息)。

要生成输出,请使用另一个DateTimeFormatter并将语言环境设置为英语以保证正确的月份名称:

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));

输出将是:

  

2016年6月16日

答案 2 :(得分:-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);

修改

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(); 

这两个代码都在运行。