I'm getting the following error when trying to pass a date object from AngularJS to java spring backend:
Failed to convert from type [java.lang.String] to type
[#javax.persistence.Column java.sql.Timestamp] for value
'2018-06-12T22:00:00.000Z'; nested exception is
java.lang.IllegalArgumentException: Timestamp format must be
yyyy-mm-dd hh:mm:ss[.fffffffff]
So far I tried to format the date object to a string in the expected format:
$filter('date')(date, "yyyy-MM-dd hh:mm:ss");
which leads to an error telling:
Error: [ngModel:datefmt] Expected 2018-06-13 12:00:00 to be a date
Seems like I need to pass a date object but I can't find a way to influence the date format AngularJS is attempting to convert to.
java.time.Instant
Your backend service is outdated, using a legacy class java.sql.Timestamp. That class was supplanted years ago by java.time.Instant.
If you make that change your backend to use Instant, you’ll have no problem passing a String such as 2018-06-12T22:00:00.000Z. That string is using a standard format defined in ISO 8601. That format is the ideal way to exchange date-time values as text.
The java.time classes use ISO 8601 formats by default. So no need to specify a formatting pattern.
I know Hibernate has been updated to support the java.time classes. I don’t know about JPA. (I don’t use either.)
You can convert a date string to a date object using any format like this:
Date parseDateString(String dateString){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = dateFormat.parse(dateString);
}
You can read more about it in the documentation
Related
This question already has answers here:
Converting a date string to a DateTime object using Joda Time library
(10 answers)
Closed 6 years ago.
Is there a way to convert a date in the format "YYYY-MM-dd" to "YYYY-MM-dd HH:mm:ss" using Joda?
Eg: "2016-01-21" to "2016-01-21 00:00:00"
Use DateTimeFormat class from Joda API. It helps you to format the date to the formatting of your choice. You can simply provide the format you want, like in this case you want "YYYY-MM-dd HH:mm:ss". The code below works with JodaTime 2.0 and above.
DateTime date = DateTime.parse("2016-01-21", DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss"));
There are two things in play here, first we need to parse the existing string into a DateTime object, which is done via the parse method, it also allows an additional argument, to convert the output into a different format. The longer but easier to understand implementation is given below.
DateTime date = DateTime.parse("2016-01-21");
DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss");
date = formatter.parseDateTime(string);
Your question is not clear:
Do you want to just format "something representing a date" into a string with time of "00:00:00"?
Or are you trying to convert "something representing a date" into "something representing a date+time, with 00:00:00 as time"?
Or are you trying to convert a java.util.Date to a Joda org.joda.time.DateTime by ignoring the original time and set time to 00:00:00?
Or are you trying to convert a string of date with format of "YYYY-MM-dd" to another String with date+time, with 00:00:00 as time?
Or something else?
In Joda, the proper way to represent a date is by LocalDate, and the proper way to represent a "date + time" information (but not a instant of time) is by LocalDateTime. DateTime is representing a instant of time. With these basic understanding:
Answer for Q1:
String result = DateTimeFormat.forPattern("YYYY-MM-dd", myLocalDate);
Answer for Q2:
LocalDateTime result = myLocalDate.toLocalDateTime(LocalTime.MIDNIGHT);
Answer for Q3:
DateTime result = new DateTime(javaUtilDate).withTimeAtStartOfDay();
Answer for Q4:
String result = dateString + " 00:00:00";
I'm having a problem with SimpleDateFormat. I have inputfields in my HTML-page with type = date. I want to save these values into my database where they should be saved as dates. I already figured out how to do this and it works. The only probem I encouter is the way the dates are represented in the database.
I want them to be representated as dd-MM-yyyy. Let's say I want to display 01-06-2016 into my database. When doing this with the code I have..it gives me 0006-12-07. Strangely..when I change my pattern into yyyy-MM-dd...it does give me exactly what the pattern says: 2016-06-01. But it doesn't work the other way round.
String parameter = request.getParameter("instroomdatum");
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
try {
Date parsed = sdf.parse(parameter);
java.sql.Date sql = new java.sql.Date(parsed.getTime());
student.setInstroomdatum(sql);
} catch (ParseException ex) {
Logger.getLogger(StudentController.class.getName()).log(Level.SEVERE, null, ex);
}
Can somebody please explain me what's going on and how to fix this problem? It's really annoying.
EDIT: I tried printing the value of parameter with a simple PrintWriter-object for the specific date 01-06-2016. It shows me 2016-06-01, even though my pattern in the code above is set to dd-MM-yyyy.
You are confusing the display format with the internal representation.
Dates in a database are not represented in any specific display format, such as YYYY-MM-DD. Database dates are normally stored in a numeric form that represents a certain number of seconds and milliseconds (or nanoseconds) from some fixed starting point.
The display format is applied dynamically when you query the database and ask for the date/time as a string, but if you ask for it as a Date object, you get the internal representation, encapsulated in a java.sql.Date.
It is up to your Java code to format the date as you need it.
In your particular example (according to your comment), the string returned by your input method is 2016-06-01, so you need to parse it with the pattern yyyy-MM-dd. This will correctly convert the external representation to a valid Date object.
But how should i specifically change this representation to dd-MM-yyyy
Once you have it as Date, you can immediately turn around and convert the Date back into a String with a different SimpleDateFormat specification.
Date-Time != String
As explained in the correct Answer by Garrison, you must understand that a date’s value internally in a database or in a language such as Java is distinct is distinct from a String generated to represent or communicate that value.
How the date is internally tracked varies amongst databases and languages, and is irrelevant really. What matters is the interface provided by which you can fetch or put your app’s values. A separate issue is how to represent those values as Strings for presentation to your user.
Database (internal) ↔ Driver (JDBC) ↔ App (java.time) ↔ Presentation (String)
java.time
Also, the Question and the other Answers are using old outmoded classes, the date-time classes bundled with the earliest versions of Java. Those classes have been supplanted by the java.time classes built into Java 8 and later. See Oracle Tutorial. Much of the functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
LocalDate
Amongst the java.time classes is LocalDate to represent a date-only value without time-of-day and without time zone. The old java.util.Date class, despite its unfortunate name, tracks both a date and a time-of-day. The old java.sql.Date pretends to represent a date-only but in fact, in an unfortunate design decision, extends from java.util.Date so it inherits both a date and a time-of-day, but you are instructed in the class doc to pretend that it is not a subclass. (yes, that is an unpleasant mess)
Do all your business logic using the java.time classes such as LocalDate.
Strings & ISO 8601
As for strings, use the standard ISO 8601 formats. For serializing date-only values, that means YYYY-MM-DD. The java.time classes use ISO 8601 formats by default when parsing/generating strings that represent date-time values.
LocalDate localDate = LocalDate.parse( "2016-06-01" );
But try to stick with objects. Serialize to strings only when you must.
Database
No need for strings when getting data to/from a database. The job of a JDBC driver is to figure out how to move a Java object to/from a data type of your database column.
With a driver that complies with JDBC 4.2, you should be able to use the getObject and setObject methods on a PreparedStatement to deal directly with java.time types.
myPreparedStatement.setObject( 1 , localDate );
If your driver does not support that, you must fall back onto the java.sql.Date class. Look for new methods added to the old classes to go back and forth with java.time types.
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
And the other direction.
LocalDate localDate = sqlDate.toLocalDate();
Generate Strings
Apply a format to generate a string as needed for presentation to a user. Use the DateTimeFormatter class. You can define your own formatting pattern.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd-MM-yyyy" );
String output = localDate.format( formatter ); // 01-06-2016
Better yet, let java.time localize to the human language and cultural norms of the user’s desired/expected Locale.
Locale locale = Locale.CANADA_FRENCH;
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT , locale );
String output = localDate.format( formatter );
You will need to use the formatter to generate a String for presentation to the user, and to parse input made by the user. You or your users may wish instead to take data-entry as three separate fields: year, month, and day-of-month.
LocalDate localDate = LocalDate.of( 2016 , 6 , 1 );
If all you want to do is format your date into 01-06-2016 format. Try this
String parameter = "0006-12-07";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date parsed = sdf.parse(parameter);
sdf = new SimpleDateFormat("dd-MM-yyyy");
System.out.println(sdf.format(parsed)); //Prints out your desired format 07-12-0006
java.sql.Date sql = new java.sql.Date(parsed.getTime());
student.setInstroomdatum(sql);
} catch (ParseException ex) {
Logger.getLogger(StudentController.class.getName()).log(Level.SEVERE,null, ex);
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
java.sql.Date someDate;
Date anotherDate = format.parse(/*needVariables*/.getOutDate());
someDate = new java.sql.Date(anotherDate.getTime());
work for me
I need to convert JsDate to java.util.Date. I searched but I couldn't find anything. So could you help me with this problem?
Edit: I do this conversion process on GWT screen. I have Datepicker on screen and it gives me JsDate value when I use it's getValue() method. So I'm supposed to put this value into the property of an object which has Date type.
ObjectName.setDate(PickerName.getValue());
I hope my edit will be more clear.
Edit2:
This line is the solution of my problem:
myObject.setDate(new Date((long) myPicker.getValue().getTime()));
The best way of dates conversion is using time in milliseconds, UTC. Both JS Date object and java.util.Date class support conversion to milliseconds (getTime()) and instantiating from milliseconds (using constructor).
You can create a java.util.Date object from the 'time since epoch' value of the JS Date
javascript
var d = new Date().getTime();
java
// get value from client (ajax, form, etc), and construct in Date object
long valueFromClient = ...
Date date = new Date(valueFromClient);
String formatted = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
If people like me are forced to parse a JS-formatted date string (as the result of (new Date()).toString() in JavaScript), here is the SimpleDateFormat spec I used:
DateFormat jsfmt = new SimpleDateFormat("EE MMM d y H:m:s 'GMT'Z (zz)");
If you have control of the producer of the dates, I concur that using timestamps or at least .toUTCString() is definitely more robust.
You may want this:
java:
String jsDate="2013-3-22 10:13:00";
Date javaDate=new SimpleDateFormat("yy-MM-dd HH:mm:ss").parse(jsDate);
System.out.println(javaDate);
ISO 8601 and java.time
ISO 8601 is the international standard for date and time including date and time formats. About any programming language has support for it, including both JavaScript and Java.
In JavaScript produce a string in ISO 8601 format using Date.toISOString(). We don’t need any formatter.
var d = new Date();
var n = d.toISOString();
console.log(n);
The result is somewhat human readable as long as you remember that it’s in UTC, denoted by the trailing Z.
In Java parse the string using Instant.parse(). We don’t need to specify any formatter here either.
String stringFromJavaScript = "2021-07-12T05:54:03.365Z";
Instant inst = Instant.parse(stringFromJavaScript);
System.out.println(inst);
Output:
2021-07-12T05:54:03.365Z
The question asked for a java.util.Date for the result from a date picker. We should avoid using java.util.Date for this both because despite the name a Date does not represent a date and because the Date class is poorly designed and long outdated. For a date without time of day a LocalDate is appropriate:
LocalDate date = inst.atZone(ZoneId.systemDefault()).toLocalDate();
System.out.println(date);
In my time zone the output was:
2021-07-12
The conversion is time zone dependent and will only be correct if the default time zone of the JVM (or which time zone you pass to atZone()) is the same as used by the date picker.
If you do need a Date for a legacy API not yet upgraded to java.time:
Date oldfashionedDate = Date.from(inst);
System.out.println(oldfashionedDate);
Mon Jul 12 07:54:03 CEST 2021
Links
Wikipedia article: ISO 8601
Oracle tutorial: Date Time explaining how to use java.time.
I would suggest using the DateFormat parse method (doc can be found here). It can parse a string representation of a date and return a java.util.Date.
JS Date --
new Date()
Wed Aug 14 2019 14:54:38 GMT+0530 (India Standard Time)
Java Date --
new Date().toISOString()
"2019-08-14T09:25:50.136Z"
In my program I am trying to convert the date to string to specified format and then back to date. I need the date to be in dd-MMM-yy format. So, I am converting the date to dd-MMM-yy format using SimpleDateFormat like,
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy");
String bookingDate = sdf.format(myDate);
The result is what I expected, that is 23-May-12 but when I convert the string back to date
using parse(), it is changing to Wed May 23 13:16:14 IST 2012.
Is there any way to convert the string back to date without changing format? I strictly need to pass the date object in the specified format to the query.
when i convert the string back to date using parse(), it is changing to Wed May 23 13:16:14 IST 2012.
That is not true, It converts back to Date correctly, When you try to print Date instance, It invokes toString() method and it has fixed formated output so if you want the formatted date you need to use format() method
In short parse method parses the String to Date there is no property of Date which holds format so you need to use format() method anyhow
How are you passing the date object in your query, if you are simply appending date in your query string why you need to convert your string date back to date object ? And If you are using prepared statement then you need not worry about the format. And as suggested above Date object does not hold any format information
If You strictly need to pass the date object then there is no worries about its format as Date object has understanding with its format either Java, any java framework or SQL..
And if you are passing the date directly in sql query (concatenating) then you can pass Date String in the same format you see in DB, it will process the same correctly.
You can use DateFormat.getDateInstance(DateFormat.SHORT, <locale>).parse(myDate);.
You will, however, have a date in a standard format like dd/MM/yy, not custom. Template depends on which Locale you use.
You can try building your own Pattern using the standard Java Library or through ThreeTen/JSR-310
We now have a more modern way to do this work.
java.time
The java.time framework is bundled with Java 8 and later. See Tutorial. These new classes are inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extra project. They are a vast improvement over the troublesome confusing old classes, java.util.Date/.Calendar et al.
Date-only class
The new framework offers a class, LocalDate, to represent a date-only without any time-of-day nor time zone.
By the way, using two-digits for year is asking for trouble. I strongly recommend using four-digit years whenever possible. The java.time framework assumes any two-digit years are in the 20xx century, years 2000 to 2099 inclusive.
To parse the string, specify the expected format. You are not using any of the standard ISO 8601 formats, so we must define a format pattern. Specify a Locale that includes the language we expect to find for name-of-month.
// Parse String representation.
String input = "23-May-12";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "d-MMMM-yy" , Locale.ENGLISH ); // Using four "M" characters means we expect the full name of the month.
LocalDate localDate = formatter.parse ( input , LocalDate :: from );
To go the other direction, to generate a string representation of the date value, we can recycle the same formatter.
// Generate String representation.
String output = localDate.format ( formatter );
Dump to console.
System.out.println ( "input: " + input + " → localDate : " + localDate );
System.out.println ( "localDate : " + localDate + " → output: " + output );
When run.
input: 23-May-12 → localDate : 2012-05-23
localDate : 2012-05-23 → output: 23-May-12
I am using Facebook graph API to retrieve user wall information. In that, I am getting the post created time value as:
created_time: "2012-04-19T09:00:02+0000"
Can anyone suggest me how to convert this time to UTC or epoch value in Java?
The format of date you receive is ISO 8601.
As described in Converting ISO8601-compliant String to java.util.Date (using Joda-Time):
DateTimeFormatter parser = ISODateTimeFormat.dateTimeNoMillis();
String jtdate = "2012-04-19T09:00:02+0000";
System.out.println(parser.parseDateTime(jtdate));
You basically need to parse the ISO8601 date format. There are libraries out there that would do it for you or you can create your own parser (relatively simply), e.g.
http://www.java2s.com/Code/Java/Data-Type/ISO8601dateparsingutility.htm