【问题标题】:Parse Date JSON Object to Java将日期 JSON 对象解析为 Java
【发布时间】:2018-01-09 11:01:09
【问题描述】:

我有一个这样的 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"

【问题讨论】:

标签: java android json date simpledateformat


【解决方案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(); 

两个代码都在工作。

【讨论】:

  • 你有吗??看到我删除了一些东西
  • @jigarsavaliya 用2016-06-16 23:47:21.800000 试试你的代码,看看你是否仍然认为它有效
  • 这甚至无法编译,请参见 SimpleDateFormat 中的额外双引号 spf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS"");
  • ok 两个代码都在工作,你可以再试一次,我编辑了一些项目
【解决方案2】:

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

【讨论】:

  • 一个问题,如何与String date_d = date_cre.getString("date");结合?
  • @retrospectrum,您可以通过调用方法并在进一步的代码中使用其结果来组合它。您确实了解如何在代码中使用变量,对吧?
【解决方案3】:

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 将区域设置强制为英语,因此月份名称的格式正确。如果您不指定区域设置,它将使用系统的默认设置,并且不保证始终为英语(并且默认设置也可以在不通知的情况下更改,即使在运行时也是如此,因此最好始终明确说明哪一个你正在使用)。

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 ,则可以使用 ThreeTen Backport,这是 Java 8 新日期/时间类的一个很好的向后移植。对于Android,还有ThreeTenABP(更多关于如何使用它here)。

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

要解析输入,您需要使用 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 日

【讨论】:

    猜你喜欢
    • 2014-10-17
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2015-01-20
    • 2012-02-09
    相关资源
    最近更新 更多