Reputation: 387
I am using following code to get the last 7 days:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ");
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
String[] days = new String[6];
days[0] = sdf.format(date);
for(int i = 1; i < 6; i++){
cal.add(Calendar.DAY_OF_MONTH, -1);
date = cal.getTime();
days[i] = sdf.format(date);
}
for(String x: days){
System.out.println(x);
}
And this is giving the following output:
2016-04-14
2016-04-13
2016-04-12
2016-04-11
2016-04-10
2016-04-09
But I want this instead:
2016-04-09
2016-04-10
2016-04-11
2016-04-12
2016-04-13
2016-04-14
If I use the following line below the code it will give me the correct order:
List<String> list = Arrays.asList(days);
Collections.reverse(list);
days = (String[]) list.toArray();
for(String x: days){
System.out.println(x);
}
But is there any other way to get the last 7 days in ascending order in one shot?
Upvotes: 11
Views: 14052
Reputation: 23047
Here's my two cents, using Streams:
LocalDate start = LocalDate.now().minusDays(6);
Stream.iterate(start, date -> date.plusDays(1))
.limit(7)
.toList();
As Ole V.V. mentioned in the comments, since Java 9, they've added a convenience method to get a stream of dates: LocalDate::datesUntil
.
It then would look like something like this:
LocalDate now = LocalDate.now();
now.minusDays(6).datesUntil(now.plusDays(1))
.toList();
Because you want the end date to be today, we need to provide now.plusDays(1)
as argument to datesUntil
. That is because the given date is exclusive.
Upvotes: 2
Reputation: 340098
The other answers use old outmoded classes or are overly complicated.
The old date-time classes have been supplanted by the java.time framework built into Java 8 and later, with back-ports to Java 6 & 7 and to Android. The old classes have proven to be poorly designed, confusing, and troublesome. Avoid them.
LocalDate
Among the new classes is LocalDate
to represent a date-only value without time-of-day and without time zone. While not stored, a time zone is required to determine “today”. A new dawns earlier in the east, so the date can vary between time zones, “tomorrow” in Paris while “yesterday” in Montréal.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
You can add and subtract. We want to go back a week, so subtract a week.
LocalDate limit = today.minusWeeks( 1 );
Loop a day at a time until we reach the limit. Collect each date as we increment.
A List
is an ordered collection, a sequence. The ArrayList
class is an appropriate implementation for our needs.
List< LocalDate > list = new ArrayList<>();
Loop while each decremented date is still later than our stopping point (a week ago).
LocalDate localDate = today;
while ( localDate.isAfter( limit ) ) {
list.add( localDate );
// Setup next loop.
localDate = localDate.minusDays( 1 );
}
Lastly, sort your list in either direction you desire.
The Collections
class (note the plural 's' in name) provides many utility methods. Call sort
for natural order. Call reverse
for the opposite of natural order.
Collections.sort( list );
Collections.reverse( list );
Upvotes: 1
Reputation: 1287
Collections.sort
You can use Collections.sort
method. It's a static method. You pass it the list and a comparator. It uses a modified mergesort algorithm over the list. That's why you must pass it a comparator to do the pair comparisons. This has been answered before as well.
Sort objects in ArrayList by date?
Upvotes: 1
Reputation: 27003
I would simplify your method a bit, if you want this output you don't need to create an String[]
array, either loop twice, you can achieve same with a single for-loop
, one Calendar
and the SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ");
Calendar cal = Calendar.getInstance();
// get starting date
cal.add(Calendar.DAY_OF_YEAR, -6);
// loop adding one day in each iteration
for(int i = 0; i< 6; i++){
cal.add(Calendar.DAY_OF_YEAR, 1);
System.out.println(sdf.format(cal.getTime()));
}
OUTPUT:
2016-04-09
2016-04-10
2016-04-11
2016-04-12
2016-04-13
2016-04-14
Upvotes: 14
Reputation: 4623
If the numbers of days is constant you can simply start filling the array from the end (Of course after allocating the table: new String[DAYS]
):
private static final DAYS = 6;
//...
for(int i = DAYS; i >= 0; i--){
cal.add(Calendar.DAY_OF_MONTH,-1);
date = cal.getTime();
days[i] = sdf.format(date);
}
Upvotes: 0
Reputation: 1533
Using java8 and joda you can write something like:
LocalDate weekBeforeToday = LocalDate.now().minusDays(7);
IntStream.rangeClosed(1, 7)
.mapToObj(weekBeforeToday::plusDays)
.forEach(System.out::println);
It prints:
2016-04-08
2016-04-09
2016-04-10
2016-04-11
2016-04-12
2016-04-13
2016-04-14
If you need collection you have to use collector.
In your example you're printing 6 days so I don't now if it's your mistake or you need 6 days instead of 7.
Upvotes: 6
Reputation: 3090
Just loop the other way:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ");
Calendar cal = Calendar.getInstance();
Date date=cal.getTime();
String[] days = new String[6];
days[0]=sdf.format(date);
for(int i = 1; i< 6; i++){
cal.add(Calendar.DAY_OF_MONTH,-1);
date=cal.getTime();
days[i]=sdf.format(date);
}
for(int i = (days.length-1); i >= 0; i--){
System.out.println(days[i]);
}
This is the output:
2016-04-09
2016-04-10
2016-04-11
2016-04-12
2016-04-13
2016-04-14
Upvotes: 2
Reputation: 9336
Instead of a loop going forward, you can try to use a loop going backwards. Replace the following two lines of your code:
days[0] = sdf.format(date);
for(int i = 1; i < 6; i++){
with:
days[days.length - 1] = sdf.format(date);
for(int i = days.length - 2; i >= 0; i--){
OUTPUT:
2016-04-14
2016-04-13
2016-04-12
2016-04-11
2016-04-10
2016-04-09
EDIT: Better yet, use Jordi Castilla's solution.
Upvotes: 0
Reputation: 328863
Here is a suggestion:
String[] days = new String[6];
for (int i = 0; i < days.length; i++) {
days[i] = LocalDate.now().minusDays(days.length - i - 1).toString();
}
for (String x : days) {
System.out.println(x);
}
And possibly even clearer, using a list:
List<String> days = new ArrayList<> ();
LocalDate now = LocalDate.now();
for (LocalDate d = now.minusDays(5); !d.isAfter(now); d = d.plusDays(1)) {
days.add(d.toString());
}
for (String x : days) {
System.out.println(x);
}
Upvotes: 2
Reputation: 4228
Try this :
Change days
to an array of Date
and then convert it to list and sort the list with Collections.sort(list);
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ");
Calendar cal = Calendar.getInstance();
Date date=cal.getTime();
Date[] days = new Date[6];
days[0]= date;
for(int i = 1; i< 6; i++){
cal.add(Calendar.DAY_OF_MONTH,-1);
date=cal.getTime();
days[i]=date;
}
List<Date> list = Arrays.asList(days);
Collections.sort(list);
for(Date x: days){
System.out.println(sdf.format(x));
}
}
Upvotes: 0