2014-01-23 1 views
1

Ниже представлен код без проблем. Но логически это кажется неправильным. Почему это так?Использование ~ в SimpleDateFormat # parse()

import java.sql.Date; 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 

DateFormat df =new SimpleDateFormat("MM/dd/yyyy"); 

new Date(df.parse("09/01/3~34").getTime()); // Produces '09/01/3' 
new Date(df.parse("09/01/100000").getTime()); // Produces ' 000-09-01' 
+2

1. Парсер останавливается после чтения того, что он может интерпретировать. 2. Парсер может быть * мягким *. –

+0

Какова ценность 'parsedDate'? Я думаю '3-01-09'. –

+0

да, я получил '0003-09-01'. это я получаю даже для 'df.parse (« 09/01/3 ~ qwwww »)' – gowthamvelusamy

ответ

0

Первый вопрос:

new Date(df.parse("09/01/3~34").getTime()); // Produces '09/01/3' 

По DateFormat#parse() JavaDoc:

Анализирует текст с начала данной строки для получения даты. Метод может не использовать весь текст данной строки.

Из-за этого после того, как он разбирает значение из строки, он прекращает поиск на нем. Когда он нашел знак ~, он проанализировал значение 3 в течение года и прекратил смотреть на строку.

Второй вопрос:

new Date(df.parse("09/01/100000").getTime()); // Produces ' 000-09-01' 

Это не производит '000-09-01'. Следующий код:

DateFormat df = new SimpleDateFormat("MM/dd/yyyy"); 
java.util.Date parsedDate = df.parse("09/01/100000"); 

System.out.println(parsedDate); 
System.out.println(df.format(parsedDate)); 

Выходы:

Fri Sep 01 00:00:00 BRT 100000 
09/01/100000 

Однако, как представляется, ошибка с java.sql.Date#toString методом на JDK. Чтобы представить эту java.sql.Date правильно, попробуйте передать его в метод DateFormat#format:

java.sql.Date sqlDt = new java.sql.Date(df.parse("09/01/10000").getTime()); 
System.out.println(df.format(sqlDt)); 

Выход:09/01/100000

+0

в этом случае, почему 'Date parsedDate = new Date (df.parse (" 09/01/100000 "). GetTime());' возвращает '000-09-01' – gowthamvelusamy

+0

Я не использовал java.util.date. . Я использую java.sql.date. Можете ли вы проверить, как работает sql.date с '09/01/100000' – gowthamvelusamy

+0

Это, похоже, ошибка с методом 'java.sql.Date # toString'. По-видимому, он неправильно понимает годы за 9999 год. Чтобы правильно представить эту дату, попробуйте использовать тот же DateFormat: 'df.format (parsedDt)'. – everton

0

О первый вопрос:

Класс SimpleDateFormat очень мягок и просто останавливается, когда некоторые недопустимые символы ударяются. Даже если вы явно поручите ему разобрать строго через df.setLenient(false);, вы заметите здесь тот же вывод и не исключение. JodaTime, JSR-310 или моя библиотека времени корректно отклонят ввод, содержащий недопустимые символы в строгом режиме. Итак, у нас есть явная ошибка в JDK.

О второй вопрос:

Ну, вы используете java.sql.Date вместо java.util.Date. Sql-версия не рассчитана на годы> 9999. Это даже указано в ее javadoc:

«дата миллисекунд с 1 января 1970 года, 00:00:00 GMT не должна превышать представление миллисекунды за 8099 год»,

Не ясно в javadoc, но Oracle говорит о смещении года 1900 г. Таким образом, наконец java.sql.Date поддерживает только диапазон года до 9999. Это соответствует ANSI-SQL, поэтому никакое ограничение в этом году не является ошибкой, но необходимо для взаимодействия с SQL.Вместо этого другой аспект плохой, и, на мой взгляд, ошибка, а именно: если вы кормите конструктор недействительным годом, тогда вы не получите никакого исключения, но внутренне состояние будет тихо настроено на что-то глупое и непредсказуемое.

Вывод:

Избегайте использовать java.sql.Date что-нибудь еще, чем в слое JDBC. Это не для прикладного уровня. Кроме того, java.util.Date, а также SimpleDateFormat (которые являются «стандартными» в Java-pre8) более или менее ужасно нарушены. Хорошими альтернативами являются JodaTime, в Java 8 - новый JSR-310-API или моя библиотека, если он достигнет не-альфа-состояния в один прекрасный день.