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 (i.e. not logged in -> the app stops monitoring) and the text label could look something like that
(e.g. 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);
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 V.V. 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.
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);
}
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;
}
I want to compare two dates to categories Browser History...
I have seen too many posts but didn't get any helpful,
My code is as :
private static String calculateDate()
{
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR, -10);
return simpleDateFormat.format(new Date(calendar.getTimeInMillis()));
}
private static String today()
{
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR,0);
return simpleDateFormat.format(new Date(calendar.getTimeInMillis()));
}
public void getBHistory()
{
long startdates = 0;
long enddates = 0;
Date endDate = null;
Date startDate=null;
try
{
startDate = (Date)new SimpleDateFormat("yyyy-MM-dd")
.parse(calculateDate());
endDate = (Date)new SimpleDateFormat("yyyy-MM-dd")
.parse(today());
startdates = startDate.getTime();
enddates = endDate.getTime();
} catch (ParseException e)
{
e.printStackTrace();
}
// 0 = history, 1 = bookmark
String sel = Browser.BookmarkColumns.BOOKMARK + " = 0" + " AND "
+ Browser.BookmarkColumns.DATE + " BETWEEN ? AND ?";
Cursor mCur = m_oContext.getContentResolver().query(Browser.BOOKMARKS_URI, Browser.HISTORY_PROJECTION, sel,
new String[]{
"" + startdates, "" + enddates
}, null);
mCur.moveToFirst();
String title = "";
String date_time = "";
if (mCur.moveToFirst() && mCur.getCount() > 0)
{
while (!mCur.isAfterLast())
{
title = mCur.getString(mCur
.getColumnIndex(Browser.BookmarkColumns.TITLE));
date_time = mCur.getString(mCur
.getColumnIndex(Browser.BookmarkColumns.DATE));
SimpleDateFormat simpleDate= new SimpleDateFormat("yyyy-MM-dd");
String curDate=simpleDate.format(new Date(Long.parseLong(date_time)));
Toast.makeText(m_oContext,"History Time : "+curDate,Toast.LENGTH_SHORT).show();
Toast.makeText(m_oContext,"Limit Time : "+calculateDate(),Toast.LENGTH_SHORT).show();
//TODO: Compare these two dates here
mCur.moveToNext();
}
}
}
I want to do if the History date is earlier than ten days ago then notify the user.
Any kind of help will be appreciated ,thank you.
tl;dr
Boolean alertUser =
LocalDate.parse( "2016-01-02" )
.isBefore(
LocalDate.now( ZoneId.of( “America/Montreal” ) )
.minusDays( 10 )
) ;
java.time
You are using troublesome old date-time classes now supplanted by the java.time classes.
Time zone
Your code ignores the crucial issue of time zone in determining a date such as “today”.
Example code
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
ZoneId z = ZoneId.of( “America/Montreal” );
LocalDate today = LocalDate.now( z );
Your input strings are in standard ISO 8601 format. The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern.
LocalDate target = LocalDate.parse( "2016-01-02" );
You say the boundary is ten days ago. Use the plus or minus methods to determine future/past dates.
LocalDate tenDaysAgo = today.minusDays( 10 );
Compare using compareTo, equals, isBefore, and isAfter methods.
Boolean alertUser = target.isBefore( tenDaysAgo );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Calendar is comparable so you can just use compare to. I would make curDate a calendar. Then (curDate.compareTo(calculatedDate) < 0) will be true if curDate is earlier than calculatedDate which you've set to ten days before today.
You can use
before()
Or
after()
to compare your calculated date with today's date
public boolean isHDateEarlier(String historyDate){
String[] historySplitStrings= historyDate.split("-");
String[] tenDaysEarlierStrings = calculateDate().split("-");
int historyYear = Integer.parseInt(historySplitStrings[0]);
int daysYear = Integer.parseInt(tenDaysEarlierStrings [0]);
int historyMonth = Integer.parseInt(historySplitStrings[1]);
int daysMonth = Integer.parseInt(tenDaysEarlierStrings [1]);
int historyDay = Integer.parseInt(historySplitStrings[2]);
int daysDay = Integer.parseInt(tenDaysEarlierStrings [2]);
if(historyYear < daysYear ){//check year
return true;
}
if(historyMonth < daysMonth &&
historyYear <= daysYear ){//check month
return true;
}
if(historyDay < daysDay &&
historyYear <= daysYear &&
historyMonth <= daysMonth){//check day
return true;
}
return false;
}
Just call :
isHDateEarlier(curDate);
I had a problem with comparing dates a week ago, and searched for answers and this helped me: Find nearest date from a list. - The last answer talks about NavigableSet<>
Try using NavigableSet<Date> such as TreeSet<> and put your dates in the list.
Than compare with lower or higher
Is there any direct way to set a date to a variable but as an input?
I mean that i don't know the date at design time, the user should give it.
I tried the following code but it doesn't work:
Calendar myDate=new GregorianCalendar(int year, int month , int day);
Try the following code. I am parsing the entered String to make a Date
// To take the input
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the Date ");
String date = scanner.next();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
Date date2=null;
try {
//Parsing the String
date2 = dateFormat.parse(date);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(date2);
tl;dr
LocalDate.of( 2026 , 1 , 23 ) // Pass: ( year , month , day )
java.time
Some other Answers are correct in showing how to gather input from the user, but use the troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
LocalDate
For a date-only value without time-of-day and without time zone, use the LocalDate class.
LocalDate ld = LocalDate.of( 2026 , 1 , 23 );
Parse your input strings as integers as discussed here: How do I convert a String to an int in Java?
int y = Integer.parseInt( yearInput );
int m = Integer.parseInt( monthInput ); // 1-12 for January-December.
int d = Integer.parseInt( dayInput );
LocalDate ld = LocalDate.of( y , m , d );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Maybe you can try my simple code below :
SimpleDateFormat dateInput = new SimpleDateFormat("yyyy-MM-dd");
Scanner input = new Scanner(System.in);
String strDate = input.nextLine();
try
{
Date date = dateInput.parse(strDate);
System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(date));
}
catch (ParseException e)
{
System.out.println("Parce Exception");
}
java.time
I recommend that you use java.time, the modern Java date and time API, for your date work. The Date and SimpleDateFormat classes used in most of the other answers are poorly designed and long outdated. Don’t use them.
I further suggest that the user wants to enter the date in a short format specific to his or her locale. For this purpose I first declare a few constants:
private static final Locale defaultFormattingLocale
= Locale.getDefault(Locale.Category.FORMAT);
private static final String defaultDateFormat = DateTimeFormatterBuilder
.getLocalizedDateTimePattern(FormatStyle.SHORT, null,
IsoChronology.INSTANCE, defaultFormattingLocale);
private static final DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern(defaultDateFormat, defaultFormattingLocale);
Now prompting for and reading the date goes like this:
Scanner inputScanner = new Scanner(System.in);
LocalDate sampleDate
= Year.now().minusYears(1).atMonth(Month.NOVEMBER).atDay(26);
System.out.println("Enter date in " + defaultDateFormat
+ " format, for example " + sampleDate.format(dateFormatter));
String dateString = inputScanner.nextLine();
try {
LocalDate inputDate = LocalDate.parse(dateString, dateFormatter);
System.out.println("Date entered was " + inputDate);
} catch (DateTimeParseException dtpe) {
System.out.println("Invalid date: " + dateString);
}
Sample session in US locale:
Enter date in M/d/yy format, for example 11/26/20
2/9/21
Date entered was 2021-02-09
Sample session in Danish locale:
Enter date in dd/MM/y format, for example 26/11/2020
9/februar/2021
Invalid date: 9/februar/2021
In the last case you will probably want to allow the user to try again. I am leaving that to you.
Link
Oracle tutorial: Date Time explaining how to use java.time.
Check this out:)
ZoneId defaultZoneId = ZoneId.systemDefault();
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the DOB: ");
String dobString = scanner.nextLine();
LocalDate dobLocal = LocalDate.parse(dobString);
Date dob = Date.from(dobLocal.atStartOfDay(defaultZoneId).toInstant());
System.out.println(dob);
Simple project GitHub Repo: https://github.com/lojithv/Java-Enter-Student-Details.git
You should enter dob like this : yyyy-mm-dd
Done:)
I have modified #SK08 answer and created a method which takes year, month and date as input from the user and returns date.
Scanner scanner = new Scanner(System.in);
String str[] = {"year", "month", "day" };
String date = "";
for(int i=0; i<3; i++) {
System.out.println("Enter " + str[i] + ": ");
date = date + scanner.next() + "/";
}
date = date.substring(0, date.length()-1);
System.out.println("date: "+ date);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
Date parsedDate = null;
try {
parsedDate = dateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return parsedDate;
This is a repost of a comment. I give Arvind Kumar Avinash full credit. #arvindkumaravinash
"Nice! For future visitors: In the code given above, the Locale used with dateFormatter doesn't necessarily have to be the same one as used to obtain defaultDateFormat. For example,
String format = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRANCE);
LocalDate now = LocalDate.now();
System.out.println(
now.format(DateTimeFormatter.ofPattern(format, Locale.ENGLISH)));
System.out.println(
now.format(DateTimeFormatter.ofPattern(format, Locale.FRANCE)));
"
For Americans, be sure to replace FRANCE with US, the British use UK, and so on. here is a list of currently used countries.
https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html
Also be sure to import all packages necessary separately, because time* will not work for this. So these essentially
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
import java.time.format.FormatStyle;
import java.time.chrono.IsoChronology;
This should work fine and you can validate the date as well using setlenient function-
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;
public class Datinput {
public static void main(String args[]) {
int n;
ArrayList<String> al = new ArrayList<String>();
Scanner in = new Scanner(System.in);
n = in.nextInt();
String da[] = new String[n];
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setLenient(false);
Date date[] = new Date[n];
in.nextLine();
for (int i = 0; i < da.length; i++) {
da[i] = in.nextLine();
}
for (int i = 0; i < da.length; i++) {
try {
date[i] = sdf.parse(da[i]);
} catch (ParseException e) {
e.printStackTrace();
}
}
in.close();
}
}
This is working I tried!
package javaapplication2;
//#author Ibrahim Yesilay
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class JavaApplication2 {
public static void main(String[] args) throws ParseException {
Scanner giris = new Scanner(System.in);
System.out.println("gün:");
int d = giris.nextInt();
System.out.println("ay:");
int m = giris.nextInt();
System.out.println("yil:");
int y = giris.nextInt();
String tarih;
tarih = Integer.toString(d) + "/" + Integer.toString(m) + "/" + Integer.toString(y);
System.out.println("Tarih : " + tarih);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date girilentarih = null;
girilentarih = dateFormat.parse(tarih);
System.out.println(dateFormat.format(girilentarih));
}
}
I recently came across a task where i have to get all Fridays in a date range. I wrote a small piece of code and was surprised see some strange behaviour.
Below is my code:
public class Friday {
public static void main(String[]args){
String start = "01/01/2009";
String end = "12/09/2013";
String[] startTokens = start.split("/");
String[] endTokens = end.split("/");
Calendar startCal = new GregorianCalendar(Integer.parseInt(startTokens[2]),Integer.parseInt(startTokens[1])-1,Integer.parseInt(startTokens[0]));
Calendar endCal = new GregorianCalendar(Integer.parseInt(endTokens[2]),Integer.parseInt(endTokens[1])-1, Integer.parseInt(endTokens[0]));
int startYear = Integer.parseInt(startTokens[2]);
int endYear = Integer.parseInt(endTokens[2]);
int startWeek = startCal.get(Calendar.WEEK_OF_YEAR);
int endWeek = endCal.get(Calendar.WEEK_OF_YEAR);
Calendar cal = new GregorianCalendar();
cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
// cal.setMinimalDaysInFirstWeek(7);
ArrayList<String> main = new ArrayList<String>();
while(startYear <= endYear ){
cal.set(Calendar.YEAR, startYear);
System.out.println(cal.getMinimalDaysInFirstWeek());
if(startYear == endYear){
main.addAll(getFridays(startWeek, endWeek, cal));
}
else{
main.addAll(getFridays(startWeek, 52, cal));
startWeek = 1;
}
startYear =startYear +1;
}
for(String s: main){
System.err.println(s);
}
}
public static ArrayList<String> getFridays(int startWeek, int endWeek, Calendar cal){
ArrayList<String> fridays = new ArrayList<String>();
while(startWeek <= endWeek){
cal.set(Calendar.WEEK_OF_YEAR, startWeek);
fridays.add(cal.getTime().toString());
startWeek = startWeek+1;
}
return fridays;
}
}
Now when I ran the code i noticed that Fridays of 2011 are missing. After some debugging and online browsing i figured that Calendar.WEEK_OF_YEAR is locale specific and I have to use setMinimalDaysInFirstWeek(7) to fix it.
So uncommented the related line in the above code.
From what I understood now first week of year should start from full week of year.
For example Jan 1 2010 is friday. But it should not show up in results as i configured it to treat that week begins from Jan 3rd. But Now i still see the Jan 1 as friday
I am very much confused. Can some one explain why it is happening?
These Stackoverflow articles helped me a bit:
Why dec 31 2010 returns 1 as week of year?
Understanding java.util.Calendar WEEK_OF_YEAR
Here is an easier method, using the wonderful http://www.joda.org/joda-time/ library:
String start = "01/01/2009";
String end = "12/09/2013";
DateTimeFormatter pattern = DateTimeFormat.forPattern("dd/MM/yyyy");
DateTime startDate = pattern.parseDateTime(start);
DateTime endDate = pattern.parseDateTime(end);
List<DateTime> fridays = new ArrayList<>();
while (startDate.isBefore(endDate)){
if ( startDate.getDayOfWeek() == DateTimeConstants.FRIDAY ){
fridays.add(startDate);
}
startDate = startDate.plusDays(1);
}
at the end of this, you'd have the fridays in the fridays array. Simple?
Or if you want to speed things up, once you have gotten a friday, you can switch from using days, to using weeks:
String start = "01/01/2009";
String end = "12/09/2013";
DateTimeFormatter pattern = DateTimeFormat.forPattern("dd/MM/yyyy");
DateTime startDate = pattern.parseDateTime(start);
DateTime endDate = pattern.parseDateTime(end);
List<DateTime> fridays = new ArrayList<>();
boolean reachedAFriday = false;
while (startDate.isBefore(endDate)){
if ( startDate.getDayOfWeek() == DateTimeConstants.FRIDAY ){
fridays.add(startDate);
reachedAFriday = true;
}
if ( reachedAFriday ){
startDate = startDate.plusWeeks(1);
} else {
startDate = startDate.plusDays(1);
}
}
First off, I would not bother with weeks. Set the Calendar to the beginning of the range, and figure out which DOW it is, then increment to get to the next Friday, then simply loop adding 7 days until you are at the end of the range.
Actually, since you are always only going forward, should be something like:
int daysToAdd = FridayDOW - currentDOW;
if (daysToAdd < 0) daysToAdd += 7;
Date startDate = currentDate.add(Calendar.DAYS, daysToAdd);
Yeah, like that.
Ok, actually, for kicks, here it is in Java 8:
#Test
public void canFindAllFridaysInRange(){
start = LocalDate.of(2013, 5, 10);
end = LocalDate.of(2013, 8,30);
DayOfWeek dowOfStart = start.getDayOfWeek();
int difference = DayOfWeek.FRIDAY.getValue() - dowOfStart.getValue();
if (difference < 0) difference += 7;
List<LocalDate> fridaysInRange = new ArrayList<LocalDate>();
LocalDate currentFriday = start.plusDays(difference);
do {
fridaysInRange.add(currentFriday);
currentFriday = currentFriday.plusDays(7);
} while (currentFriday.isBefore(end));
System.out.println("Fridays in range: " + fridaysInRange);
}
Got to love the new date classes!! Of course a lambda would condense this further.
tl;dr
someLocalDate.with( // Date-only value without time-of-day and without time zone, represented by `LocalDate` class.
TemporalAdjusters.nextOrSame ( DayOfWeek.FRIDAY ) ) // Moving from one `LocalDate` object to another, to find the next Friday unless the starting date is already a Friday.
) // Return a `LocalDate` object.
java.time
The other Answers are outdated. The old java.util.Date/.Calendar classes have been supplanted in Java 8 and later by the new java.time framework. Joda-Time library is excellent, continues to be maintained, and even inspired java.time. But the Joda-Time team recommends moving on to java.time as soon as is convenient.
LocalDate
The java.time classes include LocalDate for a date-only value without time-of-day nor time zone. See Tutorial.
First parse your input strings to get LocalDate objects.
String inputStart = "01/01/2009";
String inputStop = "12/09/2013"; // 258 Fridays.
// String inputStop = "01/01/2009"; // 0 Friday.
// String inputStop = "01/02/2009"; // 1 Friday.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "MM/dd/yyyy" );
LocalDate start = LocalDate.parse ( inputStart , formatter );
LocalDate stop = LocalDate.parse ( inputStop , formatter );
In your own code, try-catch for exception in case of bad inputs. And verify that stop is indeed the same or later than start.
TemporalAdjusters
The java.time framework includes the TemporalAdjuster interface as a way of shifting date-time values. For example, getting the next or same Friday for any particular date. On your starting date, call with(TemporalAdjuster adjuster) and pass a pre-defined implementation of a TemporalAdjuster from the class TemporalAdjusters (note the plural s). See Tutorial.
List<LocalDate> fridays = new ArrayList<> (); // Collect each Friday found.
LocalDate nextOrSameFriday = start.with ( TemporalAdjusters.nextOrSame ( DayOfWeek.FRIDAY ) );
// Loop while we have a friday in hand (non-null) AND that friday is not after our stop date (isBefore or isEqual the stop date).
while ( ( null != nextOrSameFriday ) & ( ! nextOrSameFriday.isAfter ( stop ) ) ) {
fridays.add ( nextOrSameFriday ); // Remember this friday.
nextOrSameFriday = nextOrSameFriday.plusWeeks ( 1 ); // Move to the next Friday, setting up for next iteration of this loop.
}
Dump to console.
System.out.println ( "From: " + start + " to: " + stop + " are " + fridays.size () + " Fridays: " + fridays );
From: 2009-01-01 to: 2013-12-09 are 258 Fridays: [2009-01-02, 2009-01-09, 2009-01-16, 2009-01-23, 2009-01-30, 2009-02-06, 2009-02-13, 2009-02-20, 2009-02-27, 2009-03-06, 2009-03-13, 2009-03-20, 2009-03-27, 2009-04-03, 2009-04-10, 2009-04-17, 2009-04-24, 2009-05-01, 2009-05-08, 2009-05-15, 2009-05-22, 2009-05-29, 2009-06-05, 2009-06-12, 2009-06-19, 2009-06-26, 2009-07-03, 2009-07-10, 2009-07-17, 2009-07-24, 2009-07-31, 2009-08-07, 2009-08-14, 2009-08-21, 2009-08-28, 2009-09-04, 2009-09-11, 2009-09-18, 2009-09-25, 2009-10-02, 2009-10-09, 2009-10-16, 2009-10-23, 2009-10-30, 2009-11-06, 2009-11-13, 2009-11-20, 2009-11-27, 2009-12-04, 2009-12-11, 2009-12-18, 2009-12-25, 2010-01-01, 2010-01-08, 2010-01-15, 2010-01-22, 2010-01-29, 2010-02-05, 2010-02-12, 2010-02-19, 2010-02-26, 2010-03-05, 2010-03-12, 2010-03-19, 2010-03-26, 2010-04-02, 2010-04-09, 2010-04-16, 2010-04-23, 2010-04-30, 2010-05-07, 2010-05-14, 2010-05-21, 2010-05-28, 2010-06-04, 2010-06-11, 2010-06-18, 2010-06-25, 2010-07-02, 2010-07-09, 2010-07-16, 2010-07-23, 2010-07-30, 2010-08-06, 2010-08-13, 2010-08-20, 2010-08-27, 2010-09-03, 2010-09-10, 2010-09-17, 2010-09-24, 2010-10-01, 2010-10-08, 2010-10-15, 2010-10-22, 2010-10-29, 2010-11-05, 2010-11-12, 2010-11-19, 2010-11-26, 2010-12-03, 2010-12-10, 2010-12-17, 2010-12-24, 2010-12-31, 2011-01-07, 2011-01-14, 2011-01-21, 2011-01-28, 2011-02-04, 2011-02-11, 2011-02-18, 2011-02-25, 2011-03-04, 2011-03-11, 2011-03-18, 2011-03-25, 2011-04-01, 2011-04-08, 2011-04-15, 2011-04-22, 2011-04-29, 2011-05-06, 2011-05-13, 2011-05-20, 2011-05-27, 2011-06-03, 2011-06-10, 2011-06-17, 2011-06-24, 2011-07-01, 2011-07-08, 2011-07-15, 2011-07-22, 2011-07-29, 2011-08-05, 2011-08-12, 2011-08-19, 2011-08-26, 2011-09-02, 2011-09-09, 2011-09-16, 2011-09-23, 2011-09-30, 2011-10-07, 2011-10-14, 2011-10-21, 2011-10-28, 2011-11-04, 2011-11-11, 2011-11-18, 2011-11-25, 2011-12-02, 2011-12-09, 2011-12-16, 2011-12-23, 2011-12-30, 2012-01-06, 2012-01-13, 2012-01-20, 2012-01-27, 2012-02-03, 2012-02-10, 2012-02-17, 2012-02-24, 2012-03-02, 2012-03-09, 2012-03-16, 2012-03-23, 2012-03-30, 2012-04-06, 2012-04-13, 2012-04-20, 2012-04-27, 2012-05-04, 2012-05-11, 2012-05-18, 2012-05-25, 2012-06-01, 2012-06-08, 2012-06-15, 2012-06-22, 2012-06-29, 2012-07-06, 2012-07-13, 2012-07-20, 2012-07-27, 2012-08-03, 2012-08-10, 2012-08-17, 2012-08-24, 2012-08-31, 2012-09-07, 2012-09-14, 2012-09-21, 2012-09-28, 2012-10-05, 2012-10-12, 2012-10-19, 2012-10-26, 2012-11-02, 2012-11-09, 2012-11-16, 2012-11-23, 2012-11-30, 2012-12-07, 2012-12-14, 2012-12-21, 2012-12-28, 2013-01-04, 2013-01-11, 2013-01-18, 2013-01-25, 2013-02-01, 2013-02-08, 2013-02-15, 2013-02-22, 2013-03-01, 2013-03-08, 2013-03-15, 2013-03-22, 2013-03-29, 2013-04-05, 2013-04-12, 2013-04-19, 2013-04-26, 2013-05-03, 2013-05-10, 2013-05-17, 2013-05-24, 2013-05-31, 2013-06-07, 2013-06-14, 2013-06-21, 2013-06-28, 2013-07-05, 2013-07-12, 2013-07-19, 2013-07-26, 2013-08-02, 2013-08-09, 2013-08-16, 2013-08-23, 2013-08-30, 2013-09-06, 2013-09-13, 2013-09-20, 2013-09-27, 2013-10-04, 2013-10-11, 2013-10-18, 2013-10-25, 2013-11-01, 2013-11-08, 2013-11-15, 2013-11-22, 2013-11-29, 2013-12-06]
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
This code will print all dates having Friday.
public class Friday {
public static void main(String[] args) throws ParseException {
String start = "01/01/2013";
String end = "12/01/2013";
SimpleDateFormat dateFormat=new SimpleDateFormat("dd/MM/yyyy");
Calendar scal=Calendar.getInstance();
scal.setTime(dateFormat.parse(start));
Calendar ecal=Calendar.getInstance();
ecal.setTime(dateFormat.parse(end));
ArrayList<Date> fridayDates=new ArrayList<>();
while(!scal.equals(ecal)){
scal.add(Calendar.DATE, 1);
if(scal.get(Calendar.DAY_OF_WEEK)==Calendar.FRIDAY){
fridayDates.add(scal.getTime());
}
}
System.out.println(fridayDates);
}
}
Here a solution based on new stream-features of Java-8 and using my library Time4J (v4.18 or later):
String start = "01/01/2009";
String end = "12/09/2013";
ChronoFormatter<PlainDate> f =
ChronoFormatter.ofDatePattern("dd/MM/yyyy", PatternType.CLDR, Locale.ROOT);
PlainDate startDate =
f.parse(start).with(PlainDate.DAY_OF_WEEK.setToNextOrSame(Weekday.FRIDAY));
PlainDate endDate = f.parse(end);
Stream<PlainDate> fridays =
DateInterval.stream(Duration.of(1, CalendarUnit.WEEKS), startDate, endDate);
fridays.forEachOrdered(System.out::println);
// output
2009-01-02
2009-01-09
...
2013-08-30
2013-09-06
// other example: list of fridays in ISO-8601-format
List<String> result =
DateInterval.between(startDate, endDate)
.stream(Duration.of(1, CalendarUnit.WEEKS))
.map((date) -> date.toString()) // or maybe use dd/MM/yyyy => f.format(date)
.collect(Collectors.toList());
By the way, Java-9 will offer a similar solution (but with exclusive end date boundary), see also this enhancement-issue.
with Lamma Date :
List<Date> fridays = Dates.from(2015, 12, 1).to(2016, 1, 1).byWeek().on(DayOfWeek.FRIDAY).build();
for (Date friday: fridays) {
System.out.println(friday);
}
public static List<Date> getWeekNumberList(Date currentMonthDate) {
List<Date> dates = new ArrayList<>(10);
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(currentMonthDate);
startCalendar.set(Calendar.DAY_OF_MONTH,
startCalendar.getActualMinimum(Calendar.DAY_OF_MONTH));
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(currentMonthDate);
endCalendar.set(Calendar.DAY_OF_MONTH,
endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
Date enddate = endCalendar.getTime();
while (startCalendar.getTime().before(enddate)) {
if (startCalendar.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
Date result = startCalendar.getTime();
dates.add(result);
startCalendar.add(Calendar.WEEK_OF_MONTH, 1);
} else {
startCalendar.add(Calendar.DAY_OF_MONTH, 1);
}
}
return dates;
}
Using Java 8+
LocalDate s= LocalDate.now();
LocalDate e= LocalDate.now().plusMonths(5);
List<LocalDate> dates2 = s.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)).datesUntil(e, Period.ofWeeks(1)).collect(Collectors.toList());
dates2.forEach(x->System.out.println(x));
I am having a bit of trouble parsing a string date to a Date object. I use a DateFormat to parse the string, and when I print the value of the date, it gives me what I expect.
But when I try get the day, the month or the year it gives me the wrong values. For instance, the year is 2011, but when I do .getYear() it gives me 111. I have no idea why this is happening. Here is the relevant code segment:
Date dateFrom = null;
String gDFString = g.getDateFrom();
System.out.println(gDFString);
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
try {
dateFrom = df.parse("04/12/2011");
System.out.println(dateFrom);
System.out.println(dateFrom.getYear());
} catch (ParseException e) {
e.printStackTrace();
}
When I out print dateFrom, I get Sun Dec 04 00:00:00 GMT 2011, which is what you would expect. But printing .getYear() returns 111.
I need to be able to get the day, month and year of the date for a time series graph.
Those methods have been deprecated. Instead, use the Calendar class.
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public final class DateParseDemo {
public static void main(String[] args){
final DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
final Calendar c = Calendar.getInstance();
try {
c.setTime(df.parse("04/12/2011"));
System.out.println("Year = " + c.get(Calendar.YEAR));
System.out.println("Month = " + (c.get(Calendar.MONTH)));
System.out.println("Day = " + c.get(Calendar.DAY_OF_MONTH));
}
catch (ParseException e) {
e.printStackTrace();
}
}
}
Output:
Year = 2011
Month = 3
Day = 12
And as for the month field, this is 0-based. This means that January = 0 and December = 11. As stated by the javadoc,
Field number for get and set indicating the month. This is a
calendar-specific value. The first month of the year in the Gregorian
and Julian calendars is JANUARY which is 0; the last depends on the
number of months in a year.
Javadoc to the rescue:
Deprecated. As of JDK version 1.1, replaced by
Calendar.get(Calendar.YEAR) - 1900.
Returns a value that is the result of subtracting 1900 from the
year that contains or begins with the instant in time represented by
this Date object, as interpreted in the local time zone.
You should not use deprecated methods. Deprecated methods are methods which should not be used anymore. But whatever the method you're using, read its javadoc to know what it does.
President Evil nailed it, Date.getYear() returns a value that is the result of subtracting 1900 from the year that contains. And you you shouldn't use it.
But quick fix for the code in the question is:
Date dateFrom = null;
String gDFString = g.getDateFrom();
System.out.println(gDFString);
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
try {
dateFrom = df.parse("04/12/2011");
System.out.println(dateFrom);
// Add 1900 to dateFrom.getYear()
System.out.println(dateFrom.getYear()+1900);
} catch (ParseException e) {
e.printStackTrace();
}
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Date.html#getYear%28%29
The specification states that it returns the year minus 1900. Probably a good idea to avoid deprecated methods as well.
tl;dr
int year =
LocalDate.parse(
"04/12/2011" ,
DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.US )
).getYear() ;
2011
java.time
The troublesome java.util.Date class and its siblings are now supplanted by the excellent java.time classes.
String input = "04/12/2011";
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( locale );
LocalDate ld = LocalDate.parse( input , f );
The java.time classes utilize sane numbering, with:
Months 1-12 for January-December
2011 means 2011
Days of week are 1-7 for Monday-Sunday (per ISO 8601).
Interrogate the LocalDate for its constituent parts.
int year = ld.getYear(); // 2011
int month = ld.getMonthValue(); // 4
int dayOfMonth = ld.getDayOfMonth(); // 12
You can even ask for automatically localized name of month and name of day-of-week.
String monthName = ld.getMonth().getDisplayName( TextStyle.FULL_STANDALONE , Locale.CANDA_FRENCH ); // avril
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
This is only a guess, but the 111 could be the number of years since 1900. Take a look at documentation/do some tests to verify this (I can't check at the moment)