繁体   English   中英

转换JSON日期格式

[英]Convert JSON date format

我收到一个日期值如下的JSON对象:

{"PostingDate":"\/Date(1325134800000-0500)\/"}

我想用Java代码解析它到Date或将它作为String

我想知道这样做的简单方法。

我认为第一个数字( 1325134800000 )是自纪元以来的毫秒数, -0500是时区。 这似乎是下面的示例代码的情况,这似乎做你想要的。

以下代码使用Jackson解析JSON输入,如果您还没有选择JSON解析库,我建议使用它。 它缺乏错误检查等。

示例代码:

public final class Foo
{
    public static void main(final String... args)
        throws IOException
    {
        // What the JSON value must match exactly
        // Not anchored since it will be used with the (misnamed) .matches() method
        final Pattern pattern
            = Pattern.compile("\\\\/Date\\((\\d+)(-\\d+)?\\)\\\\/");

        final ObjectMapper mapper = new ObjectMapper();

        // Parse JSON...
        final JsonNode node = mapper.readTree(
            "{\"PostingDate\": \"\\/Date(1325134800000-0500)\\/\"}");

        if (!node.has("PostingDate")) {
            System.err.println("Bad JSON input!");
            System.exit(1);
        }

        // Get relevant field
        final String dateSpec = node.get("PostingDate").getTextValue();

        // Try and match the input.
        final Matcher matcher = pattern.matcher(dateSpec);

        if (!matcher.matches()) {
            System.err.println("Bad pattern!"); // Yuck
            System.exit(1);
        }

        // The first group capture the milliseconds, the second one the time zone

        final long millis = Long.parseLong(matcher.group(1));
        String tz = matcher.group(2);
        if (tz.isEmpty()) // It can happen, in which case the default is assumed to be...
            tz = "+0000";

        // Instantiate a date object...    
        final Date date = new Date(millis);

        // And print it using an appropriate date format
        System.out.printf("Date: %s %s\n",
            new SimpleDateFormat("yyyy/MM/dd HH:MM:ss").format(date), tz);
    }
}

输出:

Date: 2011/12/29 06:12:00 -0500

Hier是一种基于fge版本的工作解析方法,但改进为

  1. 它使用了jode的DateTime,并初始化了正确的时区
  2. 模式的微小变化也接受+0200

=>

private static final Pattern bingTimePattern = Pattern.compile("\\/Date\\((\\d+)([-+]\\d+)?\\)\\/");

public static DateTime parseBingTime(String timeAsString) throws ParseException {
    Matcher matcher = bingTimePattern.matcher(timeAsString);
    if (!matcher.find())
        throw new ParseException("wrong date time format " + timeAsString, 0);

    final long millis = Long.parseLong(matcher.group(1));
    String tz = matcher.group(2);
    if (tz.isEmpty())
        tz = "+0000";

    return new DateTime(millis, DateTimeZone.forID(tz));
}

我使用Jquery DatePicker创建了一个简单的JavaScript函数

  function JsonToJSDate(jsonDate) { var reg = /-?\\d+/; var m = reg.exec(jsonDate); return new Date(parseInt(m[0])); } 

$('#Started')。val($。datepicker.formatDate('mm / dd / yy',JsonToJSDate(yourDateVarHere)));

简单的事情,但处理我的工作。 从JSON中提取对象值并应用子字符串。
例如:

      String postingDateObjectValue = "\\/Date(1442436473422)\\/";

      String dateStringInMillis = postingDateObjectValue .substring(7,20);

现在解析millis并在任何你想要的地方使用它们。

在Java> = 8中,您可以使用新的java.time API

输入包含:

  • 一个unix时间戳1325134800000 ),这是自unix epoch( 1970-01-01T00:00Z )以来的毫秒数
  • UTC偏移量-0500 ),这是与UTC的差异(在这种情况下,比UTC晚5小时)

在新的java.time API中,有许多不同类型的日期/时间对象。 在这种情况下,我们可以选择使用java.time.Instant (表示自unix epoch以来的纳秒数)或java.time.OffsetDateTime (表示Instant转换为特定偏移中的日期/时间)。

为了解析String ,我使用java.time.format.DateTimeFormatterBuilder来创建java.time.format.DateTimeFormatter 我还使用java.time.temporal.ChronoField来指定我正在解析的字段:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // epoch seconds
    .appendValue(ChronoField.INSTANT_SECONDS)
    // milliseconds
    .appendValue(ChronoField.MILLI_OF_SECOND, 3)
    // offset
    .appendPattern("xx")
    // create formatter
    .toFormatter();

我还使用正则表达式从输入String提取相关部分(尽管您也可以使用substring()来获取它):

String s = "/Date(1325134800000-0500)/";

// get just the "1325134800000-0500" part - you can also do s.substring(6, 24)
s = s.replaceAll(".*/Date\\(([\\d\\+\\-]+)\\)/.*", "$1");

然后我可以解析我想要的类型:

// parse to Instant
Instant instant = Instant.from(fmt.parse(s));
// parse to OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse(s, fmt);

Instant相当于2011-12-29T05:00:00ZInstant只是时间轴中的一个点,你可以认为它始终是UTC)。 OffsetDateTime具有相同的瞬间,但转换为-0500偏移量,因此其值为2011-12-29T00:00-05:00 InstantOffsetDateTime代表相同的时间点。


要转换为java.util.Date ,请使用Instant

// convert to java.util.Date
Date date = Date.from(instant);

// if you have an OffsetDateTime, you can do this:
Date date = Date.from(odt.toInstant());

这是因为java.util.Date 没有时区/偏移量信息 ,它只表示自unix epoch(与Instant相同的概念)以来的毫秒数,因此可以很容易地从Instant转换。


Java 6和7

对于Java 6和7,您可以使用ThreeTen Backport ,这是Java 8的新日期/时间类的一个很好的后端 对于Android ,你还需要ThreeTenABP (更多关于如何在这里使用它)。

与Java 8的区别在于包名(在Java 8中是java.time ,在ThreeTen Backport(或Android的ThreeTenABP中)是org.threeten.bp ),但类和方法名称是相同的。 因此,格式化程序创建和InstantOffsetDateTime的解析代码是相同的。

另一个区别是,在Java <= 7中, java.util.Date类没有from()方法。 但是您可以使用org.threeten.bp.DateTimeUtils类进行转换:

// convert to java.util.Date
Date date = DateTimeUtils.toDate(instant);

// or from the OffsetDateTime
Date date = DateTimeUtils.toDate(odt.toInstant());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM