0

When I use these codes, I get dates of the month which we are in. For instance, I can see dates between from 01/09/2017 to 21/09/2017.

private void createRandomData(InMemoryCursor cursor) {
List<Object[]> data = new ArrayList<>();
Calendar today = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
today.set(Calendar.HOUR_OF_DAY,0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);

mStart = (Calendar) today.clone();
mStart.set(Calendar.DAY_OF_MONTH, 1);
while (mStart.compareTo(today) <= 0) {
    data.add(createItem(mStart.getTimeInMillis()));
    mStart.add(Calendar.DAY_OF_MONTH, 1);
}
    cursor.addAll(data);
}

However, I need dates of the particular month. How can I see other dates which in other months? For example, I want to see dates of April. It should not be September. (I know it's related to today.clone() but I didn't understand how can I change it).

I plan to separate months with dialog in Android studio and when I select any month, I should see all of dates of month.

I need just dates of a month for doing this, like April. How can I get dates of April? (If I get dates of April, I can do this all of the months)

EDIT Some changing and results:

private void createRandomData(InMemoryCursor cursor) {
List<Object[]> data = new ArrayList<>();
Calendar today = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
today.set(Calendar.HOUR_OF_DAY,0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);

mStart = (Calendar) today.clone();
mStart.set(Calendar.MONTH, Calendar.APRIL);
mStart.set(Calendar.DAY_OF_MONTH, 1);
data.add(createItem(mStart.getTimeInMillis()));
cursor.addAll(data);
}

I get just 01/04/2017

private void createRandomData(InMemoryCursor cursor) {
List<Object[]> data = new ArrayList<>();
Calendar today = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
today.set(Calendar.HOUR_OF_DAY,0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);

mStart = (Calendar) today.clone();
mStart.set(Calendar.MONTH, Calendar.APRIL);
int daysInMonth = today.getActualMaximum(Calendar.DAY_OF_MONTH);
for(int i=0; i<daysInMonth; i++ ){
mStart.set(Calendar.DAY_OF_MONTH, i);}
data.add(createItem(mStart.getTimeInMillis()));
cursor.addAll(data);
}

I get just 29/04/2017 and If I change mStart.set(Calendar.DAY_OF_MONTH, i) to mStart.set(Calendar.DAY_OF_MONTH, 1) result is 01/04/2017

  • Have you tried `mStart.set(Calendar.MONTH, 3)`? Yeah, April is 3 because January is zero in `Calendar` API: https://developer.android.com/reference/java/util/Calendar.html#MONTH –  Sep 21 '17 at 14:16
  • @Hugo Instead of `3`, why not use `Calendar.APRIL`? As in `mStart.set(Calendar.MONTH, Calendar.APRIL)`? That would make it clear what you meant. – Andreas Sep 21 '17 at 14:26
  • @Andreas Indeed, I missed that (I'm using more the new API's and forgetting how to use the old ones). Thanks! –  Sep 21 '17 at 14:30
  • Both of them is the same result. I get just 21/04/2017 for doing today.clone(), how can I fix it? –  Sep 21 '17 at 14:30
  • You should set both the day and the month. In your code above, you're already doing it: `mStart.set(Calendar.DAY_OF_MONTH, 1);` - have you removed this? –  Sep 21 '17 at 14:31
  • When I add it and remove while loop, I get just 01/04/2017. If I don't remove while loop, I get all dates of year. (like, 01/01/2017 to today) (while loop means mStart.compareTo.... ) It might be complicated sorry...know what I mean? –  Sep 21 '17 at 14:38
  • Check @Andreas' answer below. You set the day and month to April 1st before the loop. And inside the loop you add 1 day. if that's not what you want, you can **[edit]** your question and add the code you're trying (it's better to write code there than to describe it in the comments) –  Sep 21 '17 at 14:41
  • What is the point of `for(int i=0; i – Andreas Sep 21 '17 at 20:59

3 Answers3

2

To get all the dates of a particular month, set the Calendar to a date in that month, e.g. the 1th, ask the Calendar for the number of dates in that month, then get the dates.

You could also just get dates until month changes, but code below ask for number of days in the month, to show how you can do that.

This code just prints the dates. You can of course do whatever you want with them instead.

public static void printDatesInMonth(int year, int month) {
    SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
    Calendar cal = Calendar.getInstance();
    cal.clear();
    cal.set(year, month - 1, 1);
    int daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
    for (int i = 0; i < daysInMonth; i++) {
        System.out.println(fmt.format(cal.getTime()));
        cal.add(Calendar.DAY_OF_MONTH, 1);
    }
}

Test

printDatesInMonth(2017, 2);

Output

01/02/2017
02/02/2017
03/02/2017
04/02/2017
05/02/2017
06/02/2017
07/02/2017
08/02/2017
09/02/2017
10/02/2017
11/02/2017
12/02/2017
13/02/2017
14/02/2017
15/02/2017
16/02/2017
17/02/2017
18/02/2017
19/02/2017
20/02/2017
21/02/2017
22/02/2017
23/02/2017
24/02/2017
25/02/2017
26/02/2017
27/02/2017
28/02/2017
Andreas
  • 154,647
  • 11
  • 152
  • 247
0

you are starting with today's date, so assuming you want months starting from there simply use:

cal.add(Calendar.MONTH, 1) to move to next month or

cal.add(Calendar.MONTH, -1) to move to last month.

0

@Andreas's answer provides the way to do it with Calendar. I just like to add another approach.

The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.

In Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need the ThreeTenABP (more on how to use it here).

First you can use a org.threeten.bp.YearMonth to represent the month and year (in this case, April 2017). Then you loop through all the days of this month.

The getTimeInMillis() method takes the number of milliseconds since epoch (1970-01-01T00:00Z), and in your code you're getting it from the date at midnight, in the JVM default timezone.

In ThreeTen Backport, you do this by converting the YearMonth to a org.threeten.bp.LocalDate, then convert it to the JVM default timezone (using a org.threeten.bp.ZoneId), and then using the resulting org.threeten.bp.ZonedDateTime to get the epoch millis value:

// April 2017
YearMonth ym = YearMonth.of(2017, 4);
// get the last day of month
int lastDay = ym.lengthOfMonth();
// loop through the days
for(int day = 1; day <= lastDay; day++) {
    // create the day
    LocalDate dt = ym.atDay(day);
    // set to midnight at JVM default timezone
    ZonedDateTime z = dt.atStartOfDay(ZoneId.systemDefault());
    // get epoch millis value
    data.add(createItem(z.toInstant().toEpochMilli()));
}

If you also need to check if the date is before the current date, you can add an additional check:

....
// today
LocalDate today = LocalDate.now();
// loop through the days
for (int day = 1; day <= lastDay; day++) {
    // create the day
    LocalDate dt = ym.atDay(day);
    if (dt.isBefore(today)) {
        ....

The use of TimeZone.getDefault() and ZoneId.systemDefault(), although might seem a good convenience, is also tricky, because the JVM default timezone can be changed without notice, even at runtime, so it's better to always make it explicit which one you're using.

The API uses IANA timezones names (always in the format Region/City, like America/Sao_Paulo or Europe/Berlin). Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard.

You can get a list of available timezones (and choose the one that fits best your system) by calling ZoneId.getAvailableZoneIds().

Example: to use the New York timezone, you could do:

....
// New York timezone
ZoneId ny = ZoneId.of("America/New_York");
// today in New York timezone
LocalDate today = LocalDate.now(ny);
// loop through the days
for (int day = 1; day <= lastDay; day++) {
    // create the day
    LocalDate dt = ym.atDay(day);
    if (dt.isBefore(today)) {
        // set to midnight at New York timezone
        ZonedDateTime z = dt.atStartOfDay(ny);
        ....

America/New_York is one of the valid names returned by ZoneId.getAvailableZoneIds().


java.util.Calendar

Regarding your code, you're starting with day zero and adding the item to data outside of the loop (so you're just adding the last one - indent your code and you'll see that data.add is outside of the for loop). The code should be like that:

Calendar mStart = (Calendar) today.clone();
// set day to 1
mStart.set(Calendar.DAY_OF_MONTH, 1);
// set month to April
mStart.set(Calendar.MONTH, Calendar.APRIL);
// now mStart is April 1st, we can begin the loop

// get the number of days in April
int daysInMonth = today.getActualMaximum(Calendar.DAY_OF_MONTH);
// loop from day 1 to daysInMonth
for (int i = 1; i <= daysInMonth; i++) {
    // set the day
    mStart.set(Calendar.DAY_OF_MONTH, i);
    // add item for the day
    data.add(createItem(mStart.getTimeInMillis()));
}
// add all items to cursor
cursor.addAll(data);