将日期 JSON 对象解析为 Java

Parse Date JSON Object to Java

我有一个 JSON 对象日期如下:

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

还有我的javaclass:

    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"

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

两个代码都有效。

您可以将 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));

SimpleDateFormatmillisecond precision(小数点后只有3位),但是你的输入有6个。问题是这个class也太宽松了,试图解析无论你传递给它的是什么输入(不是很好),甚至是无效的值,都会导致意想不到的结果。

虽然它可能会这样工作:

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 (第二天!)。

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

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

您还必须使用 java.util.Locale 将区域设置强制为英语,以便正确设置月份名称的格式。如果您不指定区域设置,它将使用系统的默认设置,并且不能保证始终是英语(并且默认设置也可以在不通知的情况下更改,即使在运行时也是如此,因此最好始终明确说明是哪个区域设置你正在使用)。

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}).*", "");
// 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 的新 date/time API,因为它具有纳秒精度(9小数点后的数字)。更不用说旧的 classes(DateCalendarSimpleDateFormat)有 lots of problems 并且正在被新的 API 取代。

如果您正在使用 Java 8,请考虑使用 new java.time API. It's easier, less bugged and less error-prone than the old APIs.

如果您使用 Java <= 7,您可以使用 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 ).

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

要解析输入,您需要使用 DateTimeFormatter 并将其解析为 LocalDateTime(代表日期和时间的 class,没有时区 - 看起来是最好的,因为您的输入中没有时区信息。

为了生成输出,您使用另一个 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));

输出将是:

16 Jun 2016