хорошо, есть новые возможности HTML5 для доступа к собственной камере устройства - «API-интерфейс getUserMedia»
ПРИМЕЧАНИЕ. HTML5 может обрабатывать захват фотографий с веб-страницы на устройствах Android (по крайней мере, в последних версиях, управляемый ОС Honeycomb, но он не может обрабатывать его на iPhone, но iOS 6).
Эта проблема уже сообщалась в JDK-bug-log . Стивен Коулборн упоминает следующее решение:
DateTimeFormatter dtf =
new DateTimeFormatterBuilder()
.appendPattern("yyyyMMddHHmmss")
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.toFormatter();
Примечание. Это обходное решение не охватывает ваш случай использования только двух символов шаблона SS. Настройкой может быть только использование других полей, таких как MICRO_OF_SECOND (6 раз SSSSSS) или NANO_OF_SECOND (9 раз SSSSSSSSS).
@PeterLawrey О значении символа шаблона «S» см. эту документацию :
Фракция: Выводит поле nano-of-second как долю секунды. Значение nano-of-second имеет девять цифр, поэтому количество букв шаблона составляет от 1 до 9. Если оно меньше 9, то значение nano-of-second усекается, и выводятся только самые значащие цифры. При синтаксическом анализе в строгом режиме количество проанализированных цифр должно соответствовать количеству букв шаблонов. При разборе в режиме смягчения количество проанализированных цифр должно быть не менее, чем число букв шаблонов, до 9 цифр.
blockquote>Таким образом, мы видим, что S обозначает любую долю секунды (в том числе наносекунды), а не только миллисекунды. К сожалению, дробная часть в данный момент не очень хорошо воспринимается при смежном разборе значений.
EDIT:
В качестве фона здесь приведены некоторые замечания о смежном анализе значений. До тех пор, пока поля разделяются литералами, такими как десятичные точки или разделители временной части (двоеточие), интерпретация полей в анализируемом тексте не является сложной задачей, потому что синтаксический анализатор тогда легко знает, когда останавливаться, т.е. когда часть поля заканчивается и когда начинается следующее поле. Поэтому парсер JSR-310 может обрабатывать текстовую последовательность, если вы указываете десятичную точку.
Но если у вас есть последовательность смежных цифр, охватывающих несколько полей, возникают некоторые трудности с реализацией. Чтобы позволить парсеру знать, когда поле останавливается в тексте, необходимо заранее проинструктировать парсер, что данное поле представлено фиксированной шириной символов цифр. Это работает со всеми
appendValue(...)
-методами, которые принимают численные представления.К сожалению, JSR-310 не сумел сделать это также с дробной частью (
appendFraction(...)
). Если вы ищете ключевое слово «смежное» в javadoc классаDateTimeFormatterBuilder
, вы обнаружите, что эта функция ТОЛЬКО реализована с помощью методовappendValue(...)
. Обратите внимание, что спецификация для буквы шаблона S немного отличается, но внутренне делегируетappendFraction()
-метод. Я предполагаю, что мы, по крайней мере, должны будем связываться до Java 9 (как сообщается в JDK-журнале ошибок или позже) до тех пор, пока фракционные части не смогут управлять парсингами смежных значений.
Update от 2015-11-25:
Следующий код с использованием двух цифр разряда не работает и выдает
DateTimeParseException
.DateTimeFormatter dtf = new DateTimeFormatterBuilder() .appendPattern("yyyyMMddHHmmssSS") .appendValue(ChronoField.MILLI_OF_SECOND, 2) .toFormatter(); String input = "2011120312345655"; LocalDateTime.parse(input, dtf); // abort
Обходной путь
String input = "2011120312345655"; SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSS"); Date d = sdf.parse(input); System.out.println(d.toInstant()); // 2011-12-03T12:34:56.055Z
не работает, потому что
SimpleDateFormat
неправильно интерпретирует дробь (см. вывод, 55 мс вместо 550 мс).То, что остается в качестве решения, либо ждет долгое время, дольше, чем Java 9 (или позже?), либо записывает ваш собственный взлом или использует сторонние библиотеки в качестве решения.
Решение на основе грязного взлома:
String input = "2011120312345655"; DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); int len = input.length(); LocalDateTime ldt = LocalDateTime.parse(input.substring(0, len - 2), dtf); int millis = Integer.parseInt(input.substring(len - 2)) * 10; ldt = ldt.plus(millis, ChronoUnit.MILLIS); System.out.println(ldt); // 2011-12-03T12:34:56.550
Решение с использованием Joda-Time :
String input = "2011120312345655"; DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyyMMddHHmmssSS"); System.out.println(dtf.parseLocalDateTime(input)); // 2011-12-03T12:34:56.550
Решение с использованием моего библиотека Time4J :
String input = "2011120312345655"; ChronoFormatter<PlainTimestamp> f = ChronoFormatter.ofTimestampPattern("yyyyMMddHHmmssSS", PatternType.CLDR, Locale.ROOT); System.out.println(f.parse(input)); // 2011-12-03T12:34:56.550
Обновление от 2016-04-29:
Как люди могут видеть по упомянутой выше проблеме JDK, теперь он помечен как разрешенный - для Java 9.
Вот алгоритм, который корректирует порядок конечных нулей, которые обычно возвращаются из форматированной даты String
.
/**
* Takes a Date and provides the format whilst compensating for the mistaken representation of sub-second values.
* i.e. 2017-04-03-22:46:19.000991 -> 2017-04-03-22:46:19.991000
* @param pDate Defines the Date object to format.
* @param pPrecision Defines number of valid subsecond characters contained in the system's response.
* */
private static final String subFormat(final Date pDate, final SimpleDateFormat pSimpleDateFormat, final int pPrecision) throws ParseException {
// Format as usual.
final String lString = pSimpleDateFormat.format(pDate);
// Count the number of characters.
final String lPattern = pSimpleDateFormat.toLocalizedPattern();
// Find where the SubSeconds are.
final int lStart = lPattern.indexOf('S');
final int lEnd = lPattern.lastIndexOf('S');
// Ensure they're in the expected format.
for(int i = lStart; i <= lEnd; i++) { if(lPattern.charAt(i) != 'S') {
// Throw an Exception; the date has been provided in the wrong format.
throw new ParseException("Unable to process subseconds in the provided form. (" + lPattern + ").", i);
} }
// Calculate the number of Subseconds. (Account for zero indexing.)
final int lNumSubSeconds = (lEnd - lStart) + 1;
// Fetch the original quantity.
String lReplaceString = lString.substring(lStart + (lNumSubSeconds - pPrecision), lStart + lNumSubSeconds);
// Append trailing zeros.
for(int i = 0; i < lNumSubSeconds - pPrecision; i++) { lReplaceString += "0"; }
// Return the String.
return lString.substring(0, lStart) + lReplaceString;
}