Эта проблема уже сообщалась в 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
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.
Для вопроса 2 вам нужно вызвать super в каждом классе:
class First(object):
def __init__(self):
super(First, self).__init__()
print "first"
class Second(object):
def __init__(self):
super(Second, self).__init__()
print "second"
class Third(First, Second):
def __init__(self):
super(Third, self).__init__()
print "that's it"
Для вопроса 3 это невозможно сделать, ваш метод должен иметь одну и ту же подпись. Но вы можете просто игнорировать некоторые параметры в родительских кланах или использовать аргументы ключевых слов.
1) Нет ничего плохого в том, что вы сделали в 1, если вы хотите использовать атрибуты из базового класса, тогда вам нужно вызвать базовый класс init () или даже если ur использует методы из базового класса, которые использует атрибуты своего собственного класса, тогда вам нужно вызвать baseclass init ()
2) Вы не можете использовать super для запуска init с First и Second, потому что python использует MRO (порядок разрешения метода)
см. следующий код: это иерархия алмазов
class A(object):
def __init__(self):
self.a = 'a'
print self.a
class B(A):
def __init__(self):
self.b = 'b'
print self.b
class C(A):
def __init__(self):
self.c = 'c'
print self.c
class D(B,C):
def __init__(self):
self.d = 'd'
print self.d
super(D, self).__init__()
d = D()
print D.mro()
Он печатает:
d
b
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]
MRO питона будет D, B, C, A
, если у B нет метода init для C.
3) Вы не можете использовать все методы, чтобы иметь такую же подпись.