Будет ли метка времени (с разными форматами часовых поясов) в будущем?


Мне даны временные метки в следующем формате:

Mon Jul 28 11:39:29 GMT-05:00 2014
Mon Jul 28 13:39:29 GMT+02:00 2014
Thu Jul 17 00:02:02 UTC 2014
Fri Jul 18 14:47:01 UTC 2014

Мне нужно добавить к этому X минут и вернуть true/false, если результат будет в будущем. Хитрость в том, что метки времени могут находиться в любом часовом поясе, а часовой пояс может быть выражен в формате UTC или GMT (см. Примеры выше).

Вот код, который я написал до сих пор, но я не знаю, как продолжить:

function isFuture($dateTimeStr, $minToAdd) {    
  $date1 = DateTime::createFromFormat("D M d H:i:s P Y", $dateTimeStr);

  // Something like $date1->date_interval_create_from_date_string('30 minutes);
  $date1->add(date_interval_create_from_date_string($minToAdd . ' minutes'));

  $now = new DateTime("now");
  return $date1 > $now;
}

echo isFuture("Mon Jul 28 14:39:29 GMT-05:00 2014", 30) ? "Future" : "Past";
echo isFuture("Fri Jul 18 14:47:01 UTC 2014", 30) ? "Future" : "Past";

Отвечая на мой собственный вопрос:

function isFuture($dateTimeStr, $minToAdd) {    
  $t = strtotime($dateTimeStr) + ($minToAdd*60);
  return $t > time();
}
Author: Pepster K., 2014-07-28

2 answers

Просто используйте DateTime::getTimezone() чтобы получить рабочий часовой пояс $date1 и использовать его для вашего объекта $now Дата-время:

function isFuture($dateTimeStr, $minToAdd) {    
  $date1 = DateTime::createFromFormat("D M d H:i:s P Y", $dateTimeStr);

  // Something like $date1->date_interval_create_from_date_string('30 minutes);
  $date1->add(date_interval_create_from_date_string($minToAdd . ' minutes'));

  $now = new DateTime("now", new DateTimeZone($date1->getTimezone()));
  return $date1 > $now;
}

Затем это будет работать с любым часовым поясом. Но если часовой пояс всегда будет GMT/UTC, вы можете просто жестко запрограммировать его в своей функции:

$now = new DateTime("now", new DateTimeZone('GMT'));
 2
Author: John Conde, 2014-07-28 19:33:34

Java.время

Как проблемные старые классы даты и времени из самых ранних версий Java, так и библиотека времени Joda теперь являются устаревшими, вытесненными классами java.time.

Шаблон форматирования

Коды шаблонов форматирования DateTimeFormatter похожи на унаследованный класс SimpleDateFormat, но не идентичны. Изучите JavaDoc.

OffsetDateTime

Тип элементов GMT-05:00 является смещением от UTC, поэтому мы обрабатываем как OffsetDateTime. Вы могли бы проанализировать как ZonedDateTime для простоты смешивания этих объектов с объектами, полученными из других входных данных, но это вводило бы в заблуждение людей, читающих ваш код.

ZonedDateTime

UTC на самом деле является названием часового пояса, поэтому мы обрабатываем как ZonedDateTime.

Чтобы быть ясным, GMT и UTC - это практически одно и то же с точки зрения обычных бизнес-приложений. Но использование здесь другое. Цифры плюс или минус указывают на смещение от UTC, но не полный часовой пояс. Один только текст UTC является именем зоны, определенной зоной, которая имеет нулевое смещение, но вид строки может также иметь имя зоны America/Montreal или Europe/Paris.

Классы для различных способов просмотра момента:

  • В Instant класс представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).
  • Ан OffsetDateTime похож на Instant, но присвоен смещение от UTC (количество часов, минут и секунд, скорректированных по его времени настенных часов).
  • А ZonedDateTime похоже на Instant, но ему назначен часовой пояс. Часовой пояс - это совокупность прошлых, настоящих и будущих смещений региона.

Пример кода

List<CharSequence> inputs = new ArrayList<> ( 4 );

inputs.add ( "Mon Jul 28 11:39:29 GMT-05:00 2014" );
inputs.add ( "Mon Jul 28 13:39:29 GMT+02:00 2014" );
inputs.add ( "Thu Jul 17 00:02:02 UTC 2014" );
inputs.add ( "Fri Jul 18 14:47:01 UTC 2014" );
inputs.add ( "garbage-in garbaage-out" );
inputs.add ( "Fri Jan 23 12:34:56 UTC 2099" );  // Future.

Instant now = Instant.now ();  // Capture the current moment in UTC.

DateTimeFormatter fGMT = DateTimeFormatter.ofPattern ( "EEE MMM dd HH:mm:ss OOOO uuuu" );
DateTimeFormatter fUTC = DateTimeFormatter.ofPattern ( "EEE MMM dd HH:mm:ss z uuuu" );

for ( CharSequence input : inputs ) {
    if ( input.length () == "Mon Jul 28 11:39:29 GMT-05:00 2014".length () ) {
        OffsetDateTime odt = OffsetDateTime.parse ( input , fGMT );
        if ( odt.toInstant ().isAfter ( now ) ) {
            System.out.println ( "input: " + input + " is future." );
        } else {
            System.out.println ( "input: " + input + " is past or present." );
        }
    } else if ( input.length () == "Thu Jul 17 00:02:02 UTC 2014".length () ) {
        ZonedDateTime zdt = ZonedDateTime.parse ( input , fUTC );
        if ( zdt.toInstant ().isAfter ( now ) ) {
            System.out.println ( "input: " + input + " is future." );
        } else {
            System.out.println ( "input: " + input + " is past or present." );
        }
    } else {
        System.err.println ( "ERROR - Unexpected input: " + input );
    }
}

Ввод: Пн 28 июля 11:39:29 по Гринвичу - 05:00 2014 год прошел или начался.

Ввод: Пн. 28 июля 13:39:29 GMT+02:00 2014 прошел или присутствует.

Ввод: Чт 17 июля 00:02:02 UTC 2014 прошел или присутствует.

Ввод: Пт 18 июля 14:47:01 UTC 2014 года в прошлом или настоящем.

Ввод: Пт 23 января 12:34:56 UTC 2099 - это будущее.

Смотрите этот код запускается в режиме реального времени по адресу IdeOne.com.

Математика даты и времени

Добавление времени кажется отвлекающим от основных вопросов вашего вопроса. Поэтому я проигнорировал эту тему в примере выше.

Но это достаточно просто сделать. Классы выше имеют методы plus… и minus… для добавления или вычитания количества часов, минут и т.д.

OffsetDateTime odtLater = odt.plusHours( 1 );
ZonedDateTime zdtLater = zdt.plusMinutes( 90 );

Вы можете определить отрезок времени как Duration.

Duration d = Duration.ofMinutes( 90 ) ;
ZonedDateTime zdtLater = zdt.plus( d );

Классы java.time используют неизменяемые объекты . Таким образом, результатом манипуляции является новый объект со значениями, основанными на оригинале.


О java.время

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют неприятное старое наследие дата-время такие классы, как java.util.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time, в настоящее время находящийся в режиме обслуживания, рекомендует перейти на классы java.time.

Чтобы узнать больше, см. Учебник по Oracle. И найдите переполнение стека для множества примеров и объяснений. Спецификация JSR 310.

Где получить классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является доказательством основа для возможных будущих дополнений к java.time. Вы можете найти здесь некоторые полезные классы, такие как Interval, YearWeek, YearQuarter, и еще.

 0
Author: Basil Bourque, 2017-05-23 10:29:50