将Json日期转换为java日期

时间:2014-07-25 13:03:01

标签: java json datetime gson

我的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");
}   

3 个答案:

答案 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.time

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)

java.time

现在该有人提供现代答案了。在2014年提出此问题时,Java 8刚刚问世,它带有现代的Java日期和时间API java.time。今天,我建议大家都使用此方法,并避免在其他答案中使用旧的类TimestampDateDateFormatSimpleDateFormat。旧的类设计不好,有充分的理由被替换了。

编辑:使用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。