问题
I am working on an Android app that will display a list of activities. Every activity (i.e. waling, running) has a property Date (i.e. 9 March 8:58 2017). I have two buttons on the screen - Daily and Weekly and I want to switch betweren the two and change the list accordingly. Now, for the Daily list, I don't have to change anything, since a new Activity is created for every day.
However, I am not sure how to go about the Weekly list. It will essentially calculate stats (adding up the statistics for the individual weeks).
For example, I have a list of dates for the last 50 days. How to distinguish an individual list of Dates that would represent an individual week so I can construct a list of Weeks? Basically, convert those 50 dates into their week equivalent (e.g. about 7 weeks)
This is a test list of Dates that I am trying to get working first:
HashMap<Integer,Date> dateHashMap = new HashMap<>();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
List<Date> dates = new ArrayList<>();
dates.add(sdf.parse("10/03/2017"));
dates.add(sdf.parse("9/03/2017"));
dates.add(sdf.parse("8/03/2017"));
dates.add(sdf.parse("7/03/2017"));
dates.add(sdf.parse("6/03/2017"));
dates.add(sdf.parse("23/02/2017"));
dates.add(sdf.parse("3/02/2017"));
dates.add(sdf.parse("2/02/2017"));
dates.add(sdf.parse("1/02/2017"));
for(Date d:dates){
dateHashMap.put(d.getDay(),d);
}
System.out.println(dateHashMap.toString());
An example UI design that I am trying to achieve:
回答1:
As you already have Date property for each activity, then its quite simple actually
First just decide how you want your weeks
ex: I would just go from Mon
to Sun
as one week
So here Week nth
will have dates - 1st to 5th March
and Week nth+1
will have 6th to 12th March
and so on..
and as far as i can understand you already have every activity (i.e. waling, running) with a property Date (i.e. 9 March 8:58 2017)
So taking an example here (let me know if this isn't how you have your data) :waling
- 1 March 2017 8:58 to 9:58
, 3 March 2017 6:20 to 6:50
, 8 March 2017 12:00 to 13:00
running
- 2 March 2017 6:10 to 8:00
, 3 2017 March 7:00 to 8:00
, 9 March 2017 5:50 to 7:00
Now data for Week nth
you can calculate by adding up duration for waling
activity for dates 1st
and 3rd March
as waling
was present only on these dates on Week nth
of March 2017
and similarly for week nth+1
and so on
Same goes for running
activity for week nth
adding up for dates 2nd March
, 3rd March
and similarly for week nth+1
and so on..
Now you will have something like :
Week nth :
- Wailing - 1 hr and 30 min
- Running - 2 hrs and 50 min
Week nth+1 :
- Wailing - 1 hr
- Running - 1 hr and 10 min
And on clicking of each activity you can show some more details..
Hope this helps :)
Edit :
Considering this is how you have your dates list
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
List<Date> dates = new ArrayList<>();
try {
dates.add(sdf.parse("10/03/2017"));
dates.add(sdf.parse("9/03/2017"));
dates.add(sdf.parse("8/03/2017"));
dates.add(sdf.parse("7/03/2017"));
dates.add(sdf.parse("6/03/2017"));
dates.add(sdf.parse("23/02/2017"));
dates.add(sdf.parse("3/02/2017"));
dates.add(sdf.parse("2/02/2017"));
dates.add(sdf.parse("1/02/2017"));
} catch (ParseException e) {
e.printStackTrace();
}
You can create a custom List
just to identify the dates that falls in the same week
ex (I just used what @Jameson suggested in his answer, you can always write this a lot better):
public List<WeekDay> getListOfWeeksFromListOfDates(List<Date> listOfDates) {
List<WeekDay> listOfWeeks = new ArrayList<>();
WeekDay weekDay;
for (Date date : listOfDates) {
weekDay = new WeekDay(date, new SimpleDateFormat("w").format(date));
listOfWeeks.add(weekDay);
}
return listOfWeeks;
}
public class WeekDay {
Date date;
String weekIdentifier;
public WeekDay(Date Date, String WeekIdentifier) {
this.date = Date;
this.weekIdentifier = WeekIdentifier;
}
public Date getDate() {
return date;
}
public String getWeekIdentifier() {
return weekIdentifier;
}
}
And you can use getListOfWeeksFromListOfDates(dates);
to have a list with Dates
and Week
number, this week
number can serve as an identifier to compare the dates and then you can add the activities for dates with same Week
number..
Hope you are getting what i am trying to convey here :)
回答2:
/**
* Gets a list of week numbers (as strings) from a list of dates.
*
* @param listOfDates the list of dates
* @return a list of week in year (as string), corresponding
* one-to-one to the values in the input list.
*/
public List<String> getListOfWeeksFromListOfDates(List<Date> listOfDates) {
List<String> listOfWeeks = new ArrayList<>();
for (Date date : listOfDates) {
listOfWeeks.add(new SimpleDateFormat("w").format(date));
}
return listOfWeeks;
}
回答3:
Week?
You have not defined what you mean by week.
- Do you mean the standard ISO 8601 week where each week starts on a Monday and week # 1 contains the first Thursday, each week numbered 1-52 or 53?
- Or do you mean a United States type week beginning on a Sunday with weeks numbered 1-52/53 starting with January 1, and if so are the last days of the previous week in the previous year or the new year?
- Or do you mean something else?
Time zone?
What time zone do want to use as the context for determining the date? Or do you want to keep your date-times in UTC like Stack Overflow does in tracking your activity for “today” vs “yesterday”?
Avoid legacy date-time classes
The troublesome old date classes including Date
and Calendar
should be avoided whenever possible. They are now supplanted by the java.time classes.
Convert your given Date
objects to Instant
, a moment on the timeline in UTC.
Instant instant = myDate.toInstant();
ISO 8601
I suggest using the standard week whenever possible.
Adjust your Instant
into the desired time zone.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Retrieve the standard week number.
int weekNumber = zdt.get( WeekFields.ISO.weekOfWeekBasedYear() );
Keep in mind that the year number to go with this week number is not the calendar year. We want the year of the week-based year. For example, in some years, December 30 and 31 can belong to the following year number of a week-based year.
int yearOfWeekBasedYear = zdt.get( WeekFields.ISO.weekBasedYear() );
You could track your records against a string composed of this yearOfWeekBasedYear
and weekNumber
. Use standard format, yyyy-Www such as 2017-W07
.
ThreeTen-Extra YearWeek
Instead I suggest you use meaningful objects rather than mere strings. Add the ThreeTen-Extra library to your project to gain the YearWeek
class.
This code replaces the WeekFields
code we did above.
YearWeek yw = YearWeek.from( zdt );
回答4:
Thanks to @shadygoneinsane and @ Basil Bourque for pointing me to the right direction I solved the problem the following way:
TreeMap<Integer, List<Date>> dateHashMap = new TreeMap<>();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
List<Date> dates = new ArrayList<>();
dates.add(sdf.parse("10/03/2017"));
dates.add(sdf.parse("9/03/2017"));
dates.add(sdf.parse("8/03/2017"));
dates.add(sdf.parse("7/03/2017"));
dates.add(sdf.parse("6/03/2017"));
dates.add(sdf.parse("23/02/2017"));
dates.add(sdf.parse("3/02/2017"));
dates.add(sdf.parse("2/02/2017"));
dates.add(sdf.parse("1/02/2017"));
for (int i = 0; i < dates.size(); i++) {
List<Date> datesList = new ArrayList<>();
Calendar calendar = Calendar.getInstance();
calendar.setTime(dates.get(i));
int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
for (Date date : dates) {
Calendar c = Calendar.getInstance();
c.setTime(date);
if (weekOfMonth == c.get(Calendar.WEEK_OF_MONTH)) {
datesList.add(date);
}
}
dateHashMap.put(weekOfMonth, datesList);
}
System.out.println(dateHashMap.toString());
}
And the result:
Output:
1=[Fri Feb 03 00:00:00 GMT 2017,
Thu Feb 02 00:00:00 GMT 2017,
Wed Feb 01 00:00:00 GMT 2017],
2=[Fri Mar 10 00:00:00 GMT 2017,
Thu Mar 09 00:00:00 GMT 2017,
Wed Mar 08 00:00:00 GMT 2017,
Tue Mar 07 00:00:00 GMT 2017,
Mon Mar 06 00:00:00 GMT 2017],
4=[Thu Feb 23 00:00:00 GMT 2017]
Exactly what I needed! So now I can iterate through each week and sum up the statistics and thus formulate the "Weekly" view of the list
来源:https://stackoverflow.com/questions/42690985/how-to-group-list-of-dates-to-corresponding-week-in-java