我的json约会包含 CreatedOn 日期:
{
"CreatedOn" : "\/Date(1406192939581)\/"
}
我需要将 CreatedOn 转换为简单的日期格式,并计算从CreatedOn Date到Present Date的差异天数。
当我调试以下代码字符串 CreatedOn 时显示空值。怎么样?
JSONObject store = new JSONObject(response);
if (response.contains("CreatedOn"))
{
String CreatedOn = store.getString("CreatedOn");
}
答案 0 :(得分:4)
JSONObject store = new JSONObject(response);
if(store.has("CreatedOn")) {
Timestamp stamp = new Timestamp(store.getLong("CreatedOn"));
Date date = new Date(stamp.getTime());
System.out.println(date);
}
或
JSONObject store = new JSONObject(response);
if(store.has("CreatedOn")) {
Integer datetimestamp = Integer.parseInt(store.getString("CreatedOn").replaceAll("\\D", ""));
Date date = new Date(datetimestamp);
DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS");
String dateFormatted = formatter.format(date);
}
考虑使用JSON方法而不是包含。 JSON具有“has()”,用于验证密钥是否存在。
您还应该确保先尝试{}捕获{}字符串,以确保其有效的JSON。
更新
你的价值是 /日期(1406192939581)/
表示必须先格式化。 通过使用
解析字符串来获取它Integer datetimestamp = Integer.parseInt(store.getString("CreatedOn").replaceAll("\\D", ""));
答案 1 :(得分:1)
java.util
的日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern date-time API。
Instant#ofEpochMilli
这里的关键是从 JSON 字符串中的毫秒中获取 Instant
的对象。拥有 Instant
后,您可以将其转换为其他 java.time types,例如ZonedDateTime
甚至是旧版 java.util.Date
。
关于正则表达式的注释,\D+
:\D
指定了 non-digit 而 +
指定了它的 one or more ).
演示:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import org.json.JSONObject;
public class Main {
public static void main(String[] args) {
JSONObject store = new JSONObject("{\n" + "\"CreatedOn\" : \"\\/Date(1406192939581)\\/\"\n" + "}");
if (store.has("CreatedOn")) {
// Replace all non-digits i.e. \D+ with a blank string
Instant instant = Instant.ofEpochMilli(Long.parseLong(store.getString("CreatedOn").replaceAll("\\D+", "")));
System.out.println(instant);
// Now you can convert Instant to other java.time types e.g. ZonedDateTime
// ZoneId.systemDefault() returns the time-zone of the JVM. Replace it with the
// desired time-zone e.g. ZoneId.of("Europe/London")
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
// Print the default format i.e. the value of zdt#toString
System.out.println(zdt);
// A custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMMM dd HH:mm:ss uuuu", Locale.ENGLISH);
String strDateTimeFormatted = zdt.format(dtf);
System.out.println(strDateTimeFormatted);
}
}
}
输出:
2014-07-24T09:08:59.581Z
2014-07-24T10:08:59.581+01:00[Europe/London]
Thu July 24 10:08:59 2014
从 Trail: Date Time 了解有关现代日期时间 API 的更多信息。
java.util.Date
获取 Instant
:您应该避免使用 java.util.Date
,但无论出于何种目的,如果您想获得 java.util.Date
,您所要做的就是使用 Date#from
,如下所示:
Date date = Date.from(instant);
答案 2 :(得分:0)
现在该有人提供现代答案了。在2014年提出此问题时,Java 8刚刚问世,它带有现代的Java日期和时间API java.time。今天,我建议大家都使用此方法,并避免在其他答案中使用旧的类Timestamp
,Date
,DateFormat
和SimpleDateFormat
。旧的类设计不好,有充分的理由被替换了。
编辑:使用Java 8,您可以使用高级格式化程序将JSON中的字符串直接解析为Instant
,我认为这很不错:
DateTimeFormatter jsonDateFormatter = new DateTimeFormatterBuilder()
.appendLiteral("/Date(")
.appendValue(ChronoField.INSTANT_SECONDS)
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.appendLiteral(")/")
.toFormatter();
String createdOn = "/Date(1406192939581)/";
Instant created = jsonDateFormatter.parse(createdOn, Instant::from);
System.out.println("Created on " + created);
此代码段的输出为:
创建于2014-07-24T09:08:59.581Z
格式化程序知道最后3位数字是秒的毫秒数,并且考虑到自该纪元以来的所有前几秒,因此这是应该的。要计算从CreatedOn日期到当前日期的差异天:
ZoneId zone = ZoneId.of("Antarctica/South_Pole");
long days = ChronoUnit.DAYS.between(created.atZone(zone).toLocalDate(), LocalDate.now(zone));
System.out.println("Days of difference: " + days);
今天输出(2019-12-20):
差异日:1975
如果不是南极/南极,请替换您所需的时区。
原始答案:
final Pattern jsonDatePattern = Pattern.compile("/Date\\((\\d+)\\)/");
String createdOn = "/Date(1406192939581)/";
Matcher dateMatcher = jsonDatePattern.matcher(createdOn);
if (dateMatcher.matches()) {
Instant created = Instant.ofEpochMilli(Long.parseLong(dateMatcher.group(1)));
System.out.println("Created on " + created);
} else {
System.err.println("Invalid format: " + createdOn);
}
输出为:
创建于2014-07-24T09:08:59.581Z
我不仅使用正则表达式从字符串中提取数字,而且还用于验证字符串。
现代的Instant
类代表一个时间点。它的toString
方法以UTC呈现时间,因此这就是您在输出中看到的,由尾随Z
表示。
链接: Oracle tutorial: Date Time解释了如何使用java.time。