Java.util.Date vs Java.sql.Date - Date value differs - java

I have an Oracle database which contains a field W_PLANNED_DATE: 19/03/2013 10:55:00 (Date)
In Java I put this value into a variable:
Date dteBeginOrWaitingItem = orWaitinglist.getWPlannedDate();
value: 2013-03-19
Now, what happend to my time? I need this to fill the schedulecomponent of primefaces.
How can i get a full date and time value
eventResourceAvailPerDay.addEvent(new DefaultScheduleEvent(reason, dteBeginOrWaitingItem, dteEndOrWaitingItem, "waitingitem"));
This method puts the event at 12:00 PM as there is no other time or the time is just 00:00:00
I know how to use the Calendar class but it just lets me set the date, the time seems to be empty but in database view I have a date time value.
Mybean
import java.util.Date;
#ManagedBean(name="scheduleController")
#SessionScoped
public class ScheduleController implements Serializable {
private Date dteBeginOrWaitingItem, dteEndOrWaitingItem;
//methods
try
{
//eventWaitinglist.clear();
OrWaitinglistDao orWaitinglistDao = new OrWaitinglistDaoImpl();
waitingEvents = orWaitinglistDao.getOrWaitinglistKeysByResource(rKey);
int i = 0;
Iterator<OrWaitinglist> it2 = waitingEvents.iterator();
while (it2.hasNext())
{
orWaitinglist = it2.next();
dteBeginOrWaitingItem = (Date) orWaitinglist.getWPlannedDate();
dteEndOrWaitingItem = orWaitinglist.getWPlannedDate();
//dteEndOrWaitingItem = orWaitinglist.getWPlannedDate();
reason = orWaitinglist.getWDescription();
eventResourceAvailPerDay.addEvent(new DefaultScheduleEvent(reason, dteBeginOrWaitingItem, dteEndOrWaitingItem, "waitingitem"));
i += 1;
System.out.println("EventWaiting: " + i + " " + dteBeginOrWaitingItem + " " + dteEndOrWaitingItem + " " + reason);
}
}
catch(java.util.EmptyStackException Ex)
{
System.out.println(Ex.getMessage());
}
WORKING UPDATE:
Bean:
try
{
//eventWaitinglist.clear();
OrWaitinglistDao orWaitinglistDao = new OrWaitinglistDaoImpl();
waitingEvents = orWaitinglistDao.getOrWaitinglistKeysByResource(rKey);
int i = 0;
Iterator<OrWaitinglist> it2 = waitingEvents.iterator();
while (it2.hasNext())
{
orWaitinglist = it2.next();
Long wPlannedDate = orWaitinglist.getWPlannedDate().getTime();
if (wPlannedDate != 0) {
Date wPlannedDateConverted = new Date(wPlannedDate);
dteBeginOrWaitingItem = convertDate(0, 0, wPlannedDateConverted);
dteEndOrWaitingItem = convertDate(orWaitinglist.getWDuration().intValue(), orWaitinglist.getWAdditionalTime().intValue(), wPlannedDateConverted);
}
reason = orWaitinglist.getWDescription();
DefaultScheduleEvent newResourceEvent = new DefaultScheduleEvent(reason, dteBeginOrWaitingItem, dteEndOrWaitingItem, orWaitinglist);
newResourceEvent.setStyleClass("waitingitem");
eventResourceAvailPerDay.addEvent(newResourceEvent);
}
}
catch(java.util.EmptyStackException Ex)
{
System.out.println(Ex.getMessage());
}
public static Date convertDate(Integer wDuration, Integer wAdditionalTime, Date availDate)
{
Calendar cal = Calendar.getInstance();
Integer wAdditionalTimeHours, wAdditionalTimeMinutes;
Integer wDurationHours, wDurationMinutes;
if(wAdditionalTime != 0 || wDuration != 0) {
if (wAdditionalTime !=0) {
wAdditionalTimeHours = (int) Math.floor (wAdditionalTime / 60);
wAdditionalTimeMinutes = wAdditionalTime - (wAdditionalTimeHours * 60);
cal.setTime(availDate);
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
cal.add(Calendar.MINUTE, wAdditionalTimeMinutes);
cal.add(Calendar.HOUR_OF_DAY, wAdditionalTimeHours);
}
if (wDuration != 0) {
wDurationHours = (int) Math.floor (wAdditionalTime / 60);
wDurationMinutes = wAdditionalTime - (wDurationHours * 60);
cal.setTime(availDate);
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
cal.add(Calendar.MINUTE, wDurationMinutes);
cal.add(Calendar.HOUR_OF_DAY, wDurationHours);
}
} else {
cal.setTime(availDate);
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
}
return cal.getTime();
}
Model update:
<property name="WPlannedDate" type="timestamp">
<column length="7" name="W_PLANNED_DATE">
<comment>Planned date</comment>
</column>
</property>

java.sql.Date will not return time component, you should use java.util.Date while creating your preparedstatement or any other way your are querying the db.
EDIT:
Using java.util.Date with sql query can be tricky as query will expect java.sql.Date. It works for me in Spring. If you dont want to use this then you can use java.sql.Timestamp also.
See below documentation:
8.3.12 DATE, TIME, and TIMESTAMP
There are three JDBC types relating to time:
The JDBC DATE type represents a date consisting of day, month, and
year. The corresponding SQL DATE type is defined in SQL-92, but it is
implemented by only a subset of the major databases. Some databases
offer alternative SQL types that support similar semantics. The JDBC
TIME type represents a time consisting of hours, minutes, and seconds.
The corresponding SQL TIME type is defined in SQL-92, but it is
implemented by only a subset of the major databases. As with DATE,
some databases offer alternative SQL types that support similar
semantics. The JDBC TIMESTAMP type represents DATE plus TIME plus a
nanosecond field. The corresponding SQL TIMESTAMP type is defined in
SQL-92, but it is implemented by only a very small number of
databases. Because the standard Java class java.util.Date does not
match any of these three JDBC date/time types exactly (it includes
both DATE and TIME information but has no nanoseconds), JDBC defines
three subclasses of java.util.Date to correspond to the SQL types.
They are:
java.sql.Date for SQL DATE information. The hour, minute, second, and
millisecond fields of the java.util.Date base class should be set to
zero. If the number of milliseconds supplied to the java.sql.Date
constructor is negative, the driver will compute the date as the
number of milliseconds before January 1, 1970. Otherwise, the date is
computed as the specified number of milliseconds after January 1,
1970.
java.sql.Time for SQL TIME information. The year, month, and day
fields of the java.util.Date base class are set to 1970, January, and
1. This is the "zero" date in the Java epoch. java.sql.Timestamp for SQL TIMESTAMP information. This class extends java.util.Date by adding
a nanoseconds field.

EDIT: if you are using .xml for hibernate change type to timestamp instead of date.
<property name="yourdate" column="YOUR_DATE" type="timestamp" />
therefore you have time on your database and can use simpledateformat
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy-HH:mm");
dateFormat.format(orWaitinglist.getWPlannedDate());

Instead of java.sql.Date, java.sql.Timestamp and the matching methods should be used. The oracle type DATE is equivalent to the JDBC and SQL-standard type TIMESTAMP.
A driver is required by the JDBC spec to exclude the time part when one of the get/setDate methods are used.

Related

Convert String to Date and time in java

My program reading data from a database and I want to convert some fields to date format (date and time separately). I can do this from sql query but is it possible to do from java code.
date format in table = MMDDHHMISS (month day hour minute sec)
and these are sql queries now I'm using-
TO_CHAR(TO_DATE(DATETIMECOLUMN, 'MMDDHH24MISS'),'DD/MM/YYYY') AS MY_DATE
TO_CHAR(TO_DATE(DATETIMECOLUMN, 'MMDDHH24MISS'),'HH24:MI:SS') AS MY_TIME
Thanks in advance!
Here’s a suggestion:
DateTimeFormatter databaseStringFormatter = DateTimeFormatter.ofPattern("MMddHHmmss");
String sampleDatabaseString = "1129225145";
MonthDay myDate = MonthDay.parse(sampleDatabaseString, databaseStringFormatter);
LocalTime myTime = LocalTime.parse(sampleDatabaseString, databaseStringFormatter);
System.out.println("Date: " + myDate + ". Time: " + myTime + '.');
The above prints
Date: --11-29. Time: 22:51:45.
MonthDay is a date without a year, useful for birthdays and other anniversary dates.
Unless there are specific reasons to avoid it, I think you should rather change the datatype of your database column to datetime or similar and then retrieve LocalDateTime objects from your result set as shown in this answer. This would free you from any conversion from string to date and time in either the database query or in Java.

Retrieving a DateTime Using resultset into a DateTime field [duplicate]

I'm retrieving a timestamp object from a database using ResultSet.getTimestamp(), but I'd like an easy way to get the date in the format of MM/DD/YYYY and the time in a format of HH:MM xx. I was tinkering around, it it looks as though I can do such by making use of the Date and/or DateTime objects within Java. Is that the best way to go, or do I even need to convert the timestamp to accomplish this? Any recommendations would be helpful.
....
while(resultSet.next()) {
Timestamp dtStart = resultSet.getTimestamp("dtStart");
Timestamp dtEnd = resultSet.getTimestamp("dtEnd");
// I would like to then have the date and time
// converted into the formats mentioned...
....
}
....
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTest {
public static void main(String[] args) {
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
Date date = new Date(timestamp.getTime());
// S is the millisecond
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy' 'HH:mm:ss:S");
System.out.println(simpleDateFormat.format(timestamp));
System.out.println(simpleDateFormat.format(date));
}
}
java.sql.Timestamp is a subclass of java.util.Date. So, just upcast it.
Date dtStart = resultSet.getTimestamp("dtStart");
Date dtEnd = resultSet.getTimestamp("dtEnd");
Using SimpleDateFormat and creating Joda DateTime should be straightforward from this point on.
java.time
Modern answer: use java.time, the modern Java date and time API, for your date and time work. Back in 2011 it was right to use the Timestamp class, but since JDBC 4.2 it is no longer advised.
For your work we need a time zone and a couple of formatters. We may as well declare them static:
static ZoneId zone = ZoneId.of("America/Marigot");
static DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MM/dd/uuuu");
static DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm xx");
Now the code could be for example:
while(resultSet.next()) {
ZonedDateTime dtStart = resultSet.getObject("dtStart", OffsetDateTime.class)
.atZoneSameInstant(zone);
// I would like to then have the date and time
// converted into the formats mentioned...
String dateFormatted = dtStart.format(dateFormatter);
String timeFormatted = dtStart.format(timeFormatter);
System.out.format("Date: %s; time: %s%n", dateFormatted, timeFormatted);
}
Example output (using the time your question was asked):
Date: 09/20/2011; time: 18:13 -0400
In your database timestamp with time zone is recommended for timestamps. If this is what you’ve got, retrieve an OffsetDateTime as I am doing in the code. I am also converting the retrieved value to the user’s time zone before formatting date and time separately. As time zone I supplied America/Marigot as an example, please supply your own. You may also leave out the time zone conversion if you don’t want any, of course.
If the datatype in SQL is a mere timestamp without time zone, retrieve a LocalDateTime instead. For example:
ZonedDateTime dtStart = resultSet.getObject("dtStart", LocalDateTime.class)
.atZone(zone);
No matter the details I trust you to do similarly for dtEnd.
I wasn’t sure what you meant by the xx in HH:MM xx. I just left it in the format pattern string, which yields the UTC offset in hours and minutes without colon.
Link: Oracle tutorial: Date Time explaining how to use java.time.
You can also get DateTime object from timestamp, including your current daylight saving time:
public DateTime getDateTimeFromTimestamp(Long value) {
TimeZone timeZone = TimeZone.getDefault();
long offset = timeZone.getOffset(value);
if (offset < 0) {
value -= offset;
} else {
value += offset;
}
return new DateTime(value);
}
LocalDateTime dtStart = rs.getTimestamp("dtStart").toLocalDateTime();
Converts this Timestamp object to a code LocalDateTime.
The conversion creates a code LocalDateTime that represents the
same year, month, day of month, hours, minutes, seconds and nanos
date-time value as this code Timestamp in the local time zone.
since 1.8

Compare date in sqlite stored as milliseconds

I have a table in SQLite having date column defined as Numeric type
KEY_DRIVER_STAT_DAT + " NUBMERIC"
Now I'mm inserting data in KEY_DRIVER_STAT_DAT columns as
values.put(KEY_DRIVER_STAT_DAT, DateTime.now().getMillis());
How can I get the records from this table where KEY_DRIVER_STAT_DAT is between
Current date ?
Dealing with dates by their milliseconds values is tricky. When you insert record with millisecond value as date you insert it with the value of current moment. You need to search all records which are in time period from start of date (time of 00:00) and to the end of date (time of 23:59). Take a look at this example:
/*Suppose your DateTime is Joda's DateTime class*/
import java.util.*;
import org.joda.time.*;
// Two functions to help retrive start and end of date
public static DateTime getStart(DateTime date) {
return new DateTime(date.year().get(), date.monthOfYear().get(), date.dayOfMonth().get(), 0, 0);
}
public static DateTime getEnd(DateTime date) {
return new DateTime(date.year().get(), date.monthOfYear().get(), date.dayOfMonth().get(), 23, 59);
}
// Code to make clause and parameters for select-statement
DateTime now = DateTime.now();
DateTime start = getStart(now);
DateTime end = getEnd(now);
String yourClause = "KEY_DRIVER_STAT_DAT >= ? AND KEY_DRIVER_STAT_DAT <= ?";
String[] params = new String[] {String.valueOf(start.getMillis()), String.valueOf(end.getMillis())};
System.out.println("clause: " + yourClause);
System.out.println("parameters: " + Arrays.toString(params));

How to compare Calendar's time to java.sql.Time object?

I want to know whether the Time values of a Calendar object equal the value of a java.sql.Time object.
E.g
Calendar c; //c.getTime().toString() == "Sat Jan 07 09:00:00 GMT 2012"
Time t; //d.toString() == "09:00:00";
I tried
t.equals(c.getTime())
But because the Calendar has Date information the expression is false.
What would be the best way the compare the two?
Edit:
The Time object is retrieve though Hibernate and come with no date information.
The Calendar object is create by
Calendar c= Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 9);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
The way you use is perfectly fine. The goal is unclear, though. Why do you want c to be equal to d?
Additionally, there's no way to have d.toString() == "09:00:00" — Date always have, well, the date included.
What's more important, though, is that Date has no timezone information (well, it used to have, but you're discouraged to touch this part of Date), so you cannot tell 09:00 UTC from 10:00 BST—that is, unless you specify the timezone. You can get the timezone from Calendar c, and it sort of explains what you need to do:
Create a Calendar from your date
Copy timezone from the calendar you already use
Compare the Calendar fields which are of interest for you. I suppose that will be hour, minute, second, and, perhaps, millisecond.
Update: now that you've mentioned it's actually java.sql.Time, I'm worried. The problem is,
SQL servers usually store time as a structure containing hours, minutes, seconds, etc. That is, there's an implied timezone (the SQL Server timezone)
java.sql.Time stores time as milliseconds since "zero epoch" value of January 1, 1970. The date part is usually stripped to January 1, 1970 — but this class does not contain timezone information. (Well, again, it sort of does, but it's deprecated.)
Calendar has an explicitly set timezone
What it means in practice is, that the time from the server gets converted into milliseconds using system default timezone, then you read this value and compare it with a Calendar with its own timezone.
If it sounds confusing and fragile, that's because it is. So basically you have three timezones:
SQL Server TZ
JVM's default TZ
Calendar's TZ
All three must be the same so that any comparison would make any sense.
You can use Date, Calendar, GregorianCalendar,SimpleDateFormat` etc classes to deal with date-time in Java. Let's see some examples.
SimpleDateFormat dayFormat = new SimpleDateFormat("D");
int _currentDay = Integer.parseInt(dayFormat.format(new Date(System.currentTimeMillis())));
SimpleDateFormat monthFormat = new SimpleDateFormat("M");
int _currentMonth = Integer.parseInt(monthFormat.format(new Date(System.currentTimeMillis())));
SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
int _currentYear = Integer.parseInt(yearFormat.format(new Date(System.currentTimeMillis())));
System.out.println(_currentDay+"/"+_currentMonth+"/"+_currentYear);
Would display the current date based on the current millisecond.
String toDate = "07/1/2012";
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
Calendar currentDateCal = Calendar.getInstance();
// Zero out the hour, minute, second, and millisecond.
currentDateCal.set(Calendar.HOUR_OF_DAY, 0);
currentDateCal.set(Calendar.MINUTE, 0);
currentDateCal.set(Calendar.SECOND, 0);
currentDateCal.set(Calendar.MILLISECOND, 0);
Date currentDate = currentDateCal.getTime();
Date toDt;
try
{
toDt = df.parse(toDate);
}
catch (ParseException e)
{
toDt = null;
System.out.println(e.getMessage());
}
if (currentDate.equals(toDt))
{
System.out.println(currentDate); // Displays the current date.
//Rest of the stuff.
}
String toDate = "07/12/2012";
try
{
if (new SimpleDateFormat("MM/dd/yyyy").parse(toDate).getTime() / (1000 * 60 * 60 * 24) >= System.currentTimeMillis() / (1000 * 60 * 60 * 24))
{
System.out.println("True");
}
else
{
System.out.println("Untrue");
}
}
catch(ParseException ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
String toDateAsString = "07/12/2012";
Date toDate=null;
try
{
toDate = new SimpleDateFormat("MM/dd/yyyy").parse(toDateAsString);
}
catch (ParseException ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
long toDateAsTimestamp = toDate.getTime();
long currentTimestamp = System.currentTimeMillis();
long getRidOfTime = 1000 * 60 * 60 * 24;
long toDateAsTimestampWithoutTime = toDateAsTimestamp / getRidOfTime;
long currentTimestampWithoutTime = currentTimestamp / getRidOfTime;
if (toDateAsTimestampWithoutTime >= currentTimestampWithoutTime)
{
System.out.println("True");
}
else
{
System.out.println("False");
}
The JodaTime's variant:
String toDateAsString = "07/01/2012";
DateTime toDate = DateTimeFormat.forPattern("MM/d/yyyy").parseDateTime(toDateAsString);
DateTime now = new DateTime();
if (!toDate.toLocalDate().isBefore(now.toLocalDate()))
{
System.out.println("True");
}
else
{
System.out.println("False");
}
why don't you compare the time in milliseconds?
Date d;
Calendar c;
System.out.println(d.getTime() == c.getTimeInMillis());
Since, you tagged this Question with DateTime, i assume you use Joda already
...
//Initialize Calendar and Date Object
DateTime d1 = new DateTime(c.getTime());
DateTime d2 = new DateTime(d.getTime());
// Convert d1 and d2 to LocalDate say ld1 and ld2 since, Java Date defaults to GMT
ld1.compareTo(ld2);
?
I had to do this today and the answers in this post helped my solve my problem. I know all my timezones are the same like the OPs. And I don't have the liberty to use Joda time in my legacy code so for the benefit of others who have the same conditions, here is how I did it with vanilla Java.
Methodology:
java.sql.Time has a getTime() due to inheritance from
java.util.Date. Using this method, one can create a
java.util.Date object that represents just the time portion since
Java epoch.
For comparison, one must convert the desired java.util.Calendar
object to produce a java.util.Date object that represents another
time since Java epoch.
Since the date parts are now equivalent, any comparison between the 2
objects would only compare the time parts producing the desired result.
Without further adieu, here is the code:
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Test {
/**
* Method to convert a calendar object to java's epoch date
* keeping only the time information
*/
public static Date toEpochDate(Calendar calendar) {
return new Date(Time.valueOf(new SimpleDateFormat("HH:mm:ss").format(calendar.getTime())).getTime());
}
public static void main(String[] args) {
// create any calendar object
Calendar someTime = Calendar.getInstance();
someTime.set(Calendar.HOUR_OF_DAY, 17);
someTime.set(Calendar.MINUTE, 0);
someTime.set(Calendar.SECOND, 0);
// convert it to java epoch date
Date someDate = toEpochDate(someTime);
// create a date object from java.sql.Time
Date fromSqlTime = new Date(Time.valueOf("17:00:00").getTime());
// now do the comparison
System.out.println("Some Date: " + someDate.toString());
System.out.println("Sql Time: " + fromSqlTime.toString());
System.out.println("Are they equal? " + someDate.equals(fromSqlTime));
}
}
The above produces the following output:
Some Date: Thu Jan 01 17:00:00 EST 1970
Sql Time: Thu Jan 01 17:00:00 EST 1970
Are they equal? true
Using the above methodology, and by changing .equals() to .before() or .after(), various time comparison convenience methods can be created.

Converting timezone for date faster using java

I have written this method for converting a date time zone. How do i reduce the execution time of this method further.
public static Timestamp convertTimeZone(final Timestamp fromDate, final TimeZone fromTZ, final TimeZone toTZ ){
Long timeInDate = fromDate.getTime() ;
int fromOffset = fromTZ.getOffset(timeInDate);
int toOffset = toTZ.getOffset(timeInDate);
Timestamp dateStamp = new Timestamp(fromDate.getTime());
if (fromOffset >= 0){
int diff = 0;
if (toOffset > 0){
diff = (fromOffset - toOffset);
} else {
diff = (fromOffset + Math.abs(toOffset));
}
long date = fromDate.getTime() - diff;
dateStamp.setTime(date);
} else {
int diff = 0;
if (toOffset > 0){
diff = (Math.abs( fromOffset) + toOffset);
} else {
diff = (Math.abs( fromOffset) - Math.abs(toOffset));
}
long date = fromDate.getTime() + diff;
dateStamp.setTime(date);
}
return dateStamp;
}
With joda-time it may look like this:
DateTime dt = new DateTime(DateTimeZone.forID("GMT"));
System.out.println(dt); // 5 am
dt = dt.withZone(DateTimeZone.forID("EET"));
System.out.println(dt); // 8 am
Note that Timestamp has no notion of Timezone so it is not suitable for representing it.
Your solution will have a good running time, since it's O(1). It's harder to read though.
You could store your date in a Calendar object to begin with. Showing it in different time zone formats will be a matter of configuration that you apply to a SimpleDateFormat.
Technically a Date is the same in all time zones (it's internal value is the same). Applying the concept of timezones allows date formatters to adjust offsets for display. In other words, a Date that represents 17:00 in London time is equal to a Date that represents 12:00 in New York. Displaying it in the GMT vs. the EST time zones can be a function of date formatters.
It's not quite an answer, but I recommend always store timestamp in database as UTC time instead of local time. And display it for different timezones only on presentation layer setting DateFormat.setTimeZone()

Categories