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