将日期 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));
SimpleDateFormat
有millisecond 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(Date
、Calendar
和 SimpleDateFormat
)有 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
我有一个 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));
SimpleDateFormat
有millisecond 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(Date
、Calendar
和 SimpleDateFormat
)有 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