I have some code that gets the current week and loads it into an array:
DateFormat format = new SimpleDateFormat("M-dd");
calendar = Calendar.getInstance();
calendar.setFirstDayOfWeek(Calendar.SUNDAY);
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
days = new String[7];
for (int i = 0; i < 7; i++)
{
calendar.add(Calendar.DATE, 1);
days[i] = format.format(calendar.getTime());
}
I then have some code that runs on the selection of a button that will retrieve the previous week dates and loads them into an array:
DateFormat format = new SimpleDateFormat("M-dd");
days = new String[7];
for (int i = 0; i < 7; i++)
{
calendar.add(Calendar.DATE, -1);
days[i]=format.format(calendar.getTime());
}
My issue is that it will load for example: 5-22-17, 5-23-17, 5-24-17, 5-25-17, 5-26-17, 5-27-17, 5-28-17 into the initial load for the first week and then when I click on my Previous button to run the previous button code it only goes back 1 day: 5-21-17 - 5-27-17. If I click it again it then goes back a whole week: 5-14-17 - 5-20-17.
How can I fix my code to retrieve the previous week days correctly on the first click?
First, you set first day of week to Sunday, but you then add 1 before getting first value, so result is Mon 5/22 to Sun 5/28, not Sun 5/21 to Sat 5/27.
Second, when your first loop is done, the Calendar object is sitting at 5/28. You then go backwards, subtracting 1 before getting last value, so result is 5/27 down to 5/21, not 5/21 to 5/27 like you said.
That leaves Calendar object sitting at 5/21. Repeating the above, you get 5/20 down to 5/14, not 5/14 to 5/20.
So, to get your results as a week of Sunday to Saturday, like you told the Calendar that you wanted, add 1 after the getting the value. And to get a week in the right order, always get them incrementally. To go back to previous week, since Calendar is sitting after the week, you go back 2 weeks to start building the previous week.
public class Test {
private Calendar calendar;
public String[] getCurrentWeek() {
this.calendar = Calendar.getInstance();
this.calendar.setFirstDayOfWeek(Calendar.SUNDAY);
this.calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
return getNextWeek();
}
public String[] getNextWeek() {
DateFormat format = new SimpleDateFormat("M-dd");
String[] days = new String[7];
for (int i = 0; i < 7; i++) {
days[i] = format.format(this.calendar.getTime());
this.calendar.add(Calendar.DATE, 1);
}
return days;
}
public String[] getPreviousWeek() {
this.calendar.add(Calendar.DATE, -14);
return getNextWeek();
}
public static void main(String[] args) {
Test t = new Test();
System.out.println("Current : " + Arrays.toString(t.getCurrentWeek()));
System.out.println("Previous: " + Arrays.toString(t.getPreviousWeek()));
System.out.println("Previous: " + Arrays.toString(t.getPreviousWeek()));
System.out.println("Next : " + Arrays.toString(t.getNextWeek()));
System.out.println("Next : " + Arrays.toString(t.getNextWeek()));
}
}
Output
Current : [5-21, 5-22, 5-23, 5-24, 5-25, 5-26, 5-27]
Previous: [5-14, 5-15, 5-16, 5-17, 5-18, 5-19, 5-20]
Previous: [5-07, 5-08, 5-09, 5-10, 5-11, 5-12, 5-13]
Next : [5-14, 5-15, 5-16, 5-17, 5-18, 5-19, 5-20]
Next : [5-21, 5-22, 5-23, 5-24, 5-25, 5-26, 5-27]
I believe the issue is the fact the calendar is advancing and retreating, rather than being used as an anchor. This code shows one approach to handling the situation. It keeps the current start of the week, and obtains days from that point.
/**
* Returns 7 days starting from the specified starting date
*/
private static String[] getDays(Calendar starting)
{
DateFormat format = new SimpleDateFormat("M-dd");
String[] days = new String[7];
Calendar mod = Calendar.getInstance();
mod.setTime(starting.getTime());
for (int i = 0; i < days.length; ++i) {
mod.add(Calendar.DATE, 1);
days[i] = format.format(mod.getTime());
}
return days;
}
public static void main(String[] args)
{
// this sets to the beginning of the current week
Calendar cal = Calendar.getInstance();
cal.setFirstDayOfWeek(Calendar.SUNDAY);
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
// need this to back up
Calendar beginningOfWeek = cal;
// generate the array
String days[] = getDays(beginningOfWeek);
System.out.println(Arrays.toString(getDays(beginningOfWeek)));
// go forward one week
beginningOfWeek.add(Calendar.DATE, 7);
System.out.println(Arrays.toString(getDays(beginningOfWeek)));
// go back one week; same as starting
beginningOfWeek.add(Calendar.DATE, -7);
System.out.println(Arrays.toString(getDays(beginningOfWeek)));
// go back one week; one week before we began
beginningOfWeek.add(Calendar.DATE, -7);
System.out.println(Arrays.toString(getDays(beginningOfWeek)));
}
Example output:
[5-22, 5-23, 5-24, 5-25, 5-26, 5-27, 5-28]
[5-29, 5-30, 5-31, 6-01, 6-02, 6-03, 6-04]
[5-22, 5-23, 5-24, 5-25, 5-26, 5-27, 5-28]
[5-15, 5-16, 5-17, 5-18, 5-19, 5-20, 5-21]
Note there are several optimizations that could be applied, such as not creating the format every time the getDays(...) method is called. Also, the variable names are essentially from the OP, but are perhaps not optimal.
Related
Okay got my head spinning from reviewing a bunch of other code but now i gotta tackle something that seems easy but i can't figure it out.
I need to update a function that currently gets today's date, checks if it is NOT Saturday if it is not then we go ahead and make java cal to Saturday and then add -7 days to it. This function allows us to get the last day of a pay period but now we are going to go bi-weekly so now I need to update the code to check the date and if it is greater then last weekly date of pay which was the 7/17th (7/11/2021 - 7/17/2021). Our first bi-weekly pay is 7/18 - 7/31 so any of these days need to look for the last endate to be 7/17 then all other bi-weekly need to look at the end dates of the other bi-weekly. So I need to figure out the logic that would figure out how much it will add -x to the week. My thought is add -7 to the first week of the bi weekly and -14 or the second week of the bi weekly. Trying to avoid having to do drastic updates throughout the code.
public Calendar getLastEndDate() {
Calendar cal = Calendar.getInstance();
if(cal.get(Calendar.DAY_OF_WEEK)!=Calendar.SATURDAY){
cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
cal.add(Calendar.DATE, -7);
}
cal.set(Calendar.HOUR_OF_DAY,0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
return cal;}
I could be wrong so feel free to correct me and i'll make adjustments. After looking at the requirements, what it seems you really want to do is get the duration between now and the next pay date. To do that, you need to know the next pay date.
To calculate the pay date we can use the initial date you indicated and continue for N days/weeks until the current date is before the end date for the pay period.
That way we know that the start of the pay period is endDate - cycle and the duration until the pay date is endDate - currentDate.
public static void main(String[] args) {
LocalDate firstPayDate = LocalDate.of(2021, 7, 18);
LocalDate currentDate = LocalDate.now();
Period payCycle = Period.ofWeeks(2);
LocalDate nextPayDate = nextPayDate(firstPayDate, payCycle, currentDate);
Period periodUntilPayDate = Period.between(currentDate, nextPayDate);
System.out.printf("Next pay date is in %d days on %s.",
periodUntilPayDate.getDays(),
nextPayDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
}
private static LocalDate nextPayDate(LocalDate payDate, Period payCycle, LocalDate currentDate) {
while (currentDate.isAfter(payDate)) {
payDate = payDate.plus(payCycle);
if (currentDate.isBefore(payDate)) {
return payDate;
}
}
throw new IllegalStateException("Could not find pay period.");
}
Next pay date is in 9 days on 2021-08-01.
Also, this is kind of out of scope but if you wanted to cover a few bases you could validate input.
Preconditions.checkNotNull(payDate);
Preconditions.checkNotNull(payCycle);
Preconditions.checkNotNull(currentDate);
Preconditions.checkArgument(!payCycle.isNegative());
Preconditions.checkArgument(!payCycle.isZero());
I think that you will have to check the week numbers.
If you are always doing payout on even weeks the following code would work.
Test code included.
import java.text.DateFormat;
import java.util.Calendar;
import static java.util.Calendar.*;
public class BiWeekly {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
DateFormat df = DateFormat.getDateInstance();
for (int i = 1; i <= 31; i++) {
cal.set(DATE, i);
System.out.print("Today is: " + df.format(cal.getTime()));
System.out.print(", Week: " + cal.get(WEEK_OF_YEAR));
BiWeekly bw = new BiWeekly();
System.out.println(", Last payout was: " + df.format(bw.getLastEndDate(cal).getTime()));
}
}
public Calendar getLastEndDate(Calendar orig) {
Calendar cal = new Calendar.Builder().setInstant(orig.getTime()).build();
int week = cal.get(WEEK_OF_YEAR);
if (week % 2 == 0) {
cal.add(DATE, -7);
}
else {
cal.add(DATE, -14);
}
cal.set(DAY_OF_WEEK, SATURDAY);
cal.set(HOUR_OF_DAY, 0);
cal.set(MINUTE, 0);
cal.set(SECOND, 0);
cal.set(MILLISECOND, 0);
return cal;
}
}
I am working on an android app that will display a list of data. For example, if you start to use app today(28.05.2018)(MO) and I must calculate week number and add 7 days this week or you are starting Friday I must add 2 days this week.
I tried this method https://stackoverflow.com/a/42733001/9259044
but its wrong for me. First of all, I added dates and
TreeMap<Integer, List<Date>> dateHashMap = new TreeMap<>();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
List<Date> spDates = new ArrayList<>();
try {
spDates.add(sdf.parse("02/06/2018"));
spDates.add(sdf.parse("01/06/2018"));
spDates.add(sdf.parse("31/05/2018"));
spDates.add(sdf.parse("30/05/2018"));
spDates.add(sdf.parse("29/05/2018"));
spDates.add(sdf.parse("28/05/2018"));
spDates.add(sdf.parse("27/05/2018"));
spDates.add(sdf.parse("26/05/2018"));
spDates.add(sdf.parse("25/05/2018"));
} catch (ParseException e) {
e.printStackTrace();
}
I compare weekOfYear to my dates but this is wrong.
for (int i = 0; i < spDates.size(); i++) {
List<Date> datesList = new ArrayList<>();
Calendar calendar = Calendar.getInstance();
calendar.setTime(spDates.get(i));
int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
for (Date date : spDates) {
Calendar c = Calendar.getInstance();
c.setTime(date);
if (weekOfYear == c.get(Calendar.WEEK_OF_YEAR)) {
datesList.add(date);
}
}
dateHashMap.put(weekOfYear, datesList);
}
Log.d("DATE",dateHashMap.toString());
Do you have any idea how can I group my Dates to week Number?
I think you want this:
LocalDate today = LocalDate.now(ZoneId.of("Europe/Istanbul"));
int weekNumber = today.get(WeekFields.ISO.weekOfYear());
System.out.println("Week no. " + weekNumber);
LocalDate[] days = today.datesUntil(today.with(TemporalAdjusters.next(DayOfWeek.MONDAY)))
.toArray(LocalDate[]::new);
System.out.println(Arrays.toString(days));
Running it today (Monday, May 28) it printed
Week no. 22
[2018-05-28, 2018-05-29, 2018-05-30, 2018-05-31, 2018-06-01, 2018-06-02, 2018-06-03]
It gives you all the dates from today, inclusive, until next Monday, exclusive. If Monday is the first day of the week, this means the remaining days of this week.
I have a function to return all dates for a specific week.
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.WEEK_OF_YEAR, week);
String[] dates = new String[7];
currentlySelectedYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
// i = 2 because MONDAY is day two in week
for (int i = 2; i < 9; i++) {
cal.set(Calendar.DAY_OF_WEEK, i);
//i-2 to start the array at index 0
dates[i - 2] = sdf.format(cal.getTime());
}
it works fine on all devices except samsung where each time the for loop is entered again after the first iteration the WEEK_OF_YEAR field in the calendar is reset to current week instead of the week set three lines above.
Is this a known bug for samsung or am I missing something?
Is there another way to do the same thing that maybe work on all devices?
I'm new to Java. I have this code which is used to get the days of the week starting of the current.
GregorianCalendar calendar = new GregorianCalendar();
DateFormat df = new SimpleDateFormat("EEEE");
for (int i = 0; i < 7; i++) {
calendar.add(Calendar.DATE, 1);
System.out.println(df.format(calendar.getTime()));
}
I want edit the code to get the months of the year in the same way - starting from the present month. Can you help me to edit the code.
Well, you could set the day of the month to 1 (just for sanity) and then just add a month on each step instead of a day. Alternatively, you could just use:
DateFormatSymbols symbols = new DateFormatSymbols(locale);
String[] months = symbols.getMonths();
... and go from there.
You could use getWeekdays in the same way for the day names, too.
You can use Calendar.MONTH. With minimal changes to your code, it'll look like this:
GregorianCalendar calendar = new GregorianCalendar();
DateFormat df = new SimpleDateFormat("MMMM");
for (int i = 0; i < 12; i++) {
calendar.add(Calendar.MONTH, 1);
System.out.println(df.format(calendar.getTime()));
}
In JodaTime you can do new DateTime() and then do plusMonths(1) to add one month. This will return the date one month on. You can then parse that to get the month. Then repeat 11 times to get the rest of the months.
This link will help to get the month name http://joda-time.sourceforge.net/key_instant.html
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('/');}