简体   繁体   中英

Get Start day and End day of a Week? [Java]

I am developing an app that constantly monitors the user's physical activity and inactivity levels. I am trying to figure out out to get the starting and ending day of a week when a date is provided. For example, 3 Mar is the date that I am providing and I want to get the starting and ending day of this week -> 27 Feb - 5 Mar. Is it possible to do that?

I am trying to achieve the following design在此处输入图片说明

The following code that I currently have just concatenates the last and first date of the list of activities (one for every day is created).

private String formatDate(List<Activity> activities) {
    Calendar calendar = Calendar.getInstance(Locale.UK);
    Date date = activities.get(activities.size() - 1).getDate();
    calendar.setTime(date);
    String output = "" + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);

    calendar.setTime(activities.get(0).getDate());

    output += " - " + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
    return output;
}

Note: I have to mention that the List as a parameter are all of the activities grouped per week already

However, with this approach it becomes problematic when the person is not using the app (ie not logged in -> the app stops monitoring) and the text label could look something like that在此处输入图片说明 (eg only one activity for this week)

Any advice please?

It is as simple as doing:

calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());

What is considered the first day of the week depends on the Locale used.

To get the last day of the week then do:

calendar.add(Calendar.DAY_OF_YEAR, 6);

You just need to use the Calendar.DAY_OF_WEEK parameter to work out how many days to subtract - for example to print the start and end of the current week:

public static void main(String[] args) {
    Calendar calendar = GregorianCalendar.getInstance();

    // Subtract number of days to start of week
    calendar.add(Calendar.DATE, -(calendar.get(Calendar.DAY_OF_WEEK)-1));

    String output = "" + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
    calendar.add(Calendar.DATE, 6);
    output += " - " + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
    System.out.println(output);
}

java.time

The legacy date-time API ( java.util date-time types and their formatting type, SimpleDateFormat etc.) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time , the modern date-time API * .

Solution using java.time , the modern API:

For ISO 8601 week (Monday to Sunday), you can use ChronoField.DAY_OF_WEEK as 1 for the first day of the week and as 7 for the last day of the week.

import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.ChronoField;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2017, Month.MARCH, 3);

        LocalDate firstDayOfTheWeek = date.with(ChronoField.DAY_OF_WEEK, 1);
        System.out.println(firstDayOfTheWeek); // 2017-02-27

        LocalDate lastDayOfTheWeek = date.with(ChronoField.DAY_OF_WEEK, 7);
        System.out.println(lastDayOfTheWeek); // 2017-03-05
    }
}

Alternatively,

import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.WeekFields;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2017, Month.MARCH, 3);

        LocalDate firstDayOfTheWeek = date.with(WeekFields.ISO.getFirstDayOfWeek());
        System.out.println(firstDayOfTheWeek); // 2017-02-27

        LocalDate lastDayOfTheWeek = firstDayOfTheWeek.plusDays(6);
        System.out.println(lastDayOfTheWeek); // 2017-03-05
    }
}

Use WeekFields#of(Locale locale) to get the Locale -specific result (thanks, Ole VV for the suggestion):

import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.WeekFields;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2017, Month.MARCH, 3);

        System.out.println("France:");
        LocalDate firstDayOfTheWeek = date.with(WeekFields.of(Locale.FRANCE).getFirstDayOfWeek());
        System.out.println(firstDayOfTheWeek);

        LocalDate lastDayOfTheWeek = firstDayOfTheWeek.plusDays(6);
        System.out.println(lastDayOfTheWeek);

        System.out.println();
        System.out.println("USA:");
        firstDayOfTheWeek = date.with(WeekFields.of(Locale.US).getFirstDayOfWeek());
        System.out.println(firstDayOfTheWeek);

        lastDayOfTheWeek = firstDayOfTheWeek.plusDays(6);
        System.out.println(lastDayOfTheWeek);
    }
}

Output:

France:
2017-02-27
2017-03-05

USA:
2017-03-05
2017-03-11

The documentation of WeekFields.ISO.getFirstDayOfWeek() says:

Gets the first day-of-week.

The first day-of-week varies by culture. For example, the US uses Sunday, while France and the ISO-8601 standard use Monday. This method returns the first day using the standard DayOfWeek enum.

Learn more about java.time , the modern date-time API * from Trail: Date Time .


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project .

Thanks to @BarrySW19 and @john16384, here is the working method:

private String formatDate(List<Activity> activities) {
    Calendar calendar = Calendar.getInstance(Locale.UK);
    Date date = activities.get(activities.size() - 1).getDate();
    calendar.setTime(date);
    calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());

    String output = "" + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);

    calendar.add(Calendar.DAY_OF_YEAR, 6);

    output += " - " + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
    return output;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM