How can I check if date is before a specific time? - java

I have to check, if a date variable is before a specific time. The variable has the format dd.MM.yyyy HH:mm:ss.
Let's take todays date 31.10.2016 15:20:45. The value of the variable is 30.10.2016 14:00:21. How can I check now if the variable is one day older than today and if the time is before or equals 23:00?
I tried following code.
Date today = new Date();
Calendar c = Calendar.getInstance();
c.setTime(causedAt);
c.add(Calendar.DATE, 1);
if (c.getTime().compareTo(today) < 0) { // It's more than 1 day.
setOneDayOverdue(true);
setFiveDaysOverdue(false);
}
But with this code the part with the time is missing.
The solution should work with Java 7 and without any external libraries like Joda-Time.

You should use the new Java 8 Date / Time API:
LocalDateTime NOW = LocalDateTime.now(); // e.g. 31.10.2016 15:20:45
// parse given Date/Time
LocalDateTime input = LocalDateTime.parse(strInput, DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"));
// Check if input is before "now"
boolean isBefore = input.isBefore(NOW);
See https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html to get all the methods you need to meet your requirements. For example:
LocalDateTime yesterday = NOW.minusDays(1);
boolean isBeforeYesterday = input.isBefore(yesterday);
With getHour() and getMinute() you can check for <= 23:00. Or you can use LocalTime but it seems getting those two fields should be enough for you.

So I got following code that works for me:
public void setOverdueFlagIfRequired(Date today, Date causedAtDate) {
Calendar now = Calendar.getInstance();
now.setTime(today);
Calendar causedAt = Calendar.getInstance();
causedAt.setTime(causedAtDate);
Calendar yesterday2300 = Calendar.getInstance();
yesterday2300.setTime(today);
yesterday2300.add(Calendar.DATE, -1);
yesterday2300.set(Calendar.HOUR_OF_DAY, 23);
yesterday2300.set(Calendar.MINUTE, 0);
yesterday2300.set(Calendar.SECOND, 0);
yesterday2300.set(Calendar.MILLISECOND, 0);
Calendar fiveDaysBack2300 = Calendar.getInstance();
fiveDaysBack2300.setTime(yesterday2300.getTime());
fiveDaysBack2300.add(Calendar.DATE, -4);
if (causedAt.compareTo(fiveDaysBack2300)<=0) {
setFiveDaysOverdue(true);
}
else if (causedAt.compareTo(yesterday2300)<=0 && causedAt.compareTo(fiveDaysBack2300)>0) {
setOneDayOverdue(true);
}
}

Related

Java Calendar and Time UTC to BST

I get a string in the format yyyy-MM-dd HH:mm which represents a Date and Time in UTC.
Next step is to put this into a Calendar (with TimeZone UTC).
In addition need to also create a separate Calendar which has converted the UTC to "Europe/London" timeZone (GMT/BST).
After that I need to be able to detect if the "Europe/London" calendar has a DST (Day Light Savings Offset).
The code below will show you how far I have got and it runs ok on a UK based computer whose default System Timezone is GMT. However when I run it on a pc whose timezone is UTC it fails. It seems to not be able to tell me if there is an DST_offset (its always zero).
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.set(Calendar.YEAR, 2016);
cal.set(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, 27);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 35);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
//This is required as Java Date JAN starts at 0.
int MonthCon = cal.get(Calendar.MONTH)-1;
cal.set(Calendar.MONTH, MonthCon);
Date d = cal.getTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("UTC: " + f.format(d));
f.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println("BST: " + f.format(d));
//Creates a BST calendar of the same UTC time
String dateStrBST = f.format(d);
SimpleDateFormat curFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
curFormater.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date dateObjBST = curFormater.parse(dateStrBST);
System.out.println("BSTNewDate: " + f.format(dateObjBST));
Calendar calBST = Calendar.getInstance(TimeZone.getTimeZone("BST"));
calBST.setTime(dateObjBST);
System.out.println("Current TimeZone is : " + calBST.getTimeZone());
int offset = calBST.get(Calendar.DST_OFFSET);
System.out.println("Day Light Savings: "+offset);
System.out.println("Transition Day: "+isDSTTransitionDay(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH))+" Transition Type: "+DSTtransitionType(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH)));
Unfortunately I need to be able to detect if any particular day is a transition day, that is to say a day that changes from DST on/off or off/on. Again this works on the local computer but not on the UTC timezone one.
private static boolean isDSTTransitionDay(int year, int month, int day) throws ParseException
{
Calendar calStartofDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calStartofDay.set(Calendar.YEAR, year);
calStartofDay.set(Calendar.MONTH, month);
calStartofDay.set(Calendar.DAY_OF_MONTH, day);
calStartofDay.set(Calendar.HOUR_OF_DAY, 00);
calStartofDay.set(Calendar.MINUTE, 0);
calStartofDay.set(Calendar.SECOND, 1);
Date dStartofDay = calStartofDay.getTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
f.setTimeZone(TimeZone.getTimeZone("Europe/London"));
String dateStrUTCtoBST = f.format(dStartofDay);
SimpleDateFormat curFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
curFormater.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date dateObjBST = curFormater.parse(dateStrUTCtoBST);
Calendar calBST = Calendar.getInstance();
calBST.setTime(dateObjBST);
int offsetStart = calBST.get(Calendar.DST_OFFSET);
calBST.add(Calendar.HOUR_OF_DAY, 23);
int offsetEnd = calBST.get(Calendar.DST_OFFSET);
//System.out.println("Start: "+offsetStart+" End: "+offsetEnd);
if (offsetEnd == offsetStart)
{
return false;
}else
{
//if(offsetStart<offsetEnd) {System.out.println("Transition to BST");}else{System.out.println("Transition to UTC/GMT");};
return true;
}
}
So on the UTC computer it fails miserably as it always puts Calendar.DST_OFFSET at zero. I have clearly misunderstood something along the way so any help/clarity would be good.
I pretty much have to keep Calendars as the rest of the code uses it but I realise the Java8 has many more fancy ways to do things.
Please allow me to be honest, I tried to read your code and didn’t really understand your way of trying to obtain what you want. If you can use Java 8, I recommend switching to using the Java 8 date and time classes. With these your job isn’t very complicated. For the demonstration I have chosen last October 30, the date when Britain (and EU) changed back from summer time (daylight saving time) to standard time.
String originalDate = "2016-10-30 23:35";
LocalDateTime localTime = LocalDateTime.parse(originalDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
ZonedDateTime utcTime = localTime.atZone(ZoneOffset.UTC);
ZonedDateTime bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
// the summer time offset is how many milliseconds?
long dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 0
// try the same at start of day (midnight)
utcTime = utcTime.toLocalDate().atStartOfDay(ZoneOffset.UTC);
bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 3600000
// and next midnight
utcTime = utcTime.plusDays(1);
bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 0
You are using
Calendar calBST = Calendar.getInstance();
That sets calBST to the computer's timezone (on the UTC computer, it will be UTC).
calBST.setTime(dateObjBST); sets the time, not the timezone.
Try using getInstance(TimeZone zone) there also.
In any case, I would replace your code like this:
Calendar calStartofDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calStartofDay.set(Calendar.YEAR, 2017);
calStartofDay.set(Calendar.MONTH, 0);
calStartofDay.set(Calendar.DAY_OF_MONTH, 21);
calStartofDay.set(Calendar.HOUR_OF_DAY, 00);
calStartofDay.set(Calendar.MINUTE, 0);
calStartofDay.set(Calendar.SECOND, 1);
Calendar calBST = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));
calBST.setTimeInMillis(calStartofDay.getTimeInMillis());
// use this to check the time
System.out.printf("%tc%n", calBST);
Also, from the Calendar docs, be careful about this:
set(f, value) changes calendar field f to value. In addition, it sets
an internal member variable to indicate that calendar field f has been
changed. Although calendar field f is changed immediately, the
calendar's time value in milliseconds is not recomputed until the next
call to get(), getTime(), getTimeInMillis(), add(), or roll() is made.
Thus, multiple calls to set() do not trigger multiple, unnecessary
computations. As a result of changing a calendar field using set(),
other calendar fields may also change, depending on the calendar
field, the calendar field value, and the calendar system. In addition,
get(f) will not necessarily return value set by the call to the set
method after the calendar fields have been recomputed. The specifics
are determined by the concrete calendar class.

java.util.date getActualMaximum(Calendar.DAY_OF_MONTH) [duplicate]

I am having issues with the calculation of when the next Last Day of the Month is for a notification which is scheduled to be sent.
Here is my code:
RecurrenceFrequency recurrenceFrequency = notification.getRecurrenceFrequency();
Calendar nextNotifTime = Calendar.getInstance();
This is the line causing issues I believe:
nextNotifTime.add(recurrenceFrequency.getRecurrencePeriod(),
recurrenceFrequency.getRecurrenceOffset());
How can I use the Calendar to properly set the last day of the next month for the notification?
Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
This returns actual maximum for current month. For example it is February of leap year now, so it returns 29 as int.
java.time.temporal.TemporalAdjusters.lastDayOfMonth()
Using the java.time library built into Java 8, you can use the TemporalAdjuster interface. We find an implementation ready for use in the TemporalAdjusters utility class: lastDayOfMonth.
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
LocalDate now = LocalDate.now(); //2015-11-23
LocalDate lastDay = now.with(TemporalAdjusters.lastDayOfMonth()); //2015-11-30
If you need to add time information, you may use any available LocalDate to LocalDateTime conversion like
lastDay.atStartOfDay(); //2015-11-30T00:00
And to get last day as Date object:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
Date lastDayOfMonth = cal.getTime();
You can set the calendar to the first of next month and then subtract a day.
Calendar nextNotifTime = Calendar.getInstance();
nextNotifTime.add(Calendar.MONTH, 1);
nextNotifTime.set(Calendar.DATE, 1);
nextNotifTime.add(Calendar.DATE, -1);
After running this code nextNotifTime will be set to the last day of the current month. Keep in mind if today is the last day of the month the net effect of this code is that the Calendar object remains unchanged.
Following will always give proper results:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, ANY_MONTH);
cal.set(Calendar.YEAR, ANY_YEAR);
cal.set(Calendar.DAY_OF_MONTH, 1);// This is necessary to get proper results
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
cal.getTime();
You can also use YearMonth.
Like:
YearMonth.of(2019,7).atEndOfMonth()
YearMonth.of(2019,7).atDay(1)
See
https://docs.oracle.com/javase/8/docs/api/java/time/YearMonth.html#atEndOfMonth--
Using the latest java.time library here is the best solution:
LocalDate date = LocalDate.now();
LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
Alternatively, you can do:
LocalDate endOfMonth = date.withDayOfMonth(date.lengthOfMonth());
Look at the getActualMaximum(int field) method of the Calendar object.
If you set your Calendar object to be in the month for which you are seeking the last date, then getActualMaximum(Calendar.DAY_OF_MONTH) will give you the last day.
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = sdf.parse("11/02/2016");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
System.out.println("First Day Of Month : " + calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
System.out.println("Last Day of Month : " + calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
Kotlin date extension implementation using java.util.Calendar
fun Date.toEndOfMonth(): Date {
return Calendar.getInstance().apply {
time = this#toEndOfMonth
}.toEndOfMonth().time
}
fun Calendar.toEndOfMonth(): Calendar {
set(Calendar.DAY_OF_MONTH, getActualMaximum(Calendar.DAY_OF_MONTH))
return this
}
You can call toEndOfMonth function on each Date object like Date().toEndOfMonth()

Adding date in Gregorian Calendar

import java.util.GregorianCalendar;
public class CalendarMain {
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar();
int month = calendar.get(GregorianCalendar.MONTH)+1;
int year = calendar.get(GregorianCalendar.YEAR);
int weekday = calendar.get(GregorianCalendar.DAY_OF_WEEK);
int dayOfMonth = calendar.get(GregorianCalendar.DAY_OF_MONTH);
System.out.println(month+"/"+dayOfMonth+"/"+year);
calendar.add(GregorianCalendar.DAY_OF_MONTH, 10);
System.out.println(GregorianCalendar.DAY_OF_MONTH);
}
}
I am trying to add 10 days to the current date but am getting a weird problem. It does not seem to be adding correctly.
Output:
9/18/2014
5
// Get a calendar which is set to a specified date.
Calendar calendar = new GregorianCalendar(2014, Calendar.JANUARY, 1);
// Get the current date representation of the calendar.
Date startDate = calendar.getTime();
// Increment the calendar's date by 1 day.
calendar.add(Calendar.DAY_OF_MONTH, 1);
// Get the current date representation of the calendar.
Date endDate = calendar.getTime();
System.out.println(startDate);
System.out.println(endDate);
I think the last row is wrong, try this:
System.out.println(calendar.get(GregorianCalendar.DAY_OF_MONTH));
Use
System.out.println(calendar.get(GregorianCalendar.DAY_OF_MONTH));
instead of
System.out.println(GregorianCalendar.DAY_OF_MONTH);
Output :
9/18/2014
28
What you were doing in your code is printing the integer code of GregorianCalendar.DAY_OF_MONTH final variable, Which will remain 5, no matter what you have added in calendar. You were needed to use calendar.get(...) function to get the date of month of this calendar.

Compare dates using Calendar class using java

The user entered date is using a drop down separately for day, month and year. I have to compare the user entered date with today's date and check if it is same day or future day. I am a bit confused about the time portion because I am not interested in time, just the date. How to solve this without using the Date class (I read it is not recommended to use Date class).
Thanks.
You first need to create GregorianCalendar instance representing entered date:
Calendar user = new GregorianCalendar(2012, Calendar.MAY, 17);
And one for "now":
Calendar now = new GregorianCalendar();
This will yield positive value if date is in the future and negative - if in the past:
user.compareTo(now);
Few notes about constructing user object:
it uses current JVM time zone, so in my case it is midnight, 17th of May in CEST time zone
be careful with months, they are 0-based
Try class DateUtils of library Apache Commons Lang.
This class provides the method truncatedEquals(cal1, cal2, field).
So you can check for equality with a single line of code:
Calendar user = new GregorianCalendar(2012, Calendar.MAY, 17);
Calendar now = Calendar.getInstance();
if(DateUtils.truncatedEquals(user, now, Calendar.DATE)){
// your code goes here
}
Simple calculation :
GregorianCalendar gc1 = new GregorianCalendar();
GregorianCalendar gc2 = new GregorianCalendar();
gc2.add(GregorianCalendar.DAY_OF_MONTH, 2); // gc2 is 2 days after gc1
long duration = (gc2.getTimeInMillis() - gc1.getTimeInMillis() )
/ ( 1000 * 60 * 60 * 24) ;
System.out.println(duration);
-> 2
Use a gregorian calendar.
If you wanted to know the number of days difference between two dates then you could make a method similar to the following.
public int getDays(GregorianCalendar g1, GregorianCalendar g2) {
int elapsed = 0;
GregorianCalendar gc1, gc2;
if (g2.after(g1)) {
gc2 = (GregorianCalendar) g2.clone();
gc1 = (GregorianCalendar) g1.clone();
}
else {
gc2 = (GregorianCalendar) g1.clone();
gc1 = (GregorianCalendar) g2.clone();
}
gc1.clear(Calendar.MILLISECOND);
gc1.clear(Calendar.SECOND);
gc1.clear(Calendar.MINUTE);
gc1.clear(Calendar.HOUR_OF_DAY);
gc2.clear(Calendar.MILLISECOND);
gc2.clear(Calendar.SECOND);
gc2.clear(Calendar.MINUTE);
gc2.clear(Calendar.HOUR_OF_DAY);
while ( gc1.before(gc2) ) {
gc1.add(Calendar.DATE, 1);
elapsed++;
}
return elapsed;
}
That would return you the difference in the number of days.
Try this solution:
int day = 0; //user provided
int month = 0; //user provided
int year = 0; //user provided
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONDAY, month);
calendar.set(Calendar.DAY_OF_MONTH, day);
long millisUser = calendar.getTime().getTime();
long nowMillis = System.currentTimeMillis();
if(nowMillis < millisUser) {
...
}
Above is check if date is in future.
There is nothing wrong in using java.util.Date
You can use:
int day = 0; //user provided
int month = 0; //user provided
int year = 0; //user provided
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONDAY, month);
calendar.set(Calendar.DAY_OF_MONTH, day);
Date userSubmit = calendar.getTime();
Date now = new Date();
if(userSubmit.after(now)) {
...
}
But if you want fluent, easy and intuitive API with dates I recommend using JodaTime

How to get date of last Friday from specified date? [duplicate]

This question already has answers here:
Time: How to get the next friday?
(9 answers)
Closed 6 years ago.
How can I find out the date of last (previous) "Friday" or any other day from a specified date?
public getDateOnDay(Date date, String dayName) {
// ?
}
I won't give an answer (try it yourself first!), but, maybe these tips can help you out.
You first need to figure out the current day of the week you are on. You may want to take a look at Java's Calendar class to get an idea of how to do that.
Once you get the date you are on, think about the modulus operator and how you can use that to move backwards to pick up the previous day that you are looking for from the day you are currently at. (Remember, a week is 7 days and each day of the week takes up a "slot" in those 7 days.)
Once you have the number of days in between, you'll want to subtract. Of course, there are classes that can add and subtract days for you in the Java framework...
I hope that helps. Again, I encourage you to always try the problem for yourself, first. You learn far much more that way and be a better developer in the long run for it.
Here is a brute force idea. Check if current date is friday. If not, subtract 1 day from today. Check if new date is friday. If not, subtract 1 day from new date..... so on.. you get the idea.
Try this one:
/**
* Return last day of week before specified date.
* #param date - reference date.
* #param day - DoW field from Calendar class.
* #return
*/
public static Date getDateOnDay(Date date, int day) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.WEEK_OF_YEAR, -1);
cal.set(Calendar.DAY_OF_WEEK, day);
return cal.getTime();
}
Good luck.
I'm using this:
private Date getDateOnDay(Date date, int day) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.setFirstDayOfWeek(day);
cal.set(Calendar.DAY_OF_WEEK, day);
return cal.getTime();
}
Get the day of week for the date. Look at Calendar javadoc. Once you have the day of the week you can calculate an offset to apply to the date.
To get any latest date based on weekday:
private String getWeekDayDate(String weekday){
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Calendar start = Calendar.getInstance();
Date now = new Date();
start.setTime(now);
Calendar end = Calendar.getInstance();
end.add(Calendar.DATE, -7);
while (start.after(end))
{
try {
Date temp = start.getTime();
String day = new SimpleDateFormat("EEEE").format(temp);
if(day.equalsIgnoreCase(weekday))
return formatter.format(temp);
}catch(Exception e) {
e.printStackTrace();
}
start.add(Calendar.DAY_OF_YEAR, -1);
}
return null;
}
To get latest Friday date, give weekday as "Friday"
//gets the last four Fridays from today's date if you want pass in a any date
//just need to tweak the code, the other method just basically formats the date in dd/MM/YYYY format.
function GetLastFourFridays() {
today = new Date();
LastFridayDate = new Date();
LastFridayDate.setDate(LastFridayDate.getDate() - 1);
while (LastFridayDate.getDay() != 5) {
LastFridayDate.setDate(LastFridayDate.getDate() - 1);
}
var lfd = LastFridayDate
lfd = convertDate(lfd)
document.getElementById("first_week_th").innerHTML = lfd
LastFridayDate.setDate(LastFridayDate.getDate() - 1);
var friLastWeek = LastFridayDate
while (friLastWeek.getDay() != 5) {
friLastWeek.setDate(friLastWeek.getDate() - 1);
}
var flw = friLastWeek
flw = convertDate(flw)
document.getElementById("second_week_th").innerHTML = flw
friLastWeek.setDate(friLastWeek.getDate() - 1);
var friTwoWeeks = friLastWeek
while (friTwoWeeks.getDay() != 5) {
friTwoWeeks.setDate(friTwoWeeks.getDate() - 1);
}
var ftw = friTwoWeeks
ftw = convertDate(ftw)
document.getElementById("third_week_th").innerHTML = ftw
friTwoWeeks.setDate(friTwoWeeks.getDate() - 1);
var friThreeWeeks = friTwoWeeks
while (friThreeWeeks.getDay() != 5) {
friThreeWeeks.setDate(friThreeWeeks.getDate() - 1);
}
var ftww = friThreeWeeks
ftww = convertDate(ftww)
document.getElementById("fourth_week_th").innerHTML = ftww
}
//convets the date 00//00//0000
function convertDate(inputFormat) {
function pad(s) { return (s < 10) ? '0' + s : s; }
var d = new Date(inputFormat);
return [pad(d.getDate()), pad(d.getMonth()+1), d.getFullYear()].join('/');}

Categories

Resources