I am trying to retrieve date values from Oracle database using resultset.The format of date is like dd-mmm-yy(like 17-MAY-18).Th column name is VALID_TO here.The default value is set as TO_DATE 01.01.4000 in DB.I am writing code as below.
String sql_qry = "SELECT a.VALID_TO from table1 a where a.VALID_FROM > '01-JAN-
18' and a.VALID_TO > '31-JAN-18'";
this.preparedStatement = dbconnection.prepareStatement(sql_qry);
ResultSet rs = this.preparedStatement.executeQuery();
while (rs.next()) {
AccountDetails detailsVo = new AccountDetails();
detailsVo.setDateColumn(rs.getDate("VALID_TO"));
accountDetails.add(detailsVo);
}
I am getting the default value 01.01.4000 and not the actual date from database.How to fetch actual values.I imported java.sql.Date above.
tl;dr
Use java.time classes rather than legacy date-time classes. Specifically, LocalDate for date-only value.
Use placeholders in your SQL and prepared statement.
Pass java.time objects directly, via JDBC 4.2.
Example:
myPreparedStatement.setObject( 1 , startLocalDate ) ;
myPreparedStatement.setObject( 2 , stopLocalDate ) ;
…and…
myResultSet.getObject( … , LocalDate.class)
java.time
With JDBC 4.2 and later, you can exchange smart objects with your database rather than dumb strings.
Placeholders
Set up your prepared statement using placeholders rather than literals.
String sql = "SELECT * FROM tbl WHERE fromCol >= ? AND toCol < ? ;" ;
LocalDate
Set up the values to fill-in those placeholders. For a date-only column such as SQL-standard type DATE, use the java.time.LocalDate class. The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate start = LocalDate.of( 2018 , Month.JANUARY , 1 ) ; // First of January 2018.
Half-Open
Generally best in date-time work to use the Half-Open approach to defining a span of time, where the beginning is inclusive while the ending is exclusive. So if you want the entire month of January, query for "is equal to or later than the first of the month AND is less than the first day of the following month".
LocalDate stop = start.plusMonths( 1 ) ; // First of February 2018.
Or, your intention might be more clear by using the YearMonth class to represent the entire month as a whole.
YearMonth ym = YearMonth.of( 2018 , 1 ) ; // January 2018.
LocalDate start = ym.atDay( 1 ) ; // First of January 2018.
LocalDate stop = ym.plusMonths( 1 ).atDay( 1 ) ; // First of February 2018.
PreparedStatement & ResultSet
Either way, we now have a pair of LocalDate objects to feed into our prepared statement's placeholders.
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;
When retrieving from the result set:
LocalDate start = myResultSet.getObject( … , LocalDate.class ) ;
Avoid the legacy date-time classes
No need for java.util.Date, java.sql.Date, or any of the other poorly-designed hack date-time classes bundled with the earliest versions of Java.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Related
I am trying to store datetime from Java using GregorianCalendar class in SQL SERVER, however it only stores date. I need to store the date and time in SQL SERVER.
this is the code i implemented
CallableStatement asignarTurno=conexionBBDD
.getConexionBBDD().prepareCall("{call asignarTurno(?,?,?,?,?,?)}");
//GregorianCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second)
GregorianCalendar h=new GregorianCalendar(2000, 1, 1, 8, 30,0);
java.sql.Date date = new java.sql.Date(h.getTimeInMillis());
asignarTurno.setInt(1,1);
asignarTurno.setDate(2,date);
asignarTurno.setDate(3,date);
asignarTurno.setDate(4,date);
asignarTurno.setString(5, "000");
asignarTurno.setString(6,"0001");
asignarTurno.execute();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
Multiple problems with your code.
Never use the terrible date-time classes such as GregorianCalendar and Date. These were supplanted years ago by the modern java.time classes defined in JSR 310.
You are trying to represent a moment having a date, a time-of-day, and an implicit time zone (GregorianCalendar) into a data type that pretends to hold only a date (java.sql.Date). Square peg, round hole.
Date-only
The DATE type in Microsoft SQL Server is akin to the SQL-standard type DATE, holding only a date, without a time-of-day, and without a time zone. So use java.time.LocalDate in Java.
LocalDate ld = LocalDate.of( 2000 , Month.FEBRUARY , 1 ) ;
myPreparedStatement.setObject( … , ld ) ;
And retrieval.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
Moment
If you do indeed want to track moments, you must redefine your database column with an appropriate data type. In standard SQL, that would be TIMESTAMP WITH TIME ZONE. In Microsoft SQL Server, that would be datetimeoffset.
In Java, you would place your date at time-of-day in the context of a time zone. This produces a ZonedDateTime object.
LocalDate ld = LocalDate.of( 2000 , Month.FEBRUARY , 1 ) ;
LocalTime lt = LocalTime.of ( 8 , 30 ) ;
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Unfortunately, the JDBC 4.2 team inexplicably decided to require support for OffsetDateTime but not the two more commonly-used classes, Instant and ZonedDateTime. So for maximum portable code, use OffsetDateTime. If portability is not so important, test your JDBC driver to see if it optionally chose to support ZonedDateTime or Instant.
We could just call ZonedDateTime#toOffsetDateTime. But this would bring the offset used by that time zone at that moment. For clarity, I suggest instead adjusting to UTC. That is easily accomplished by extracting a Instant (always in UTC) from our ZonedDateTime. Then we convert to OffsetDateTime with an offset of zero, per JDBC 4.2 spec.
OffsetDateTime odt = zdt.toInstant().atOffset( ZoneOffset.UTC ) ;
Then pass to your prepared statement.
myPreparedStatement.setObject( … , odt ) ;
And retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 brought some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android (26+) bundle implementations of the java.time classes.
For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
I tried to get the value of html input type "date" using request.getParameter() in servlet class, converted it into java date in JDBC Class, then to sql date format.
but there is this exception java.text.ParseException: Unparseable
date.
This is the HTML tag for date
input type="date" name="BirthDate"
This is the servlet code to get value from HTML page
String bDate = request.getParameter("BirthDate");
This is the JDBC Class code to convert it
String bbd = user.getBDate();
DateFormat df = new SimpleDateFormat("dd/MM/yyy");
java.util.Date bbDate = df.parse(bbd);;
java.sql.Date bDate = new java.sql.Date(bbDate.getTime());
tl;dr
myPreparedStatement.setObject( // As of JDBC 4.2, pass java.time objects to your database.
… ,
LocalDate // Represent a date-only value, without time-of-day and without time zone.
.parse( // Convert text to a `LocalDate` object.
"23/01/2018" ,
DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) // Specify formatting pattern to match user input.
) // Returns a `LocalDate` object.
)
java.time
Use only java.time classes. Never use java.util.Date, java.sql.Date, Calendar, SimpleDateFormat, etc.
String input = "23/01/2018" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
As of JDBC 4.2, we can directly exchange java.time objects with the database.
myPreparedStatement.setObject( … , ld ) ;
Retrieval.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I got a stored Timezone date as String on a MySQL Column with the next format:
2018-07-23T20:54:37.242Z --> start_date
What I want to do is a Between two milliseconds(or dates) like this:
SELECT * FROM activity_entity WHERE start_date BETWEEN 1532322000000 AND 1532408399000
Else, I'm using Java Spring Repository as backend where I send the parameters like this:
Date since = new Date(accessRepPOSTInDto.getSince()); //1532322000000 gives Mon Jul 23 00:00:00 CDT 2018
Date to = new Date(accessRepPOSTInDto.getTo());//1532408399000 gives Mon Jul 23 23:59:59 CDT 2018
#Query(value = "SELECT * FROM activity_entity WHERE start_date BETWEEN :since AND :too , nativeQuery = true)
ActivityEntity findBetweenDates(#Param("since") Date since, #Param("too") Date too);
Doing this returns null;
I thought MySQL can automatically format the two dates and the String column to do the Between but it looks like it doesn't.
Any help will be really grateful. Regards.
In your native query, you need to explicitly cast the value of your varchar column to the proper date/timestamp to be evaluated by the between operator. This is how your native query should look like:
SELECT * FROM activity_entity WHERE STR_TO_DATE(start_date, '%Y-%c-%eT%H:%i:%s.%fZ') BETWEEN :since AND :too
tl;dr
SQL:
SELECT * FROM tbl WHERE event >= ? AND event < ? ; -- Using Half-Open approach where beginning is *inclusive* while the ending is *exclusive*.
Java:
myPreparedStatement.setString( 1 , Instant.ofEpochMilli( 1_532_322_000_000L ).toString() ) ;
myPreparedStatement.setString( 2 , Instant.ofEpochMilli( 1_532_408_399_000L ).toString() ) ;
ISO 8601
2018-07-23T20:54:37.242Z
Text in this format is abiding by the ISO 8601 standard. That standard is the best way to represent date-time values as text. But in a database you should be using a purpose-built data type, defining a column of type akin to the SQL-standard TIMESTAMP WITH TIME ZONE. Search Stack Overflow for much more info.
The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern.
Instant instant = Instant.parse( "2018-07-23T20:54:37.242Z" ) ;
Count-from-epoch
You can convert your count of milliseconds since the epoch reference of first moment of 1970 in UTC using the Instant class.
Instant start = Instant.ofEpochMilli( 1_532_322_000_000L ) ;
Instant stop = Instant.ofEpochMilli( 1_532_408_399_000L ) ;
Generate strings in standard ISO 8601 format used in your database column.
String startStr = start.toString() ;
String stopStr = stop.toString() ;
Avoid legacy date-time classes
The old date-time classes that were bundled with the earliest versions of Java are bloody awful. Never use them. They have been supplanted entirely by the java.time classes.
Half-Open
What I want to do is a Between
The BETWEEN command in SQL should generally not be used with date-time values. That command is fully “closed” meaning both the beginning and the ending are inclusive.
Instead, for date-time work, it is generally best to define a span-of-time as Half-Open. In this approach the beginning is inclusive while the ending is exclusive. For example, students dismissed for lunch break from noon to 1 PM are expected back in their seats before the clock strikes 1 and the bell rings. Another example, a week starts on a Monday and runs up to, but does not include, the following Monday.
In SQL code, this means a query uses >=, AND, and <.
SELECT *
FROM tbl
WHERE event >= ?
AND event < ?
;
Since ISO 8601 format with the Z is chronological when sorted alphabetically, you can make this work with your ISO 8601 strings.
myPreparedStatement.setString( 1 , startStr ) ;
myPreparedStatement.setString( 2 , stopStr ) ;
If you had used a TIMESTAMP WITH TIME ZONE column type as discussed above, you would simply pass the Instant objects.
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;
If you really must use fully-closed approach, adjust the query operators >=, AND, and <=. Or call BETWEEN.
I am not a Spring user, cannot help you there.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I have a DateTime widget with 3/9/2017. Based on the documentation for DateTime, I don't see a way to determine the day of the week. I'll eventually need a string parsed in this format "Wed Feb 22 14:57:34 UTC 2017" from the DateTime widget, but the first step is to get the day of the week. Is there a way to do this outside of making my own function? And if not, what would you recommend as the best approach for the function, since days of the week are not consistent to dates from year to year?
Let me know if you need any addition information.
Thank you!
Use java.util.Calendar:
Calendar c = Calendar.getInstance();
c.setTime(yourDate);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
if you need the output to be Tue rather than 3 (Days of week are indexed starting at 1), instead of going through a calendar, just reformat the string: new SimpleDateFormat("EE").format(date) (EE meaning "day of week, short version")
Documentation
tl;dr
LocalDate.of( 2017 , Month.MARCH , 9 )
.getDayOfWeek()
.getDisplayName( TextStyle.FULL , Locale.ITALY )
Or…
OffsetDateTime.now( ZoneOffset.UTC )
.format( DateTimeFormatter.RFC_1123_DATE_TIME )
java.time
The modern approach uses the java.time classes that supplanted the troublesome old date-time classes.
The DayOfWeek enum defines seven objects, one for each day of the week, Monday-Sunday.
The LocalDate class represents a date-only value without time-of-day and without time zone.
DayOfWeek dow = LocalDate.now().getDayOfWeek() ;
Generate a string of the localized name.
String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; // Or Locale.US etc.
To generate your longer string for a moment, use DateTimeFormatter to specify a custom pattern, use a built-in pattern, or automatically localize.
String output = OffsetDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.RFC_1123_DATE_TIME ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I want a date format with week number and year in the ISO format of yyyy-'W'ww. However, with only week function available in H2 database, I am able to get only the week number without the year. How can I format in such a way that I add a default year to it. Something like 2016-'W'ww.
Currently, I am using this function (which is definitely not the correct way)
WEEK(PARSEDATETIME(TRUNC(" + this.fieldName + "),'2016ww')
WEEK(PARSEDATETIME(TRUNC(" + this.fieldName + "),'2016-ww')
I am not able to get what else can be done. Can anyone help me here
There are several valid solutions in different libraries. However, you need to know that using the standard calendar year "y" would be wrong. Instead you have to use the year-of-weekdate (or called weekbased year) with symbol "Y" (capital letter).
Example using old Calendar-stuff:
java.sql.Date sqlDate = new java.sql.Date(2017 - 1900, 0, 1); // 2017-01-01
GregorianCalendar gcal = new GregorianCalendar();
gcal.setFirstDayOfWeek(Calendar.MONDAY);
gcal.setMinimalDaysInFirstWeek(4);
gcal.setTime(sqlDate);
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-'W'ww");
System.out.println(sdf.format(gcal.getTime())); // 2016-W52
Example using Java-8:
java.sql.Date sqlDate = new java.sql.Date(2017 - 1900, 0, 1); // 2017-01-01
LocalDate ld = sqlDate.toLocalDate();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("YYYY-'W'ww", Locale.FRANCE);
System.out.println(dtf.format(ld)); // 2016-W52
Side note: I have here chosen the locale of France to ensure the correct week configuration needed for ISO-8601.
Example using my library Time4J which is only interesting and gives a surplus value if you also plan to do some arithmetic with obtained calendar week (like plusWeeks(5) or plan to get some styled localized output):
java.sql.Date sqlDate = new java.sql.Date(2017 - 1900, 0, 1); // 2017-01-01
PlainDate value = JDBCAdapter.SQL_DATE.translate(sqlDate);
CalendarWeek cw =
CalendarWeek.of(
value.get(PlainDate.YEAR_OF_WEEKDATE),
value.get(Weekmodel.ISO.weekOfYear())
);
System.out.println(cw.toString()); // 2016-W52
tl;dr
org.threeten.extra.YearWeek // Handy class found in the ThreeTen-Extra library added to your project.
.from( // Determine the week number and the week-based year number from the passed `LocalDate` object, according to standard ISO 8601 definition of a week.
myResultSet.getObject( … , LocalDate.class ) // Produces a `LocalDate` object to pass to `YearWeek.from`.
)
.toString() // Generate a String in standard ISO 8601 format: yyyy-Www
2018-W13
Details
When you fetch your Date type from H2 as a java.sql.Date, convert to a java.time.LocalDate.
LocalDate ld = mySqlDate.toLocalDate();
You can interrogate for the ISO 8601 standard definition of a week where week # 1 contains the first Thursday of the year, and runs Monday-Sunday.
int weekNumber = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
Extract the year.
int year = ld.getYear();
Assemble your standard ISO 8601 string.
String output = year + "-W" + String.format( "%02d ", weekNumber );
Even easier is to use the YearWeek class from the ThreeTen-Extra project.
String output = YearWeek.from( ld ).toString() ;
JDBC 4.2
As of JDBC 4.2 and later, you can directly exchange java.time objects with your database. No need to over use java.util or java.sql date-time classes again.
LocalDate ld = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ; // Capture the current date as seen in the wall-clock used by the people in a certain region (a time zone).
myPreparedStatement.setObject( … , ld ) ;
And retrieval.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.