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?
Related
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 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.
I'm working on a method that can add dates like this :
public static ArrayList<Calendar> addDaysBetween(Calendar day1, Calendar day2)
Which returns the ArrayList containing all the dates between d1 & d2.
So, first I needed to know how many days exists between those two dates (Followed this example : https://stackoverflow.com/a/28865648/4944071)
I wrote something like this :
ArrayList<Calendar> fullDates = new ArrayList<Calendar>();
if(daysBetween > 0){
for(int day = 1; day <= daysBetween; day ++){
Calendar aNewDay = new GregorianCalendar(day1.YEAR, day1.MONTH, day1.DAY_OF_MONTH + day);
fullDates.add(aNewDay);
}
}
But, I'm pretty sure that this will not work at all. Imagine those parameters :
2012/12/21 to 2013/02/14
Not the same year, not the same month, It can't work properly. So, I scratched my head a little bit and decided to use the variable DAY_OF_YEAR.
But, i'm still stuck because I don't know how I could manipulate this variable to create correct dates with good Months & good Years..
You can try this
Calendar tmp = (Calendar) day1.clone();
ArrayList<Calendar> fullDates = new ArrayList<Calendar>();
while (tmp.before(day2)) {
fullDates.add((Calendar) tmp.clone());
tmp.add(Calendar.DAY_OF_MONTH, 1);
}
return fullDates;
With the java8 date api:
List<LocalDate> listOfDates = new ArrayList<>();
LocalDate endDay = LocalDate.of(2014, Month.JUNE, 20);
LocalDate startDay = LocalDate.of(2014, Month.JUNE, 11);
long days = ChronoUnit.DAYS.between(startDay, endDay);
for (int i = 1; i <= days; i++) {
listOfDates.add(startDay.plusDays(i));
}
if you want to convert to java.util.Date or Calendar:
Date d = Date.from(startDay.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
Calendar cal = Calendar.getInstance();
cal.setTime(d);
Try something like:
currentDay = day1;
while (currentDay < day2){
addcurrentday to collection
currentday++
}
I am getting confused while parsing a time difference[which I receive from a webpage].
For Example : I get a string like this : 2 years 10 weeks 3 days 6 hours 7 min ago. Please note that the trailing s in year, week, day and hour may not be there in case of unity and not present in the min.
Currently, I want to get the difference stored like that and get the actual date and time[by subtracting from the current time?].
And, I am confused what to do? I know about the Time parsing methods but its not a regular time, Plus there's that trailing s!!!
Can anyone suggest a good approach to this?
I'd recomend calculating how much time the difference is in milliseconds then subtracting that from now, that would be simple however you will run into an issue with leap years.
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -2);
cal.add(Calendar.WEEK_OF_YEAR, -10);
cal.add(Calendar.DAY_OF_YEAR, -3);
cal.add(Calendar.HOUR_OF_DAY, -6);
cal.add(Calendar.MINUTE, -7);
that should work fine, but I haven't tested it. you're also going to have to handle cases where you don't get a value for weeks for example.
You can use this code. This takes in accoutn the ss and the possible absense of some tokens.
String orig = "2 years 10 weeks 3 days 6 hours 7 min ago";
String[] split = orig.replaceAll("[^0-9]+", " ").trim().split(" ");
Calendar cal = Calendar.getInstance();
int idx = 0;
if (orig.contains("yea")) cal.add(Calendar.YEAR, -Integer.parseInt(split[idx++]));
if (orig.contains("wee")) cal.add(Calendar.WEEK_OF_MONTH, -Integer.parseInt(split[idx++]));
if (orig.contains("day")) cal.add(Calendar.DATE, -Integer.parseInt(split[idx++]));
if (orig.contains("hour")) cal.add(Calendar.HOUR, -Integer.parseInt(split[idx++]));
if (orig.contains("min")) cal.add(Calendar.MINUTE, -Integer.parseInt(split[idx++]));
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
String formattedString = sdf.format(cal.getTime());
System.out.println(formattedString); // it prints 04-26-2011 02:12:54
Using #Eluvatar's suggestion, assumg a space between each part:
Calendar cal = Calendar.getInstance();
String original = "2 years 10 weeks 3 days 6 hours 7 min ago";
// Split on whitespace separators ("\s+" means "one or more whitespace characters"),
// having trimmed whitespace at beginning and end.
String[] split = original.trim().split("\s+");
// Now parse each entry
int num = split.length;
int pos = 0;
while ((num-pos) >= 2) {
if (split[pos].regionMatches(true, 0, "year", 0, 4)) {
cal.add(Calendar.YEAR, -Integer.decode(split[++pos]));
}
else if (split[pos].regionMatches(true, 0, "month", 0, 5)) {
cal.add(Calendar.MONTH, -Integer.decode(split[++pos]));
}
else if (split[pos].regionMatches(true, 0, "week", 0, 4)) {
cal.add(Calendar.WEEK_OF_YEAR, -Integer.decode(split[++pos]));
}
// And so on through the other potential values, note that the last
// number in regionMatches is the number of characters to match.
pos++;
}
The "\s+" may need to become "\s+", see How do I split a string with any whitespace chars as delimiters?.
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