Get all Fridays in a date Range in Java - java

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

Related

Unable to compare two dates in android

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

Issue with Calendar calculation that spans 2 calendar years

I'm using a method that calculates the next Monday from a given date string.
public static String getStartOfNextWeek(String DATE){
String format = "dd.MM.yyyy";SimpleDateFormat df = new SimpleDateFormat(format);
Date date = null;
try {
date = df.parse(DATE);
} catch (ParseException e) {
e.printStackTrace();
}
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int week = cal.get(Calendar.WEEK_OF_YEAR);
int year = cal.get(Calendar.YEAR);
Calendar calendar = new GregorianCalendar();
calendar.clear();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.WEEK_OF_YEAR, week);
//add 8 days to get next weeks Monday
calendar.add(Calendar.DAY_OF_WEEK, 8);
Date startDate = calendar.getTime();
SimpleDateFormat df2 = new SimpleDateFormat("dd.MM.yyyy");
String start = df2.format(startDate);
return start;
This work perfectly fine over a single calendar year, but when I'm passing a value that spans two calendar years problems arise.
For example:
input: 15.12.2014
output: 22.12.2014 CORRECT
input: 22.12.2014
output: 29.12.2014 CORRECT
input: 29.12.2014
output: 6.1.2014 INCORRECT
I realize where the mistake is located, since it takes WEEK_OF_YEAR as "1", but YEAR as "2014", so the output is technically correct. Just wrong for my purpose.
How would i best tell the calendar object that i want the next monday in week 1, but 2015?
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This Answer is left intact as history. See my newer Answer.
Joda-Time
The Joda-Time library, version 2.5, gets the correct answer. And gets it more easily.
// Parse input string.
String input = "29.12.2014";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd.MM.yyyy" );
LocalDate inputLocalDate = formatter.parseLocalDate( input );
// Find desired Monday.
LocalDate possibleMonday = inputLocalDate.withDayOfWeek( DateTimeConstants.MONDAY );
// The possible Monday could be past, present, or future of our input date. Adjust as needed.
LocalDate desiredMonday = null;
if ( possibleMonday.isBefore( inputLocalDate ) || possibleMonday.isEqual( inputLocalDate ) ) {
desiredMonday = possibleMonday.plusWeeks( 1 ); // If the possible Monday is past or present, add a week to get *next* Monday.
} else {
desiredMonday = possibleMonday; // If the possible Monday is future, use it.
}
String output = formatter.print( desiredMonday );
Dump to console.
System.out.println( "input : " + input );
System.out.println( "inputLocalDate : " + inputLocalDate );
System.out.println( "desiredMonday : " + desiredMonday );
System.out.println( "output : " + output );
When run.
input : 29.12.2014
inputLocalDate : 2014-12-29
desiredMonday : 2015-01-05
output : 05.01.2015
There's something weird when combining Date and Calender, when it comes to parsing dates, using only Calender it works great;
String[] dt = dateStr.split("\\.");
GregorianCalendar cal = new GregorianCalendar(Integer.parseInt(dt[2]), (Integer.parseInt(dt[1])-1), Integer.parseInt(dt[0]));
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.clear(Calendar.DAY_OF_WEEK);
cal.add(Calendar.DATE, 7);
System.out.println(cal.get(Calendar.YEAR) + "." + (cal.get(Calendar.MONTH)+1) + "." + cal.get(Calendar.DATE));
Edit: You have to subtract 1 from the month, since calendar expects the months to range from 0 to 11.
(Calendar.JANUARY == 0) //true
tl;dr
LocalDate.parse(
"29.12.2014" ,
DateTimeFormatter.ofPattern( "dd.MM.uuuu" )
).with(
TemporalAdjusters.next( DayOfWeek.MONDAY )
)
2015-01-05
java.time
The modern approach uses the java.time classes.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd.MM.uuuu" )
LocalDate ld = LocalDate.parse( "29.12.2014" , f ) ;
To move to another date, use a TemporalAdjuster implementation found in the TemporalAdjusters class. Specify the desired day-of-week with DayOfWeek enum object. No problem crossing end-of-year/start-of-year.
LocalDate followingMonday = ld.with( TemporalAdjusters.next( DayOfWeek.MONDAY ) ) ;
If you want to use the current date if it is a Monday, use TemporalAdjusters.nextOrSame.
Similar methods provide for previous day-of-week, as well: previous & previousOrSame.
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.

Getting dates after certain period of time in Java

Basically I have a date stored as text in this format: 16/09/2014 in SQLite Browser. I wonder is there any way to get the date after one day, one week, one month and one year of each records in the database using Java.
I retrieved and display the date retrieved from database in a listview:
viewHolder.txt_ddate.setText("Next Payment On: "
+ _recurlist.get(position).getRecurringStartDate().trim());
So I was thinking to use Java technique to get the dates I mentioned above. I have researched on this and found Documentation but I not sure how to implement it into my problem.
Any guides? Thanks in advance.
Use a Calendar object like in your example, which provides the add method.
String dateAsString = "16/09/2014";
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Calendar c = Calendar.getInstance();
c.setTime(formatter.parse(dateAsString));
c.add(Calendar.DAY_OF_MONTH, 1);
System.out.println("After one day: " + formatter.format(c.getTimeInMillis()));
c.add(Calendar.DAY_OF_MONTH, -1);
c.add(Calendar.WEEK_OF_YEAR, 1);
System.out.println("After one week: " + formatter.format(c.getTimeInMillis()));
c.add(Calendar.WEEK_OF_YEAR, -1);
c.add(Calendar.MONTH, 1);
System.out.println("After one month: " + formatter.format(c.getTimeInMillis()));
c.add(Calendar.MONTH, -1);
c.add(Calendar.YEAR, 1);
System.out.println("After one year: " + formatter.format(c.getTimeInMillis()));
c.add(Calendar.YEAR, -1);
Output:
After one day: 17/09/2014
After one week: 23/09/2014
After one month: 16/10/2014
After one year: 16/09/2015
With Joda-time:
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy");
LocalDate date = LocalDate.parse("16/09/2014", formatter);
System.out.println(date.toString(formatter));
System.out.println(date.plusDays(1).toString(formatter));
System.out.println(date.plusWeeks(1).toString(formatter));
System.out.println(date.plusMonths(1).toString(formatter));
System.out.println(date.plusYears(1).toString(formatter));
Output:
16/09/2014
17/09/2014
23/09/2014
16/10/2014
16/09/2015
Use Calendar api of Java/Android as follow:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date;
try {
date = sdf.parse(dateStr);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, 1); //add one day to your date
cal.add(Calendar.MONTH, 1); //add 1 month to your date
cal.add(Calendar.YEAR, 1); //add 1 year to current date
System.out.println(sdf.format(cal.getTimeInMillis()));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Here is the example:
String strDate = "16/09/2014";
int noOfDays = 1;
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date date = formatter.parse(strDate);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DATE, noOfDays);
tl;dr
LocalDate.parse(
"16/09/2014" ,
DateTimeFormatter.ofPattern( "dd/MM/uuuu" )
)
.plusDays( 1 )
.format( DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) )
Details
Tip: Use date-time data types for date-time values. You should be using a date-oriented type to define your column in your database to store a date value rather than as text.
Tip # 2: When you do serialize a date value to text, use the standard ISO 8601 formats. These are sensible, practical, and sort chronologically when alphabetical.
Use the java.time classes rather than the troublesome old date-time classes that are now legacy. For Android, see bullets below.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = LocalDate.parse( "16/09/2014" , f ) ;
LocalDate dayAfter = ld.plusDays( 1 ) ;
LocalDate weekAfter = ld.plusWeeks( 1 ) ;
LocalDate monthAfter = ld.plusMonths( 1 ) ;
LocalDate yearAfter = ld.plusYears( 1 ) ;
To generate a string in standard format, simply call toString.
String output = dayAfter.toString() ; // YYYY-MM-DD standard format.
2014-09-17
For other formats, use a DateTimeFormatter as seen above.
String output = dayAfter.format( f ) ;
17/09/2014
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
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….

How to get next month start date and end date if current month is february? [duplicate]

This question already has answers here:
How to get the first date and last date of the previous month? (Java)
(9 answers)
Closed 4 years ago.
String febSt = "02/01/2014" ;
String febEnd = "02/28/2014" ;
Above code is my input i need "03/01/2014" and "03/31/2014" as output .
I tried more codes and used calendar functions also but no result.From this program i need next month start and end date .
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class MonthCalculation {
public void getNextMonth(String date) throws ParseException{
DateFormat format = new SimpleDateFormat("MM/dd/yyyy");
Date dt = format.parse(date);
Date begining, end;
{
Calendar calendar = getCalendarForNow(dt);
calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
setTimeToEndofDay(calendar);
end = calendar.getTime();
SimpleDateFormat endDt = new SimpleDateFormat("MM/dd/yyyy");
String endStrDt = endDt.format(end);
if(date != null && date.equalsIgnoreCase(endStrDt)){
System.out.println("Ending of the month");
calendar.add(Calendar.DAY_OF_MONTH, 1);
Date lastDate = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
String lastDateofNextMonth = sdf.format(lastDate);
System.out.println("Next Month :"+lastDateofNextMonth);
Calendar c = getCalendarForNow(new Date(lastDateofNextMonth));
calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
setTimeToEndofDay(calendar);
end = calendar.getTime();
SimpleDateFormat sfd = new SimpleDateFormat("MM/dd/yyyy");
String lastDated = endDt.format(end);
System.out.println("Testing side :"+lastDated);
}else if (findLeapYear(dt)){
Calendar calendar3 = getCalendarForNow(dt);
calendar3.add(Calendar.YEAR, 1);
Date ds = calendar3.getTime();
SimpleDateFormat dtft = new SimpleDateFormat("MM/dd/yyyy");
String dates = dtft.format(ds);
dtft.setLenient(false);
System.out.println("YEAR : "+dates);
}else{
SimpleDateFormat dtft = new SimpleDateFormat("MM/dd/yyyy");
Calendar calendar2 = getCalendarForNow(dt);
System.out.println(" Calendar time :->> " + dtft.format(calendar2.getTime()));
int curre_month = calendar2.get(Calendar.MONTH);
int curre_day = calendar2.get(Calendar.DAY_OF_MONTH);
int curre_year = calendar2.get(Calendar.YEAR);
Date dat = calendar2.getTime();
calendar2.add(Calendar.DATE, 31);
Date ds = calendar2.getTime();
String dates = dtft.format(ds);
dtft.setLenient(false);
System.out.println("OTHER DAYS : "+dates);
}
}
}
private static boolean findLeapYear(Date dt){
boolean isLeapYr = false;
int yr = dt.getYear();
if ((yr%4 == 0 && yr%100!=0)){
isLeapYr = true;
}
return isLeapYr;
}
private static Calendar getCalendarForNow(Date dt) {
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTime(dt);
return calendar;
}
private static void setTimeToBeginningOfDay(Calendar calendar) {
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.DAY_OF_MONTH, 1);
}
private static void setTimeToEndofDay(Calendar calendar) {
System.out.println("For feb calling");
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 999);
}
public static void main(String[] args) {
try {
String janSt = "01/01/2014" ;
String janEnd = "01/31/2014" ;
String febSt = "02/01/2014" ;
String febEnd = "02/28/2014" ;
String marSt = "03/01/2014" ;
String marEnd = "03/31/2014" ;
String aprilSt = "04/01/2014" ;
String aprilEnd = "04/30/2014" ;
String maySt = "05/01/2014" ;
String mayEnd = "05/31/2014" ;
String juneSt = "06/01/2014" ;
String juneEnd = "06/30/2014" ;
String julySt = "07/01/2014" ;
String julyEnd = "07/31/2014" ;
String augSt = "08/01/2014" ;
String augEnd = "08/31/2014" ;
String sepSt = "09/01/2014" ;
String sepEnd = "09/30/2014" ;
String octSt = "10/01/2014" ;
String octEnd = "10/31/2014" ;
String novSt = "11/01/2014" ;
String novEnd = "11/30/2014" ;
String deceSt = "12/01/2014" ;
String deceEnd = "12/31/2014" ;
String jan15St="01/01/2015";
String jan15End="01/31/2015";
String leapyr = "02/29/2016";
String notaleapyr = "02/28/2015";
new MonthCalculation().getNextMonth(febSt);
} catch (ParseException e) {
e.printStackTrace();
}
}
I tried more with sample inputs , for the months February ,april, june nov start date are not working if i pass these dates as inputs it returns with 2nd of next month
Suggest any idea to proceed further.I am struggling this code.
Thanks in advance
Try this:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
Date nextMonthFirstDay = calendar.getTime();
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
Date nextMonthLastDay = calendar.getTime();
tl;dr
LocalDate.parse( "02/14/2014" , DateTimeformatter.ofPattern( "MM/dd/uuuu" ) )
.with( TemporalAdjusters.firstDayOfNextMonth() )
…and…
LocalDate.parse( "02/14/2014" , DateTimeformatter.ofPattern( "MM/dd/uuuu" ) )
.with( TemporalAdjusters.lastDayOfMonth() )
java.time
The modern way is with the new java.time package bundled with Java 8 (inspired by Joda-Time, defined by JSR 310).
The LocalDate class represents a date-only value without time-of-day and without time zone.
DateTimeFormatter f = DateTimeformatter.ofPattern( "MM/dd/uuuu" );
LocalDate ld = LocalDate.parse( "02/14/2014" , f );
The TemporalAdjuster interface defines a way for implementations to manipulate date-time values. The TemporalAdjusters class provides several handy implementations.
LocalDate firstOfMonth = ld.with( TemporalAdjusters.firstDayOfMonth() );
LocalDate firstOfNextMonth = ld.with( TemporalAdjusters.firstDayOfNextMonth() );
The Question asks for the first and last of the following month, March in this case. We have the first of next month, so we just need the end of that month.
LocalDate lastOfNextMonth = firstOfNextMonth.with( TemporalAdjusters.lastDayOfMonth() );
By the way, as discussed below, the best practice for defining a span of time is the Half-Open approach. That means a month is the first of the month and running up to, but not including, the first of the month after. In this approach we do not bother with determining the last day of the month.
Joda-Time
UPDATE: The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
Easy when using the Joda-Time library and its LocalDate class.
DateTimeFormatter formatter = DateTimeFormat.forPattern( "MM/dd/yyyy" );
LocalDate localDate = formatter.parseLocalDate( "02/14/2014" );
LocalDate firstOfMonth = localDate.withDayOfMonth( 1 );
LocalDate nextMonth = localDate.plusMonths(1); // Use this for "half-open" range.
LocalDate endOfMonth = nextMonth.minusDays(1); // Use this for "fully-closed" range.
Half-Open
Tip: Rather than focus on the last moment of a span of time, a better practice is to use the "Half-Open" approach.
In half-open, the beginning is inclusive and the ending is exclusive. So for "a month", we start with the first of the desired month and run up to, but not including, the first of the next month.
February 2014 = 2014-02-01/2014-03-01
Span Of Time
Be aware that Joda-Time provides three handy classes for handling a span of time: Interval, Period, and Duration.
These classes work only with date-time objects (DateTime class) rather than the date-only (LocalDate class) shown in code above.
While not directly relevant to your question, I suspect these span-of-time classes may be helpful.
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.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, 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 (<26), 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.
Something I quickly wrote for you - so could be cleaned up. Check if this helps:
String string = "02/01/2014"; //assuming input
DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date dt = sdf .parse(string);
Calendar c = Calendar.getInstance();
c.setTime(dt);
c.add(Calendar.MONTH, 1); //adding a month directly - gives the start of next month.
String firstDate = sdf.format(c.getTime());
System.out.println(firstDate);
//get last day of the month - add month, substract a day.
c.add(Calendar.MONTH, 1);
c.add(Calendar.DAY_OF_MONTH, -1);
String lastDate = sdf.format(c.getTime());
System.out.println(lastDate);
since it is hard to get in your code I have write some coe for you. please check it out..
Date today = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(today);
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.DATE, -1);
Date lastDayOfMonth = calendar.getTime();
DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
System.out.println("Today : " + sdf.format(today));
System.out.println("Last Day of Month: " + sdf.format(lastDayOfMonth));
I see the question is old. But I used the DateUtils static methods ceiling and truncate. Came in pretty handy instead of using multiple lines of code.
Date today = new Date();
DateUtils.truncate(new Date(), Calendar.MONTH) // Thu Dec 01 00:00:00 EET 2016
DateUtils.ceiling(new Date(), Calendar.MONTH) // Sun Jan 01 00:00:00 EET 2017

Get the last day of next three weeks Java

I want to get the last day of next three weeks.
For example,if today is Wednesday,16 April ,I will get the result Sunday,4 May.
I have written a function like this
public static Date nexThreeWeekEnd() {
Date now = new Date();
Date nextWeeks = DateUtils.truncate(DateUtils.addWeeks(now, 3), Calendar.DATE);
Calendar calendar = Calendar.getInstance();
calendar.setTime(nextWeeks);
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_WEEK));
return calendar.getTime();
}
DateUtils is used from this library:
org.apache.commons.lang.time.DateUtils;
But this function will return Wednesday, 7 May, that's mean it will return exactly the day of current date.
It's not necessary to rewrite my function. Any other ways to solve my problem will be very appriciated.
Thanks.
Use below code hope it helps
Calendar cal = Calendar.getInstance();
int currentDay = cal.get(Calendar.DAY_OF_WEEK);
int leftDays= Calendar.SUNDAY - currentDay;
cal.add(Calendar.DATE, leftDays)
Just try with:
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
c.add(Calendar.WEEK_OF_YEAR, 2);
DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
System.out.println(df.format(c.getTime()));
Output:
2014/05/04
You can do something like this:
Calendar calendar = Calendar.getInstance().getFirstDayOfWeek();
calendar.add(Calendar.WEEK_OF_YEAR, 4);
calendar.add(Calendar.DAY_OF_MONTH, -1);
IN Java we can make use of Gregorian calendar
please check if below code helps you
Date d = new Date();
GregorianCalendar cal1 = new GregorianCalendar();
cal1.setTime(d);
System.out.println(cal1.getTime());
int day = cal1.get(Calendar.DAY_OF_WEEK );
cal1.add(Calendar.DAY_OF_YEAR,-(day-1));/*go to start of the week*/
cal1.add(Calendar.WEEK_OF_YEAR,3); // add 3 weeks
day = cal1.get(Calendar.DAY_OF_MONTH );// get the end Day of the 3rd week
System.out.println("end of the 3rd week ="+day);
The Question and other Answers use old outmoded classes.
java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date & .Calendar. See Oracle Tutorial. Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
The LocalDate class represents a date-only value without time-of-day and time zone. You can use a TemporalAdjuster to generate a new LocalDate value relative to the original. The TemporalAdjusters (note the plural) class implements several handy such adjusters includning the one we need, nextOrSame( WeekOfDay ). The WeekOfDay class is a handy enum representing each of the seven days of the week, Monday-Sunday.
LocalDate start = LocalDate.of ( 2014 , Month.APRIL , 16 );
LocalDate nextOrSameSunday = start.with ( TemporalAdjusters.nextOrSame ( DayOfWeek.SUNDAY ) );
LocalDate twoWeeksAfterNextOrSameSunday = nextOrSameSunday.plusWeeks ( 2 );
Dump to console.
System.out.println ( "start: " + start + " | nextOrSameSunday: " + nextOrSameSunday + " | twoWeeksAfterNextOrSameSunday: " + twoWeeksAfterNextOrSameSunday );
start: 2014-04-16 | nextOrSameSunday: 2014-04-20 | twoWeeksAfterNextOrSameSunday: 2014-05-04

Categories