Using GregorianCalendar to get weeks - java

I'm looking to utilize GregorianCalendar to do some logic based on days. Is there any way to see if 2 dates are in the same week? I've tried using get(Calendar.WEEK_OF_YEAR), and this has the two downsides of:
1) Starting on the wrong day of the week (which seems to have a potential solution in setFirstDayOfWeek, however preliminary testing has not been successful.
2) This solution does not carry over years nicely. For example - Dec 30th, 2014 and Jan 1, 2015 should be in the same week.
Is there any solution to this that doesn't require switching libraries?

OK, since you've stated there will be a time component, I'd use something similar to #MadProgrammer's answer, but without the complexity of using an entire date range. I'd have a static method something like this.
public static Date firstOfWeek(Calendar cal) {
Calendar copy = new GregorianCalendar(
cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE));
copy.set(Calendar.DAY_OF_WEEK, copy.getFirstDayOfWeek());
return copy.getTime();
}
This returns a Date for the first day of the week that includes a particular Calendar. You can then check whether two calendars fall in the same week like this.
if (firstOfWeek(cal1).equals(firstOfWeek(cal2))) {
...
}

You question basically boils down to determining if a given date falls within a given date range (ie a week).
The idea behind this is basically one of the two date's acts as the anchor, from which we calculate the date range (start of week to end of week) and then determine if the other date falls within that range.
So, first, we need to calculate the date range, something like...
Calendar cal = Calendar.getInstance();
cal.setTime(date1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
Date startOfWeek = cal.getTime();
cal.add(Calendar.DATE, 6);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
Date endOfWeek = cal.getTime();
Which will give us two dates, the first starting at the "start of the week" and one 6 days later (the "end of the week"). We force the time values to the extreme of the days to ensure we can capture the fall range
Next, we need to determine if the other date is equal to or after the "start of the week" and equal to or before the "end of the week", something like...
(date2.equals(startOfWeek) || date2.after(startOfWeek)) && (date2.equals(endOfWeek) || date2.before(endOfWeek));
This could then be wrapped up in a nice little method to make calling it simpler...
public static boolean isInSameWeek(Date date1, Date date2) {
Calendar cal = Calendar.getInstance();
cal.setTime(date1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
Date startOfWeek = cal.getTime();
cal.add(Calendar.DATE, 6);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
Date endOfWeek = cal.getTime();
System.out.println("Week starts at : " + startOfWeek);
System.out.println(" Week ends at : " + endOfWeek);
return (date2.equals(startOfWeek) || date2.after(startOfWeek)) && (date2.equals(endOfWeek) || date2.before(endOfWeek));
}
And then we can test it...
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
try {
Date date1 = sdf.parse("30/12/2014");
Date date2 = sdf.parse("1/1/2015");
System.out.println("Is in same week " + date1 + "/" + date2 + " = " + isInSameWeek(date1, date2));
System.out.println("");
date1 = sdf.parse("27/12/2014");
System.out.println("Is in same week " + date1 + "/" + date2 + " = " + isInSameWeek(date1, date2));
} catch (ParseException exp) {
exp.printStackTrace();
}
Which outputs something like...
Week starts at : Sun Dec 28 00:00:00 EST 2014
Week ends at : Sat Jan 03 23:59:59 EST 2015
Is in same week Tue Dec 30 00:00:00 EST 2014/Thu Jan 01 00:00:00 EST 2015 = true
Week starts at : Sun Dec 21 00:00:00 EST 2014
Week ends at : Sat Dec 27 23:59:59 EST 2014
Is in same week Sat Dec 27 00:00:00 EST 2014/Thu Jan 01 00:00:00 EST 2015 = false

Related

How to use Apache DateUtils to get previous month from first day to last day with time [JAVA]?

If the input is today(June 7), then it should give me May 1 12:00 AM to May 31, 11:59 PM.
I was using Calendar but I want to use DateUtils.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH, -1);
calendar.set(Calendar.HOUR,23);
calendar.set(Calendar.MINUTE,59);
calendar.set(Calendar.SECOND,59);
System.out.println("Last date of month: " + calendar.getTime());
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR, 12);
calendar.set(Calendar.MINUTE,00);
calendar.set(Calendar.SECOND,00);
System.out.println("fir stdate of month: " + calendar.getTime());
DateUtils can do the required:
Date lastmonth = DateUtils.addMonths(new Date(), -1);
System.out.println(lastmonth);
System.out.println(DateUtils.truncate(lastmonth, Calendar.MONTH));
System.out.println(DateUtils.addMinutes(DateUtils.ceiling(lastmonth, Calendar.MONTH), -1));
Edit: Adding output
Sat May 07 23:06:05 AST 2016
Sun May 01 00:00:00 AST 2016
Tue May 31 23:59:00 AST 2016
I ended up using JodaTime. Much easier!
MutableDateTime dateTime = new MutableDateTime();
System.out.println("CurrentTime " + dateTime);
dateTime.addMonths(-1); //last Month
dateTime.setMinuteOfDay(0);
dateTime.setSecondOfMinute(0);
dateTime.setHourOfDay(12);
dateTime.setDayOfMonth(1); //first Day of last Month
System.out.println("first Day Time " + dateTime);
dateTime.setDayOfMonth(dateTime.dayOfMonth().getMaximumValue()); //set Day to last Day of that month
dateTime.setMinuteOfDay(59);
dateTime.setSecondOfMinute(59);
dateTime.setHourOfDay(23); //time set to night time 11:59:59
System.out.println("last Day Time " + dateTime);

Get next Date from day hour:minutes

I am trying to get the next Date that match a date format, like getting next Date that match "1 10:00" (format: u HH:mm).
Example: If we are Tuesday June 2 - 22:00 (for example), I want to get Sunday June 7 - 10:00 as a Date object (because it does match "1 10:00" format)
EDIT: It was "u" instead of "F", sorry !
If I understand good your question, this will do the trick. Basically adding 1 minute to current date until you find your desired date by its format.
You'd want to set a safest condition than true.
Calendar calendar = Calendar.getInstance();
Date date = new Date("06/02/2015 10:00");
calendar.setTime(date);
SimpleDateFormat sdf = new SimpleDateFormat("F HH:mm");
while (true) {
calendar.add(Calendar.MINUTE, 1);
if (sdf.format(calendar.getTime()).equals(sdf.format(date))) {
System.out.println(calendar.getTime());
break;
}
}
This prints:
Wed Jun 03 10:00:00 VET 2015 ... and 1440 minutes were added.
I finally found a solution myself :
public static Date getNextDate(SimpleDateFormat format, String value) {
try {
Date date = format.parse(value);
Calendar calendar = Calendar.getInstance();
int diff = date.getDay() - calendar.get(Calendar.DAY_OF_WEEK);
if (!(diff > 0)) {
diff += 7;
}
calendar.add(Calendar.DAY_OF_MONTH, diff);
calendar.set(Calendar.HOUR_OF_DAY, date.getHours());
calendar.set(Calendar.MINUTE, date.getMinutes());
calendar.set(Calendar.MINUTE, date.getSeconds());
return calendar.getTime();
} catch (ParseException exception) {
exception.printStackTrace();
}
return null;
}
It will return the next date that match my format. I use deprecated methods but I will fix it asap.
Thanks for helping anyway !

How does changing DAY_OF_WEEK in java.util.Calendar work?

I am trying to change DayofWeek in Calendar but doesnt appear to be working as I expect. Here is an example. I set calendar time to a Friday time, but when I set Calendar.DAY_OF_WEEK to Calendar.SUNDAY, it is moving forward to next week. Since Calendar.SUNDAY is first day of week by default, shouldn't it move the time back to beginning of current week?
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class GenericWeekdayOpenFunction implements TimePeriodFunction {
public static void main(String[] args) {
// Nov 8 is Friday
long time = DateUtilities.newDateTimeAsMillis(2013, 11, 8, 10, 00, 00);
System.out.println(DateUtilities.formatGmtDatetime(time));
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
calendar.setTimeInMillis(time);
// move day of week to Sunday, expect date to be Nov 3
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(DateUtilities.formatGmtDatetime(calendar.getTimeInMillis())); // wrong
// move day of week to Friday, expect date to be Nov 8
calendar.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
System.out.println(DateUtilities.formatGmtDatetime(calendar.getTimeInMillis()));
}
}
Output:
08-11-2013 10:00:00.000
10-11-2013 10:00:00.000
08-11-2013 10:00:00.000
Your scenario working fine with basic Calendar class usage:
Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date d = new Date(113, 10, 8, 10, 0, 0);
c.setTimeInMillis(d.getTime());
System.out.println(c.getTime());
c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(c.getTime());
c.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
System.out.println(c.getTime());
Output:
Fri Nov 08 10:00:00 IST 2013
Sun Nov 03 10:00:00 IST 2013
Fri Nov 08 10:00:00 IST 2013
Note that Date(113, 10, 8, 10, 0, 0); is used only for quick check, it is deprecated though. Trying for any other combination also works fine. Can you just try using basic Calendar API and print dates ie
Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
System.out.println(c.getTime());//current day
c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(c.getTime());
second date should go back to previous sunday not upcoming one. If it's working for you then DateUtilities implementation may be doubtful.
I think that the method set(int field, int value)
Works approaching to the nearest day (not to the DAY_OF_WEEK of the same week).
But you can use the function add(int field, int amount) in this case add(Calendar.DATE, -5) to do that.

wrong time calculating in Java

when I want to sum two dates in java it does not work:
System.out.println(date + " <---- date");
System.out.println(time + " <---- time");
System.out.println(new Date(date.getTime() + time.getTime()) + " <---- new Date(time.getTime() + date.getTime())");
leads to following output:
Wed Nov 06 00:00:00 CET 2013 <---- date
Thu Jan 01 11:51:14 CET 1970 <---- time
Wed Nov 06 10:51:14 CET 2013 <---- new Date(time.getTime() + date.getTime())
... but if i work with Calender it works!
Calendar calendar = Calendar.getInstance();
calendar.setTime(time);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int min = calendar.get(Calendar.MINUTE);
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, min);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date myDate = calendar.getTime();
System.out.println(myDate);
results in
Wed Nov 06 11:51:00 CET 2013
which is correct
Can anybody explain me why?
Fundamentally, you've got problems with time zones here. The fact that you're using a java.util.Date to represent a time of day is messing you up to start with. Your time of 11:51:14 CET is actually 10:51:14 UTC, so when you add the result of calling time.getTime(), you're only adding "just under 11 hours" rather than "just under 12 hours". The use of inappropriate data types makes all this hard to work with and understand.
I'd strongly recommend using Joda Time for all of this. Then you can start with a LocalDate and LocalTime, combine them into a LocalDateTime and then work out if you want to apply a particular time zone.
Using the right data types, which mean exactly what you're trying to convey, makes a huge difference for date/time work.

Java Calendar 31st January issue

I have the following code :-
Calendar calc = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("MMM-yyyy");
calc.set(Calendar.YEAR, calc.get(Calendar.YEAR) - 1);
calc.set(Calendar.MONTH, Calendar.NOVEMBER);
System.out.println("---NOV? : " + sdf.format(calc.getTime()));
Calendar calc1 = Calendar.getInstance();
calc1.set(Calendar.YEAR, calc1.get(Calendar.YEAR) - 1);
calc1.set(Calendar.MONTH, Calendar.DECEMBER);
System.out.println("-- DEC : " + sdf.format(calc1.getTime()));
The output of the above code is :-
> ---NOV? : Dec-2012
> -- DEC : Dec-2012
This happens only for 31st january, can someone explain why this might be happening?
The Calendar is set for lenient interpretation, so if you tell it the 31st day of November, well, November only has 30 days, so it rolls over to December 1st.
I suspect the first case is rounding "November 31" to "December 1", since you're not changing the day in your calendar.

Categories

Resources