获取一周的开始日和结束日? [Java]

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

我正在开发一款持续监控用户体力 activity 和 activity 水平的应用程序。我想弄清楚在提供日期时获得一周的开始和结束日期。例如,3 月 3 日是我提供的日期,我想获得本周的开始和结束日期 -> 2 月 27 日 - 3 月 5 日。是否可以这样做?

我正在尝试实现以下设计

我目前拥有的以下代码只是连接了活动列表的最后一个日期和第一个日期(每天创建一个)。

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;
}

注意:我必须提到作为参数的列表是每周分组的所有活动

但是,使用这种方法,当用户不使用该应用程序(即未登录 -> 应用程序停止监控)并且文本标签可能看起来像这样时,就会出现问题 (例如,本周只有一个 activity)

有什么建议吗?

就这么简单:

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

一周的第一天取决于所使用的Locale

要获取一周的最后一天,请执行以下操作:

calendar.add(Calendar.DAY_OF_YEAR, 6);

您只需使用 Calendar.DAY_OF_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);
}

感谢@BarrySW19 和@john16384,这是工作方法:

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;
}

java.time

旧版日期时间 API(java.util 日期时间类型及其格式类型,SimpleDateFormat 等)已过时且容易出错。建议完全停止使用,改用java.timemodern date-time API*.

解决方案使用java.time,现代API:

对于 ISO 8601 周(周一至周日),您可以使用 ChronoField.DAY_OF_WEEK 作为一周的第一天作为 1,作为一周的最后一天作为 7。

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
    }
}

或者,

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
    }
}

使用 WeekFields#of(Locale locale) 获得 Locale 特定结果(感谢 Ole V.V 的建议):

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);
    }
}

输出:

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

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

WeekFields.ISO.getFirstDayOfWeek() 的文档说:

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.

了解更多关于 java.timemodern date-time API* 来自 Trail: Date Time.


* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用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