gson 将Json日期转换为java日期

mv1qrgav  于 2022-11-06  发布在  Java
关注(0)|答案(3)|浏览(208)

我的json响应包含创建日期日期:

{
"CreatedOn" : "\/Date(1406192939581)\/"
}

我需要将CreatedOn转换为简单的日期格式,并计算从CreatedOn Date到Present Date之间的天数差。
当我调试下面的代码字符串CreatedOn时,显示一个空值。为什么?

JSONObject store = new JSONObject(response);

if (response.contains("CreatedOn"))
{
    String CreatedOn = store.getString("CreatedOn");
}
disbfnqx

disbfnqx1#

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方法而不是contains。JSON有“has()”来验证密钥是否存在。
您还应该确保首先尝试{} catch {} String,以确保其JSON有效。
更新:
您的值为/日期(1406192939581)/
这意味着必须先设置它的格式。通过使用

Integer datetimestamp = Integer.parseInt(store.getString("CreatedOn").replaceAll("\\D", ""));
q9yhzks0

q9yhzks02#

java.时间

现在是时候有人提供现代的答案了。当这个问题在2014年被问到的时候,Java 8刚刚发布,随之而来的是java.time,现代的Java日期和时间API。今天我建议我们都使用它,避免使用旧的类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年7月24日09:08:59.581Z
格式化程序知道最后3位数是秒的毫秒数,并考虑自epoch以来的所有前面的位数秒数,因此它以应有的方式工作。要计算从CreatedOn Date到Present Date的天数差:

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
如果不是南极洲/South_Pole,请替换您想要的时区。

原始答案:

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年7月24日09:08:59.581Z
我使用正则表达式不仅是为了从字符串中提取数字,而且也是为了验证字符串。
现代的Instant类表示一个时间点,它的toString方法以UTC表示时间,所以这就是您在输出中看到的内容,由尾随的Z表示。

链接:Oracle tutorial: Date Time,说明如何使用java. time。

oogrdqng

oogrdqng3#

*java.时间 *

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的更多信息。

如何从Instant获取java.util.Date

您应该避免使用java.util.Date,但无论出于何种目的,如果您想获得java.util.Date,您所要做的就是使用Date#from,如下所示:

Date date = Date.from(instant);

相关问题