Можно ли указать дату ISO с часовым поясом (т.е. смещением по Гринвичу), но без времени? - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь выяснить, можно ли указать дату с часовым поясом в ISO, но без указания времени.

Может показаться странным задавать вопрос о наличии часового пояса без фактического времени, но технически дата представляет диапазон от двух раз ... 24-часовой период, охватывающий от полуночи до полуночи, и эта «полночь» должна находиться в часовом поясе.

В нашем случае у нас есть API, который хочет сказать «Фильтрация событий до или после даты X и до или после даты Y», и мы хотим, чтобы пользователь указал «9 апреля» (в своем часовом поясе) для обоих, чтобы получить все, что происходит в этот день .

Конечно, мы решаем эту проблему, добавляя день к первой дате, затем меняя его на чистое «до», но для выполнения этой математики требуется интерфейс. Мы не можем сделать это на бэкэнде, потому что отправка даты с указанием времени означает, что мы будем отправлять 9 апреля в полночь, а затем на бэкэнд, добавляя к этому день, но что, если кто-то пройдет в 16:00? 1008 * Мы можем потерпеть неудачу в дате, если она не относится к полуночи, но тогда мы вернемся к тому, зачем сначала передавать ее.

Итак, еще раз, вы можете иметь дату с часовым поясом, но не есть компонент времени?

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

К декодированию Даты ISO8601 только с указанием года-месяца-дня и часового пояса устанавливают соответствующие formatOptions из ISO8601DateFormatter

let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withFullDate, .withTimeZone]
1 голос
/ 25 апреля 2020

Если под часовой пояс вы подразумеваете смещение UT C (как используется с датами ISO 8601 со временем), это не проблема. Если под часовым поясом вы подразумеваете истинный часовой пояс с историей c, настоящими и известными смещениями в будущем от UT C, включая, например, летнее время / летнее время, например, Америка / Нью-Йорк или Северо-Американское восточное время, то ISO 8601 не поддерживать это ни для дат с указанием времени дня, ни без него.

2020-04-25-04:00

Это совершенно верно для ISO 8601 от 25 апреля этого года по смещению -04: 00. Таким образом, вы можете использовать его для представления интервала с 2020-04-25T00: 00-04: 00 (включительно) до 2020-04-26T00: 00-04: 00 (эксклюзив). Что будет эквивалентно 2020-04-25T04: 00Z до 2020-04-26T04: 00Z (Z означает UT C).

Java пример кода

Я не знаю не знает никакого Swift, поэтому не может сказать вам, как отформатировать или проанализировать такую ​​строку в Swift. В Java форматировании это неплохо. Пример:

    LocalDate date = LocalDate.of(2020, Month.APRIL, 25);
    String isoOffsetDateString = date
            .atStartOfDay(ZoneId.of("America/New_York"))
            .format(DateTimeFormatter.ISO_OFFSET_DATE);
    System.out.println(isoOffsetDateString);

Вывод:

2020-04-25-04: 00

Я использую встроенную в Java ISO_OFFSET_DATE форматировщик. Документация информирует нас, что этот formnatter:

Форматер даты ISO, который форматирует или анализирует дату со смещением, например, '2011-12-03 + 01: 00'.

Анализ строки и создание начала и конца дня занимает немного больше:

    TemporalAccessor parsed
            = DateTimeFormatter.ISO_OFFSET_DATE.parse(isoOffsetDateString);
    Instant start = LocalDate.from(parsed)
            .atStartOfDay(ZoneOffset.from(parsed))
            .toInstant();
    Instant end = start.plus(1, ChronoUnit.DAYS);

    System.out.println("From " + start + " inclusive to " + end + " exclusive");

С 2020-04-25T04: 00: 00Z включительно до 2020-04- 26T04: 00: 00Z эксклюзивно

Я решил преобразовать в Instant класс для момента времени, независимого от смещения или часового пояса. Инстансы печатаются в UT C, как говорит трейлинг Z на каждом. В своем коде Java вы можете предпочесть не выполнять это преобразование или делать другое преобразование, все в зависимости от обстоятельств.

Ссылка

...