Не осуждаемый точный эквивалент Date (String s) в Java? - PullRequest
26 голосов
/ 18 марта 2009

У меня есть старый код, который использует new Date(dateString) для разбора строки даты. Компиляция кода выдает предупреждение об устаревании Date(java.lang.String) in java.util.Date has been deprecated.

Javadoc бесполезно советует мне использовать DateFormat.parse(), хотя класс DateFormat не имеет статического parse метода.

Теперь я знаю, как использовать SimpleDateFormat, но я хочу убедиться, что я получаю точно такое же поведение конструктора Date, от которого мы зависимы.

Ответы [ 7 ]

49 голосов
/ 18 марта 2009

Вот мое предположение (я написал в вики сообщества, чтобы вы могли проголосовать, если я прав):

Date parsed;
try {
    SimpleDateFormat format =
        new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
    parsed = format.parse(dateString);
}
catch(ParseException pe) {
    throw new IllegalArgumentException(pe);
}
8 голосов
/ 18 марта 2009

SimpleDateFormat - это путь. Могу ли я указать, однако, что вы можете почувствовать необходимость определить один экземпляр SimpleDateFormat и построить объекты Date, используя это. Если вы это сделаете, будьте осторожны, что SimpleDateFormat не является поточно-ориентированным, и вы можете столкнуться с некоторыми потенциально трудными для отладки проблемами!

Я бы рекомендовал воспользоваться этой возможностью, чтобы взглянуть на Joda , который является гораздо более продуманным (и поточно-ориентированным) API. Он составляет основу JSR-310, который является новым предложенным Java Date API.

Я понимаю, что это немного больше работы. Однако, вероятно, стоит учесть, что на данный момент вам приходится проводить рефакторинг кода.

3 голосов
/ 18 марта 2009

Если вы посмотрите на источник метода Date.parse (String s), о котором упоминает Николас, вы увидите, что будет трудно или невозможно построить формат даты, который точно воспроизводит поведение.

Если вы просто хотите исключить предупреждение, вы можете поместить @SuppressWarnings({“deprecation”}) вне метода, вызывающего конструктор Date (String).

Если вы действительно хотите обеспечить будущий доступ к этому поведению с будущими JRE, вы можете просто извлечь метод из источников JDK и поместить его в свои собственные источники. Это потребует тщательного прочтения лицензий на исходный код и рассмотрения их применения в вашем конкретном проекте, и может вообще быть недопустимым.

2 голосов
/ 18 марта 2009

Краткий ответ (до дальнейшего расследования): нет, он не эквивалентен. конструктор Date (String toParse) эквивалентен методу разбора класса Date (который также не рекомендуется) ... И javadoc этого метода заявляет:

Обратите внимание, что это немного отличается от интерпретации лет менее 100, используемой в SimpleDateFormat.

Если это единственное изменение, думаю, вы можете пойти по этому пути.

2 голосов
/ 18 марта 2009

DateFormat имеет статические методы, которые возвращают экземпляры DateFormat. Я не знаю, какой из них (если есть) ведет себя так же, как Date(String s), но здесь вы идете:

DateFormat.getInstance()
DateFormat.getDateInstance()
DateFormat.getTimeInstance()
DateFormat.getDateTimeInstance()
1 голос
/ 12 мая 2019

ТЛ; др

ZonedDateTime.format( 
    input , 
    DateTimeFormatter.ofPattern( 
        "EEE MMM dd HH:mm:ss zzz uuuu" , 
        Locale.ENGLISH 
    ) 
)

java.time

Ужасные классы Date и DateFormat были вытеснены несколько лет назад современными java.time классами с принятием JSR 310 .

Конструктор , на который вы ссылаетесь , фактически вызывает статический метод Date.parse. Как объясняется в этой документации, этот метод принимает различные форматы. В java.time есть одна точка для такого же поведения. Однако я сомневаюсь, что ваше приложение сталкивается со всеми этими синтаксисами различных форматов одновременно.

Я предлагаю вам взглянуть на конкретные форматы, используемые вашими фактическими данными. Затем создайте коллекцию из DateTimeFormatter объектов, чтобы соответствовать. Обратите внимание, что в отличие от устаревших классов, java.time классы полностью поточно-безопасные . Таким образом, вы можете хранить один набор форматеров для многократного использования в приложении и в потоках.

Для шаблона форматирования, показанного в принятом ответе, здесь эквивалентен java.time с использованием класса DateTimeFormatter. Обратите внимание, что вы должны явно указать желаемую / ожидаемую локаль, а не полагаться неявно на текущую локаль по умолчанию JVM.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss zzz uuuu" , Locale.ENGLISH ) ;
ZonedDateTime zdt = ZonedDateTime.format( input , f ) ;

По возможности избегайте использования устаревших классов даты и времени, таких как java.util.Date. Но если вам необходимо иметь Date для взаимодействия со старым кодом, который еще не обновлен до java.time , вы можете выполнить конвертацию. Посмотрите на новые методы преобразования, добавленные к старым классам.

Псевдоним java.util.Date представляет момент в UTC. Его современный эквивалент это java.time.Instant класс. Мы можем извлечь Instant из нашего ZonedDateTime. Затем преобразовать в Date.

Instant instant = zdt.toInstant() ;        // Adjust from time zone to UTC.
java.util.Date d = Date.from( instant ) ;  // Convert from modern class `Instant` to legacy class `Date`. 

В другом направлении.

Instant instant = d.toInstant() ;                                        // Convert from legacy class `Date` to modern class `Instant`. 
ZonedDateTime zdt = instant.atZone( ZoneId.of( "Pacific/Auckland" ) ) ;  // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).

О java.time

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

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

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

Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.

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

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

1 голос
/ 10 мая 2019

Чтобы проанализировать строку даты и времени в формате ISO, вы должны использовать DateFormat следующим образом:

java.text.DateFormat.getDateInstance().parse(dt);

С SimpleDateFormat вам нужно знать формат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...