I got the following in the body of the code:
public String getStartDate() {
return (new SimpleDateFormat("dd/MM/yyyy").format(startDate));
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
and startDate is initiated as Date startDate;
When I use the set startdate method, I am setting the value of this instance to the value of the object retrieved from database..
setStartDate(rsvIns.startDate);
Now the problem is here when I try to see if the startDate is equal to TodayDate,
Date todayDate = new Date();
if(startDate.equals(todayDate))
{
changeStatus(requestID, "Active");
}else{
//update status if others approved
changeStatus(requestID, "Approved");
}
I whenever it comes to the equals line it throws error and just doesn't execute the if or else part, hence the statement is never executed. Any idea why this could be happening?
Thanks,
I see 2 problems from the code snippets you provided:
Date todayDate = new Date() object contains in information on Hour, Minutes, Seconds and Milliseconds. If you compare it to a date created from a "dd/MM/yyyy" string you will have a problem caused by the time component of the Date object.
getStartDate() returns a String object. If that value is assigned to the startDate variable from the if statement, then on equals() call with a Date object parameter value the result will be false regardless of the startDate and parameter value, because the classes do not match.
If you get into situations like this and you do not see the answer, copy the code into a small program and debug trace it, look at the values of the objects. Trace into java code.
I have seen many times java developers with years of experience trip on the time component of Date object. They even clear the Hour, Minutes and Seconds and forget about the Milliseconds component.
Related
Suppose two people run the same code and the first one creates a certificate with createDate and expireDate and a file is valid if
createDate < currentTimeOfTheUserComputer < expireDate .
Now if the first person sends this certificate(suppose for him it is valid) to someone else who is 8 hours behind around the world ,for the second person it will be invalid.In such a scenario how is this problem resolved or is there a policy how it should be if we want the second person to be able to use it without waiting 8 hours?
RFC 5280, which handles X.509 certificates specifies two methods to encode validity times in certificates:
UTCTime
GeneralizedTime
Both rely on the GMT zone as reference. If both implementations use the correct time zone for generation and checking, your scenario should not present a problem.
See RFC 5280 on validity
EDIT: Sorry, I didn't realize that Date always uses UTC Time. So any time you want to get the date, you access it like this:
import java.util.Date;
public class CurrentDateTime {
public static String getCurrDateTime() {
Date date = new Date();
return date;
}
}
public class DateCertificate {
public static void createCertificate() {
Date createDate = CurrentDateTime.getCurrDateTime();
/* Save createDate to file or something */
}
public static boolean certificateValid() {
Date currentDate = CurrentDateTime.getCurrDateTime();
/* Get createDate and expireDate from file or something */
return currentDate.after(createDate) && currentDate.before(expireDate);
}
}
You can use getCurrDateTime() and some other Date methods to get the createDate and expireDate and save them to a file or however you want to store them, then use the certificateValid() method to check if the currentDate is between the two.
Thanks Jim for pointing out my mistake.
Note: This could be easily spoofed/tricked because it is dependent on the time reading from the client machine that is given to the JVM. So do not use this for free trial validation or the like.
I am trying to persist java.time.LocalDateTime using Hibernate and JPA. I used Jadira Framework ("org.jadira.usertype:usertype.core:3.2.0.GA" & "org.jadira.usertype:usertype.extended:3.2.0.GA"). I created package-info.java file and created #TypeDefs({#TypeDef(defaultForType = java.time.LocalDateTime.class, typeClass = org.jadira.usertype.dateandtime.threeten.PersistentLocalDateTime.class)}) there. I tested the solution and the java.time.LocalDateTime fields are stored/retrieved to my MySQL database in DATETIME columns (almost) correctly.
The only problem is that the values in database are +2 hours to the correct time value from fields in Java. I'm in CEST (UTC+2) so I understood that this is some problem with time zones. I debugged the code of PersistentLocalDateTime and this is what I found.
PersistentLocalDateTime is using org.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper
AbstractTimestampThreeTenColumnMapper has field ZoneOffset databaseZone by default set to ZoneOffset.of("Z") (UTC).
Because it is thinking that my database is in UTC timezone (and the application is in UTC+2) it adds two hours to my time during conversion to database (and subtracts two hours from my time during conversion from database). So in the application I see the correct date and time but in database I not.
I found that a can add parameters to the #TypeDef so I specified them as below:
#TypeDef(defaultForType = LocalDateTime.class, typeClass = PersistentLocalDateTime.class,
parameters = {
#Parameter(name = "databaseZone", value = "+02:00")
}),
but I've got an exception:
java.lang.IllegalStateException: Could not map Zone +02:00 to Calendar
at org.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper.getHibernateType(AbstractTimestampThreeTenColumnMapper.java:59)
I debugged a little bit more. AbstractTimestampThreeTenColumnMapper has two methods:
public final DstSafeTimestampType getHibernateType() {
if (databaseZone == null) {
return DstSafeTimestampType.INSTANCE;
}
Calendar cal = resolveCalendar(databaseZone);
if (cal == null) {
throw new IllegalStateException("Could not map Zone " + databaseZone + " to Calendar");
}
return new DstSafeTimestampType(cal);
}
private Calendar resolveCalendar(ZoneOffset databaseZone) {
String id = databaseZone.getId();
if (Arrays.binarySearch(TimeZone.getAvailableIDs(), id) != -1) {
return Calendar.getInstance(TimeZone.getTimeZone(id));
} else {
return null;
}
}
getHibernateType method throws the exception because resolveCalendar method returns null. Why it returns null? Because time zones IDs from java.time.ZoneOffset and java.util.TimeZone does not match. As far as I see the only possible value which match is Z. Any other values causes exceptions.
Is there any way to setup this correctly? Or is it a bug in the Jadira Framework?
It looks like a serious bug. The problem is that jadira.usertype.databaseZone parameter is parsed to ZoneOffset instead ZoneId. This way, resolveCalendar method compares 2 different types Zone and Offset. What is funny, parameter is named databaseZone but it does not contain zone. It contains only offset.
https://github.com/JadiraOrg/jadira/issues/42
https://github.com/JadiraOrg/jadira/issues/43
I need to check if a given timestamp is today. I am using Joda-Time. Is there a method or a simple way to check this? What Joda-Time class is better suited for this? LocalDate? DateTime?
The date can be compared by single statement so why you need a special function.
when dateTimeis an object of DateTime()
if((dateTime.toLocalDate()).equals(new LocalDate()))
when date is an object of java.util.date
if((new DateTime(date).toLocalDate()).equals(new LocalDate()))
What Joda-time class is better suited for this? LocalDate? DateTime?
The understanding that you need to know what is LocalDate and DateTime.
LocalDate() is an immutable datetime class representing a date without a
time zone. So is not having a time part.
DateTime() is the standard implementation of an unmodifiable datetime
class. Its having all the attributes of the Date, which includes
date, time and timezone.
So if you need to compare both the date and time better go with datetime, if you just need to check the date you must use localDate because the datetime will produce a false if an .equal operator is used, unless the time including the seconds part are same for both the objects.
Here are some simple methods to check if a DateTime is today, tomorrow or yesterday:
public boolean isToday(DateTime time) {
return LocalDate.now().compareTo(new LocalDate(time)) == 0;
}
public boolean isTomorrow(DateTime time) {
return LocalDate.now().plusDays(1).compareTo(new LocalDate(time)) == 0;
}
public boolean isYesterday(DateTime time) {
return LocalDate.now().minusDays(1).compareTo(new LocalDate(time)) == 0;
}
One possibility is to create an interval covering the whole day in question, and then check if the various timestamps are contained in this interval.
Constructing the initial interval could look like:
Interval today = new Interval(DateTime.now().withTimeAtStartOfDay(), Days.ONE);
Then the timestamps could be checked like so:
today.contains(DateTime.now()); // True
today.contains(DateTime.now().minusDays(1)); // False
today.contains(DateTime.now().plusDays(1)); // False
today.contains(someOtherTimeStamp.toDateTime()); // And so on...
The recommended way to do this would be:
DateTime midnightToday = DateTime.now().withTimeAtStartOfDay();
DateTime myDateTime = <whatever>;
if(myDateTime.isAfter(midnightToday)) {
}
I think you need Joda 2.5 to do this, but that should do the trick.
I like #JustinMorris's answer. But I found this even better:
public static boolean isToday(DateTime time) {
return LocalDate.now().equals(new LocalDate(time));
}
public static boolean isTomorrow(DateTime time) {
return LocalDate.now().plusDays(1).equals(new LocalDate(time));
}
public static boolean isYesterday(DateTime time) {
return LocalDate.now().minusDays(1).equals(new LocalDate(time));
}
AFAIK there is no direct method available by which you can check the Date is Today Date or not.
The simplest approach will be constructing two DateTime one with the Timestamp, and another with today Date and then comparing day from dayOfYear() and year from year() but do remember whether both Date are in UTC or in Local Time Zone.
A small sample,
DateTime date = new DateTime(TimeStamp);
DateTime todayDate = new DateTime();
if(date.dayOfYear().get() == todayDate.dayOfYear().get() && date.year().get() == todayDate.year().get())
{
System.out.println("Date is today date");
}
Joda time actually have a method for this:
DateUtils#isToday(ReadablePartial);
DateUtils#isToday(ReadableInstant);
Simplest way I've found:
public boolean isToday(DateTime dateTime) {
return dateTime.withTimeAtStartOfDay().getMillis() ==
new DateTime().withTimeAtStartOfDay().getMillis();
}
I have this code copied from one of questions from SO:
public static String getCurrentTimeStamp() {
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
String strDate = sdfDate.format(now);
return strDate;
}
I want to get only the system time and NOT the date. Then I must change second line of code to:
SimpleDateFormat sdfDate = new SimpleDateFormat(" HH:mm:ss") ;
Then, DATE() must get the current time. Clear upto this point but I can't understand the format() function used.
I mean cant we simply output variable now instead of strdate?
Is it just because that the return type of function getCurrentTimeStamp() is String?
Please clarify and if there is any other simpler and one line code for getting system time alone, do share.
I mean cant we simply output variable now instead of strdate.
Well you could return now.toString() - but that will use the format that Date.toString() happens to choose, whereas you want a specific format. The point of the SimpleDateFormat object in this case is to convert a Date (which is a point in time, without reference to any particular calendar or time zone) into a String, applying an appropriate time zone, calendar system, and text format (in your case HH:mm:ss).
You can still simplify your method somewhat though, by removing the local variables (which are each only used once):
public static String getCurrentTimeStamp() {
return new SimpleDateFormat("HH:mm:ss").format(new Date());
}
Or maybe you'd find it more readable to keep the variable for the date format, but not the date and the return value:
public static String getCurrentTimeStamp() {
DateFormat format = new SimpleDateFormat("HH:mm:ss");
return format.format(new Date());
}
Personally I'd recommend using Joda Time instead, mind you - it's a much nicer date/time API, and its formatted are thread-safe so you could easily keep a reference to a single formatting object.
public static String getCurrentTimeStampwithTimeOnly() {
return new SimpleDateFormat("HH:mm:ss").format(new Date());
}
Helps you to do this.
you can call this line any time
Date now = new Date();
The now variable will contain the current timestamp
The format function just generates a String from this timestamp
also take a look at the Calendar class ( Calendar.getInstance())
I am trying to get two dates from a SQL query, and compare them. So to compare them, I believe I will need to use the "Date" type. Here is what I am trying, I know I am getting the date from the resultSet incorrectly, but I am not sure how to do it.
Date validDate = new Date(0);
Date currentDate = new Date(0);
// query
if (result.next()) {
validDate = (result.getObject("validDate")!=null)?result.getObject("validDate").toDate():"";
currentDate = (result.getObject("currentDate")!=null)?result.getObject("currentDate").toDate():"";
}
if (currentDate > validDate) {
//do something
}
So again, this was my attempt, but I cant seem to get it to run. Thanks in advance.
EDIT: the query has TO_CHAR(column, 'MM-DD-YYYY') on the two dates that I am getting.
EDIT: Now you've mentioned that your query converts the date to a string, stop doing that. You'll end up reparsing it on the calling side - so why perform two conversions pointlessly? Keep string conversions to the absolute minimum - stay in the most appropriate data type wherever possible.
Original answer
You haven't shown what result is, but you probably want something like ResultSet.getDate() to fetch the date values.
Note that your comparison code won't work either because there's no > for Date - you'd need something like:
if (currentDate.after(validDate))
Or fetch the underlying number of millis:
if (currentDate.getTime() > validDate.getTime())
Additionally:
You can't assign "" to a Date variable - a string isn't a Date.
You can just call ResultSet.getDate() and check whether the returned value is null, rather than calling getObject first and then getDate()
Try currentDate.after(validDate)
To compdare dates I always use the before and after methodes of Date.
Some nasty things can happen when accessing dates via the getObject method. You should try to use the rs.getTimestamp (with timeinfo) or the rs.getDate (without timeinfo) methods.
Also, because of the rather complex hierarchy of Date-objects you should compare Dates only using the date1.compareTo(date2) > 0 method.
if your result object is ResultSet, then
Date validDate = result.getTimestamp("validDate");
Date currentDate= result.getTimestamp("currentDate");
// you can add null checks here too....
// you can also use if (currentDate.getTime() > validDate.getTime()){}
if (currentDate.before(validDate)) {
//some code inhere...
}
There are at least three things wrong with your code:
"" is a String literal, so you cannot use it int your ternary expressions to be assigned to a variable of type Date - use null instead so you don't need a ternary
ResultSet.getObject() returns an Object, which does not have a toDate() method. Instead, simply use ResultSet.getDate()
You cannot compare Date instances using a > operator. You have to use the before() and after() methods of the Date class
Taking all this together, the following code might work:
Date validDate = new Date(0);
Date currentDate = new Date(0);
if (result.next()) {
validDate = result.getDate("validDate");
currentDate = result.getDate("currentDate");
}
if (currentDate.after(validDate)) {
//do something
}
The if clause may have to include some extra logic to deal with null values though. It's better to do that than to leave that to implicit conversions, too.