Я использую Spring 3.1 и Spring JPA Data. У меня была аналогичная проблема. Я постоянно получал ошибку при попытке обновить несколько записей в 1 запросе.
Итак, у меня было что-то вроде этого.
@Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2")
public void updateAllUsers(long state, long serverid);
Ошибка:
org.hibernate.hql.QueryExecutionRequestException: Not supported for DML operations
Итак, после поиска в Интернете какое-то время я узнал, что вам нужно добавить @Modification.
@Modifying
@Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2")
public void updateAllUsers(long state, long serverid);
Но потом я получил следующую ошибку:
...
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query;
nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
...
Итак, я решил, что проблема теперь была проблемой транзакций, и я вернулся в Google, чтобы исследовать ее и выяснил, что теперь вы должны добавить @Transactional. Похоже, что @Modifying также требует @Transactional.
@Modifying
@Transactional
@Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2")
public void updateAllUsers(long state, long serverid);
, но затем я получил следующую ошибку:
No value for key [org.apache.commons.dbcp.BasicDataSource (...) ] bound to thread
Снова я искал Google и пришел к выводу, что моя конфигурация была неправильной, и это оказалось правдой. Мне не хватало каких-то xml-конфигураций.
<beans:bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<beans:property name="entityManagerFactory" ref="entityManagerFactory"/>
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
Это было длинное путешествие, но я наконец-то получил его. Надеюсь, это поможет кому-то, пытаясь «оплатить его», поскольку многие другие помогли мне с их замечательными блогами, ответами и комментариями.
Это трудный путь, и те методы java.util.Date
setter устарели со времен Java 1.1 (1997). Просто форматируйте дату, используя SimpleDateFormat
, используя шаблон формата, соответствующий входной строке .
В вашем конкретном случае «2 января 2010» в качестве входной строки:
MMMM
для него d
шаблон для него. yyyy
.
String string = "January 2, 2010";
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
System.out.println(date); // Sat Jan 02 00:00:00 GMT 2010
Обратите внимание на важность явного аргумента Locale
. Если вы опустите его, то он будет использовать default locale , который не обязательно является английским, как используется в имени месяца входной строки. Если языковой стандарт не совпадает со строкой ввода, то вы с недоумением получите java.text.ParseException
, даже если шаблон формата кажется действительным.
Вот выдержка из релевантности javadoc g2], перечисляя все доступные шаблоны формата: Обратите внимание, что шаблоны чувствительны к регистру и что текстовые шаблоны из четырех символов или более представляют собой полную форму; в противном случае используется короткая или сокращенная форма. Так, например, Вот несколько примеров правильных шаблонов Важно отметить, что Если вы находитесь на Java 8 или новее, используйте Letter Date or Time Component Presentation Examples
------ ---------------------- ------------------ -------------------------------------
G Era designator Text AD
y Year Year 1996; 96
Y Week year Year 2009; 09
M/L Month in year Month July; Jul; 07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day in week Text Tuesday; Tue
u Day number of week Number 1
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
X Time zone ISO 8601 time zone -08; -0800; -08:00
MMMMM
или больше не нужно. SimpleDateFormat
для синтаксического анализа данной строки на сегодняшний день: Input string Pattern
------------------------------------ ----------------------------
2001.07.04 AD at 12:08:56 PDT yyyy.MM.dd G 'at' HH:mm:ss z
Wed, Jul 4, '01 EEE, MMM d, ''yy
12:08 PM h:mm a
12 o'clock PM, Pacific Daylight Time hh 'o''clock' a, zzzz
0:08 PM, PDT K:mm a, z
02001.July.04 AD 12:08 PM yyyyy.MMMM.dd GGG hh:mm aaa
Wed, 4 Jul 2001 12:08:56 -0700 EEE, d MMM yyyy HH:mm:ss Z
010704120856-0700 yyMMddHHmmssZ
2001-07-04T12:08:56.235-0700 yyyy-MM-dd'T'HH:mm:ss.SSSZ
2001-07-04T12:08:56.235-07:00 yyyy-MM-dd'T'HH:mm:ss.SSSXXX
2001-W27-3 YYYY-'W'ww-u
SimpleDateFormat
не является потокобезопасным. Другими словами, вы никогда не должны объявлять и назначать его как статическую или экземплярную переменную, а затем повторно использовать ее из разных методов / потоков. Вы всегда должны создавать его в рамках локальной области метода.
Обновление Java 8
DateTimeFormatter
(также здесь, щелкните ссылку, чтобы увидеть все предопределенные форматы и доступные шаблоны формата; учебник доступен здесь ).
String string = "January 2, 2010";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(string, formatter);
System.out.println(date); // 2010-01-02
Примечание: если ваш шаблон формата также содержит часть времени, используйте LocalDateTime#parse(text, formatter)
вместо LocalDate#parse(text, formatter)
. И, если ваш шаблон формата также содержит часовой пояс, используйте вместо него ZonedDateTime#parse(text, formatter)
.
Вот выдержка из релевантности javadoc , перечисляя все доступные шаблоны формата:
Symbol Meaning Presentation Examples
------ -------------------------- ------------ ----------------------------------------------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
D day-of-year number 189
M/L month-of-year number/text 7; 07; Jul; July; J
d day-of-month number 10
Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
Y week-based-year year 1996; 96
w week-of-week-based-year number 27
W week-of-month number 4
E day-of-week text Tue; Tuesday; T
e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
F week-of-month number 3
a am-pm-of-day text PM
h clock-hour-of-am-pm (1-12) number 12
K hour-of-am-pm (0-11) number 0
k clock-hour-of-am-pm (1-24) number 0
H hour-of-day (0-23) number 0
m minute-of-hour number 30
s second-of-minute number 55
S fraction-of-second fraction 978
A milli-of-day number 1234
n nano-of-second number 987654321
N nano-of-day number 1234000000
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
z time-zone name zone-name Pacific Standard Time; PST
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z zone-offset offset-Z +0000; -0800; -08:00;
Обратите внимание, что для более популярных шаблонов имеется несколько предопределенных форматировщиков . Таким образом, вместо, например, DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
, вы можете использовать DateTimeFormatter.RFC_1123_DATE_TIME
. Это возможно, потому что они, напротив, SimpleDateFormat
, потокобезопасны. Таким образом, вы также можете определить свои собственные.
Для определенного формата входной строки вам не нужно использовать явный DateTimeFormatter
: стандартную дату ISO 8601 , как и 2016-09-26T17: 44: 57Z, может быть проанализирован непосредственно с помощью LocalDateTime#parse(text)
, поскольку он уже использует форматтер ISO_LOCAL_DATE_TIME
. Аналогично, LocalDate#parse(text)
анализирует дату ISO без временной составляющей (см. ISO_LOCAL_DATE
), а ZonedDateTime#parse(text)
анализирует дату ISO с добавлен смещение и часовой пояс (см. ISO_ZONED_DATE_TIME
).
Для Android
Calendar.getInstance (). getTime () дает
Thu Jul 26 15:54:13 GMT+05:30 2018
Используйте
String oldDate = "Thu Jul 26 15:54:13 GMT+05:30 2018";
DateFormat format = new SimpleDateFormat("EEE LLL dd HH:mm:ss Z yyyy");
Date updateLast = format.parse(oldDate);
Хотя некоторые из ответов являются технически правильными, они нецелесообразны.
Несколько заметок о Joda-Time следуют.
В Joda-Time , объект DateTime действительно знает свой собственный назначенный часовой пояс. Это контрастирует с классом java.util.Date, который , кажется, имеет часовой пояс, но не делает.
Обратите внимание, что в приведенном ниже примере мы передаем объект часового пояса в форматтер который анализирует строку. Этот часовой пояс используется для интерпретации того времени, которое произошло в этом часовом поясе. Поэтому вам нужно подумать и определить часовой пояс, представленный этим строковым вводом.
Поскольку у вас нет временной части в вашей строке ввода, Joda-Time назначает первый момент дня указанного часового пояса как время суток. Обычно это означает 00:00:00
, но не всегда, из-за Летнее время (DST) или других аномалий. Кстати, вы можете сделать то же самое с любым экземпляром DateTime, вызвав withTimeAtStartOfDay
.
Символы, используемые в шаблоне форматирования, аналогичны в Joda-Time для тех в java.util.Date/Calendar, но не совсем то же самое. Внимательно прочитайте документ.
Обычно мы используем неизменяемые классы в Joda-Time. Вместо того, чтобы изменять существующий объект Date-Time, мы вызываем методы, которые создают новый новый экземпляр на основе другого объекта с большинством аспектов, скопированных, за исключением тех случаев, когда желательны изменения. Примером является вызов withZone
в последней строке ниже. Неизменность помогает сделать Joda-Time очень потокобезопасным, а также может сделать некоторую работу более ясной.
Вам понадобится java.util. Объекты Date для использования с другими классами / структурами, которые не знают о объектах Joda-Time. К счастью, очень легко перемещаться взад и вперед.
Переход от объекта java.util.Date (с именем date
) к Joda-Time DateTime ...
org.joda.time.DateTime dateTime = new DateTime( date, timeZone );
Переход в другое направление от Joda-Time до объекта java.util.Date ...
java.util.Date date = dateTime.toDate();
String input = "January 2, 2010";
java.util.Locale locale = java.util.Locale.US;
DateTimeZone timeZone = DateTimeZone.forID( "Pacific/Honolulu" ); // Arbitrarily chosen for example.
DateTimeFormatter formatter = DateTimeFormat.forPattern( "MMMM d, yyyy" ).withZone( timeZone ).withLocale( locale );
DateTime dateTime = formatter.parseDateTime( input );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTime in UTC/GMT: " + dateTime.withZone( DateTimeZone.UTC ) );
При запуске ...
dateTime: 2010-01-02T00:00:00.000-10:00
dateTime in UTC/GMT: 2010-01-02T10:00:00.000Z
Моя скромная программа испытаний. Я использую его, чтобы играть с форматированием и искать длинные даты, которые я нахожу в лог-файлах (но кто их там поместил ...).
Моя тестовая программа:
package be.test.package.time;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
public class TimeWork {
public static void main(String[] args) {
TimeZone timezone = TimeZone.getTimeZone("UTC");
List<Long> longs = new ArrayList<>();
List<String> strings = new ArrayList<>();
//Formatting a date needs a timezone - otherwise the date get formatted to your system time zone.
//Use 24h format HH. In 12h format hh can be in range 0-11, which makes 12 overflow to 0.
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS");
formatter.setTimeZone(timezone);
Date now = new Date();
//Test dates
strings.add(formatter.format(now));
strings.add("01-01-1970 00:00:00.000");
strings.add("01-01-1970 00:00:01.000");
strings.add("01-01-1970 00:01:00.000");
strings.add("01-01-1970 01:00:00.000");
strings.add("01-01-1970 10:00:00.000");
strings.add("01-01-1970 12:00:00.000");
strings.add("01-01-1970 24:00:00.000");
strings.add("02-01-1970 00:00:00.000");
strings.add("01-01-1971 00:00:00.000");
strings.add("01-01-2014 00:00:00.000");
strings.add("31-12-1969 23:59:59.000");
strings.add("31-12-1969 23:59:00.000");
strings.add("31-12-1969 23:00:00.000");
//Test data
longs.add(now.getTime());
longs.add(-1L);
longs.add(0L); //Long date presentation at - midnight 1/1/1970 UTC - The timezone is important!
longs.add(1L);
longs.add(1000L);
longs.add(60000L);
longs.add(3600000L);
longs.add(36000000L);
longs.add(43200000L);
longs.add(86400000L);
longs.add(31536000000L);
longs.add(1388534400000L);
longs.add(7260000L);
longs.add(1417706084037L);
longs.add(-7260000L);
System.out.println("===== String to long =====");
//Show the long value of the date
for (String string: strings) {
try {
Date date = formatter.parse(string);
System.out.println("Formated date : " + string + " = Long = " + date.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
}
System.out.println("===== Long to String =====");
//Show the date behind the long
for (Long lo : longs) {
Date date = new Date(lo);
String string = formatter.format(date);
System.out.println("Formated date : " + string + " = Long = " + lo);
}
}
}
Результаты испытаний:
===== String to long =====
Formated date : 05-12-2014 10:17:34.873 = Long = 1417774654873
Formated date : 01-01-1970 00:00:00.000 = Long = 0
Formated date : 01-01-1970 00:00:01.000 = Long = 1000
Formated date : 01-01-1970 00:01:00.000 = Long = 60000
Formated date : 01-01-1970 01:00:00.000 = Long = 3600000
Formated date : 01-01-1970 10:00:00.000 = Long = 36000000
Formated date : 01-01-1970 12:00:00.000 = Long = 43200000
Formated date : 01-01-1970 24:00:00.000 = Long = 86400000
Formated date : 02-01-1970 00:00:00.000 = Long = 86400000
Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000
Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000
Formated date : 31-12-1969 23:59:59.000 = Long = -1000
Formated date : 31-12-1969 23:59:00.000 = Long = -60000
Formated date : 31-12-1969 23:00:00.000 = Long = -3600000
===== Long to String =====
Formated date : 05-12-2014 10:17:34.873 = Long = 1417774654873
Formated date : 31-12-1969 23:59:59.999 = Long = -1
Formated date : 01-01-1970 00:00:00.000 = Long = 0
Formated date : 01-01-1970 00:00:00.001 = Long = 1
Formated date : 01-01-1970 00:00:01.000 = Long = 1000
Formated date : 01-01-1970 00:01:00.000 = Long = 60000
Formated date : 01-01-1970 01:00:00.000 = Long = 3600000
Formated date : 01-01-1970 10:00:00.000 = Long = 36000000
Formated date : 01-01-1970 12:00:00.000 = Long = 43200000
Formated date : 02-01-1970 00:00:00.000 = Long = 86400000
Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000
Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000
Formated date : 01-01-1970 02:01:00.000 = Long = 7260000
Formated date : 04-12-2014 15:14:44.037 = Long = 1417706084037
Formated date : 31-12-1969 21:59:00.000 = Long = -7260000
С Java 8 мы получаем новый API Date / Time ( JSR 310 ).
Следующий способ можно использовать для синтаксического анализа даты на Java 8 без использования Joda-Time :
String str = "January 2, 2010";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(str, formatter);
// access date fields
int year = date.getYear(); // 2010
int day = date.getDayOfMonth(); // 2
Month month = date.getMonth(); // JANUARY
int monthAsInt = month.getValue(); // 1
LocalDate - стандартный класс Java 8 для представления даты (без времени). Если вы хотите анализировать значения, содержащие информацию о дате и времени, вы должны использовать LocalDateTime . Для значений с часовыми поясами используйте ZonedDateTime . Оба обеспечивают метод parse()
, аналогичный LocalDate
:
LocalDateTime dateWithTime = LocalDateTime.parse(strWithDateAndTime, dateTimeFormatter);
ZonedDateTime zoned = ZonedDateTime.parse(strWithTimeZone, zoneFormatter);
Символы форматирования списка из DateTimeFormatter Javadoc :
All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters.
The following pattern letters are defined:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
D day-of-year number 189
M/L month-of-year number/text 7; 07; Jul; July; J
d day-of-month number 10
Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
Y week-based-year year 1996; 96
w week-of-week-based-year number 27
W week-of-month number 4
E day-of-week text Tue; Tuesday; T
e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
F week-of-month number 3
a am-pm-of-day text PM
h clock-hour-of-am-pm (1-12) number 12
K hour-of-am-pm (0-11) number 0
k clock-hour-of-am-pm (1-24) number 0
H hour-of-day (0-23) number 0
m minute-of-hour number 30
s second-of-minute number 55
S fraction-of-second fraction 978
A milli-of-day number 1234
n nano-of-second number 987654321
N nano-of-day number 1234000000
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
z time-zone name zone-name Pacific Standard Time; PST
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z zone-offset offset-Z +0000; -0800; -08:00;
У меня была задача, когда мне приходилось писать код, который бы взял любую строку и попытался преобразовать ее в дату, когда формат строки неизвестен заранее.
Я написал интересную утилиту. Вот статья, в которой описывается идея: Java 8 java.time package: анализ любой строки на дату . Это было реализовано на Java 8, но идея могла быть реализована и в более ранних версиях.
Ах, да, обсуждение Java Date снова. Для обработки даты мы используем Date , Calendar , GregorianCalendar и SimpleDateFormat . Например, используя вашу январскую дату в качестве входных данных:
Calendar mydate = new GregorianCalendar();
String mystring = "January 2, 2010";
Date thedate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(mystring);
mydate.setTime(thedate);
//breakdown
System.out.println("mydate -> "+mydate);
System.out.println("year -> "+mydate.get(Calendar.YEAR));
System.out.println("month -> "+mydate.get(Calendar.MONTH));
System.out.println("dom -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod -> "+mydate.get(Calendar.HOUR_OF_DAY));
Тогда вы можете манипулировать этим с помощью чего-то вроде:
Calendar now = Calendar.getInstance();
mydate.set(Calendar.YEAR,2009);
mydate.set(Calendar.MONTH,Calendar.FEBRUARY);
mydate.set(Calendar.DAY_OF_MONTH,25);
mydate.set(Calendar.HOUR_OF_DAY,now.get(Calendar.HOUR_OF_DAY));
mydate.set(Calendar.MINUTE,now.get(Calendar.MINUTE));
mydate.set(Calendar.SECOND,now.get(Calendar.SECOND));
// or with one statement
//mydate.set(2009, Calendar.FEBRUARY, 25, now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
System.out.println("mydate -> "+mydate);
System.out.println("year -> "+mydate.get(Calendar.YEAR));
System.out.println("month -> "+mydate.get(Calendar.MONTH));
System.out.println("dom -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod -> "+mydate.get(Calendar.HOUR_OF_DAY));
Попробуйте
String date = get_pump_data.getString("bond_end_date");
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date datee = (Date)format.parse(date);
O
, как разрешить печатьUTC+08:00
вместоGMT+08:00
. Я не мог получить никакого примера. – theGamblerRises 18 April 2018 в 14:2620-JUN-16 12.00.00.000000000 AM
, нужна помощь, чтобы преобразовать ее в Date. Ваша помощь очень ценится! – mannedear 24 July 2018 в 06:57