Конвертировать формат даты JSON - PullRequest
6 голосов
/ 02 января 2012

Я получаю объект JSON со значением даты, например:

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

И я хочу проанализировать его в коде Java на Date или получить как String.

Я хочу знать, как это легко сделать.

Ответы [ 5 ]

5 голосов
/ 02 января 2012

Я так понимаю, первое число (1325134800000) - это количество миллисекунд с начала эпохи, а -0500 - это часовой пояс. Это похоже на случай с приведенным ниже примером кода, который, кажется, делает то, что вы хотите.

Следующий код анализирует ввод JSON, используя Jackson , что я рекомендую, если у вас еще нет библиотеки выбора 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
0 голосов
/ 19 октября 2017

В Java> = 8 вы можете использовать новый java.time API .

Вход содержит:

  • a unix timestamp (1325134800000), то есть число миллисекунд, прошедших с начала эпохи Unix (1970-01-01T00:00Z)
  • a Смещение UTC (-0500), что отличается от UTC (в данном случае на 5 часов позже UTC)

В новом java.time API имеется лотов различных типов объектов даты / времени.В этом случае мы можем выбрать использование java.time.Instant (которое представляет количество наносекунд после эпохи Unix) или 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:00Z (Instant простоточка на временной шкале, и вы можете думать, что это всегда в UTC).OffsetDateTime имеет тот же момент, но преобразован в смещение -0500, поэтому его значение равно 2011-12-29T00:00-05:00.Но и Instant, и OffsetDateTime представляют один и тот же момент времени.


Чтобы преобразовать в 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 (та же концепция Instant), поэтому его можно легко преобразовать из Instant.


Java 6 и 7

Для Java 6 и 7 вы можете использовать ThreeTen Backport , отличный backport для новых классов даты / времени в Java 8.А для Android вам также потребуется ThreeTenABP (подробнее о том, как его использовать здесь ).

Отличие от Java 8это имена пакетов (в Java 8 java.time и в ThreeTen Backport (или ThreeTenABP Android) org.threeten.bp), но классы и методы names одинаковы.Таким образом, создание форматера и код разбора на Instant и OffsetDateTime одинаковы.

Другое отличие состоит в том, что в Java <= 7 класс <code>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());
0 голосов
/ 17 сентября 2015

Простая вещь, но справиться с моей работой.Извлеките значение вашего объекта из JSON и примените подстроку.
Например:

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

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

Теперь проанализируйте миллисис и используйте их где угодно.

0 голосов
/ 21 февраля 2013

Я создал простую функцию JavaScript, используя Jquery DatePicker

    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)));

0 голосов
/ 08 июня 2012

Hier - это рабочий метод синтаксического анализа, основанный на версии fge, но улучшенный как

  1. , в котором используется DateTime jode с правильным инициализированным часовым поясом
  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));
}
...