Joda Time - Get all weeks of a year - java

is there a way to get all weeks of a year plus start and ending days of every week ?
(With Joda-Time)
something like this (2012) :
week : 21
start: 21.05.2012
ending : 27.05.12
Thanks for your help

Try this:
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy");
Period weekPeriod = new Period().withWeeks(1);
DateTime startDate = new DateTime(2012, 1, 1, 0, 0, 0, 0 );
DateTime endDate = new DateTime(2013, 1, 1, 0, 0, 0, 0 );
Interval i = new Interval(startDate, weekPeriod );
while(i.getEnd().isBefore( endDate)) {
System.out.println( "week : " + i.getStart().getWeekOfWeekyear()
+ " start: " + df.format( i.getStart().toDate() )
+ " ending: " + df.format( i.getEnd().minusMillis(1).toDate()));
i = new Interval(i.getStart().plus(weekPeriod), weekPeriod);
}
Note that the week numbers start at 52 and then go from 1 - 51, since Jan 1 isn't on a Sunday.
If instead you want to see the dates of each Monday-Sunday week:
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy");
Period weekPeriod = new Period().withWeeks(1);
DateTime startDate = new DateTime(2012, 1, 1, 0, 0, 0, 0 );
while(startDate.getDayOfWeek() != DateTimeConstants.MONDAY) {
startDate = startDate.plusDays(1);
}
DateTime endDate = new DateTime(2013, 1, 1, 0, 0, 0, 0);
Interval i = new Interval(startDate, weekPeriod);
while(i.getStart().isBefore(endDate)) {
System.out.println("week : " + i.getStart().getWeekOfWeekyear()
+ " start: " + df.format(i.getStart().toDate())
+ " ending: " + df.format(i.getEnd().minusMillis(1).toDate()));
i = new Interval(i.getStart().plus(weekPeriod), weekPeriod);
}

Joda-Time is in maintenance mode
FYI, the Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. See Tutorial by Oracle.
Define ‘week’
You can define a week in different ways.
I will assume you mean the standard ISO 8601 week. Week number 1 has the first Thursday of the year, starts on a Monday, and a week-based year has either 52 or 53 weeks. A few days at the end or beginning of the calendar year may land in the other week-based year.
java.time
The modern approach uses the java.time classes, and their extension found in the ThreeTen-Extra project.
From ThreeTen-Extra, use the YearWeek class.
YearWeek start = YearWeek.of( 2017 , 1 ) ; // First week of the week-based year 2017.
Get the number of weeks in this week-based year, 52 or 53.
int weeks = start.lengthOfYear() ;
…or…
int weeks = ( start.is53WeekYear() ) ? 53 : 52 ;
Loop for each week of the year. For each YearWeek, ask it to produce a LocalDate for the beginning and ending of that week.
List<String> results = new ArrayList<>( weeks ) ;
YearWeek yw = start ;
for( int i = 1 , i <] weeks , i ++ ) {
String message = "Week: " + yw + " | start: " + yw.atDay( DayOfWeek.MONDAY ) + " | stop: " + yw.atDay( DayOfWeek.SUNDAY ) ;
results.add( message ) ;
// Prepare for next loop.
yw = yw.plusWeeks( 1 ) ;
}
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….
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.

Never used Joda Time.
I would do something like this:
Create a class that has the weeknumber and two DateTimes (start, end)
Create a List of this class
Iterate over the year (week per week) and save the current week in the list
That's the way I would do this with the standard java calendar api. Probably Joda Time is a little bit easier, I don't know.

Related

Android/Java - Calculate date difference shows different results

public long getDays(){
Date today = new Date ( );
Calendar cal = Calendar.getInstance (TimeZone.getTimeZone("GMT"));
// Set as today
cal.setTime ( today );
System.out.println ( "Today Cal: "+cal.get ( Calendar.YEAR ) + "Y / " + ( cal.get ( Calendar.MONTH ) + 1 ) + "M / " + cal.get ( Calendar.DATE ) + " D" );
Calendar cal2 = Calendar.getInstance (TimeZone.getTimeZone("GMT") );
//Month has offset -1. June = 5
cal2.set ( 2011, 5, 15 );//YY MM DD
System.out.println ( "Start Day Cal2: "+cal2.get ( Calendar.YEAR ) + "Y / " + ( cal2.get ( Calendar.MONTH ) + 1 ) + "M / " + cal2.get ( Calendar.DATE ) + " D" );
long count = 0;
while ( !cal2.after ( cal ) ) {
count++;
//increment date
cal2.add ( Calendar.DATE, 1 );
}
System.out.println ( "Ending Cal2: "+cal2.get ( Calendar.YEAR ) + "Y / " + ( cal2.get ( Calendar.MONTH ) + 1 ) + "M / " + cal2.get ( Calendar.DATE ) + " D" );
return count;
}
This is the code that I am using to calculate the difference in Days between today and 2011 June 15th.
This always works on Eclipse IDE, but when I implement this on Android, it shows 2 different results by random chance.
Screenshot
Most of the times it shows 2405, but sometimes it shows 2406
(Although the date should not have changed as it is 3 AM in the UK now.)
Console output
This is what is shown on System.out.println.
It has the same start date and end date, but by a random chance, while loop counts 1 extra. How?
It only happens on Android.
This is the code showing how the textview is being updated as a widget if it helps.
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int count = appWidgetIds.length;
//Set Date Text
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.haruhi_widget);
long days=getDays();
remoteViews.setTextViewText(R.id.textView, days+context.getString(R.string.days));
//Set ImageView
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.haruhi1,options);
remoteViews.setImageViewBitmap(R.id.imageView,bitmap);
Intent intent = new Intent(context, HaruhiWidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
remoteViews.setOnClickPendingIntent(R.id.imageView, getPendingSelfIntent(context, KYON_KUN_DENWA));
for (int i = 0; i < count; i++) {
// System.out.println(count+"appWidgetIds[i]");
int widgetId = appWidgetIds[i];
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
tl;dr
ChronoUnit.DAYS.between(
LocalDate.of( 2011 , Month.JUNE , 15 ) ,
LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
)
Problems
Certainly seems like a time zone issue. We cannot be certain as you have not provided us with enough information such as the time zone being used when your code was run.
More importantly, you are using troublesome old date-time classes that were outmoded years ago by the java.time classes.
And you are trying to work with date-only values using date-with-time-of-day classes.
Solution
calculate difference in Days between today and 2011 June 15th.
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.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
Always specify your desired/expected time zone explicitly. Omitting the zone means the JVM’s current default time zone is implicitly applied. That default can vary by machine and can even vary during runtime(!). So your results may vary. Instead, always pass the optional ZoneId argument. Doing so has the side benefit of making your intentions clear with more self-documenting code.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
Get the date for 2011 June 15th.
LocalDate ld = LocalDate.of( 2011 , Month.JUNE , 15 ) ;
Calculate elapsed days.
long days = ChronoUnit.DAYS.between( ld , today ) ;
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 (JSR 310) classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

Timer countdown is negative

I have a code of which is used to create a 24 hour countdown.
This code checks if a "date" file exists and if it doesn't it creates one, which contains the date and time in 24 hourse/a day. It then gets the current time and compares the two, to create a countdown from the current date, to the date in the document.
This makes it possible to save the timer and check how far it has come even though the code is "turned off". The only issue is the fact that sometimes the timer turns negative. Like if I run the code from the start with no "date" file created on Monday, right before midnight, lets say Monday at half past eleven at night. Then if I stop the code and run it again when the current date has passed midnight, so it is actually Tuesday, but there is still missing up to 23 hours before it hits the actual goal timer. If this is the case, the time left in the countdown is negative. Like it would show "-1day 23hours 60minutes and 60seconds remaining". But if as an example it is run from scratch past midnight on Tuesday and then relaunch after 30 minutes the same day, there is no issue.
I hope you can understand what the issue is, it is slightly hard to express through text. But I have attached the whole code of mine, which is the exact one I am using and of which is having that issue. The code has comments for every actions happening, so it should be rather easy to understand.
static File dFileD = new File("date.txt");
static String date = "";
public static void main(String[] args) throws ParseException {
Timer tickTock = new Timer();
TimerTask tickTockTask = new TimerTask(){
public void run(){
try {
timFunRun(); //Timer calls method to start the countdown
} catch (ParseException e) {
e.printStackTrace();
}
}
};
tickTock.schedule(tickTockTask, 1000, 1000);
}
static void timFunRun() throws ParseException {
if (!dFileD.exists()){ //if it doesn't exist, first part
//Get current date and time
Calendar startDat = Calendar.getInstance();
System.out.println("Current date: " + startDat.getTime());
//Get that current date and time and then add 1 day
Calendar todAdd = Calendar.getInstance();
todAdd.add(Calendar.DATE, 1);
System.out.println("Date in 1 day: " + todAdd.getTime());
//Create a format for sending date to text file
SimpleDateFormat formDat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
String formatted = formDat.format(todAdd.getTime());
System.out.println("Formatted: " + formatted);
try{
PrintWriter dW = new PrintWriter("date.txt");
dW.println(formatted);
dW.close();
} catch (IOException e) {
}
System.out.println(formDat.parse(formatted));
} else { //if it does exist, second part
//Get current date and time
Calendar currentDeT = Calendar.getInstance();
System.out.println("Current date: " + currentDeT.getTime());
SimpleDateFormat formDat2 = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
Date dateFroText = null; //Get the "goal" date
try {
Scanner dateRead = new Scanner(dFileD);
while (dateRead.hasNextLine()) {
date = dateRead.nextLine();
dateFroText = formDat2.parse(date);
System.out.println("Date from text new format: " + dateFroText);
}
dateRead.close();
} catch (Exception e) {
System.out.println("Error!");
}
if (dateFroText != null){ //method to compare the current date and the goal date
Calendar dateFromTxtCal = Calendar.getInstance();
dateFromTxtCal.setTime(dateFroText);
int yearDiff = dateFromTxtCal.get(Calendar.YEAR) - currentDeT.get(Calendar.YEAR);
int dayDiff = ((yearDiff*365) + dateFromTxtCal.get(Calendar.DAY_OF_YEAR)) - currentDeT.get(Calendar.DAY_OF_YEAR);
dayDiff--;
int hourDiffer = dateFromTxtCal.get(Calendar.HOUR_OF_DAY)+23 - currentDeT.get(Calendar.HOUR_OF_DAY);
int minuDiff = dateFromTxtCal.get(Calendar.MINUTE)+60 - currentDeT.get(Calendar.MINUTE);
int secoDiff = dateFromTxtCal.get(Calendar.SECOND)+60 - currentDeT.get(Calendar.SECOND);
System.out.println(dayDiff + " days " + hourDiffer + " hours " + minuDiff +" minutes " + secoDiff + "seconds remaining");
}
}
}
Avoid legacy date-time classe
You are working too hard. And you are using troublesome old date-time classes now obsoleted and supplanted by the java.time classes.
Work in UTC
Also, if you only care about the next 24 hours, then no need for time zones. Just use UTC.
Instant
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instantNow = Instant.now();
Duration
A span of time unattached to the timeline is represented by the Duration or Period classes.
Duration duration = Duration.ofHours( 24 );
You can perform date-time math, adding a Duration to an Instant. The java.time classes use immutable objects, so the result of such manipulations is a fresh object with values based on the original.
Instant instantLater = instantNow.plus( duration );
ISO 8601
To serialize date-time values such as those to text, use the standard ISO 8601 formats. The java.time classes use ISO 8601 by default when generating and parsing strings.
String output = instantNow.toString();
2017-04-03T03:18:48.183Z
Calculate remaining time
To get the remaining time, let java.time do the math.
Duration remaining = Duration.between( Instant.now() , instantLater );
To report that in standard ISO 8601 format, call toString. The format for durations is PnYnMnDTnHnMnS. The P marks the beginning (for Period), and the T separates any years-months-dates from hours-minutes-seconds.
String outputRemaining = remaining.toString();
PT23H34M22S
To generate a longer string, in Java 9 call the to…Part method for each unit (hours, minutes, seconds). Oddly those methods were omitted from the original java.time.Duration class in Java 8. You could look to the source code of Java 9 to write similar code.
Or more simply, manipulate the standard string. Delete the PT. Replace the H with hours and so on. Do S first to avoid the plural s in the other two words. Admittedly this is kind of a hack, but it works thanks to some good luck in the occurrence of letters is the English spelling of hours-minutes-seconds.
String output = remaining.toString()
.replace( "PT" , "" )
.replace( "S" , " seconds " )
.replace( "H" , " hours " )
.replace( "M" , " minutes " ) ;
23 hours 34 minutes 22 seconds
ZonedDateTime
If you want to display the target date-time in the user's desired/expected time zone, apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
To generate a string in standard format, call toString. Actually the ZonedDateTime class extends the standard by appending the name of the time zone in square brackets.
To generate strings in other formats, search Stack Overflow for many examples of DateTimeFormatter class.
Converting to java.util.Date
The Timer class has not yet been updated to work with the java.time types. So convert back to a Date object via new methods added to the old classes, in this case from.
java.util.Date date = java.util.Date.from( instantLater );
Or use a count of milliseconds from the Duration object.
long milliseconds = duration.toMillis() ;
ScheduledExecutorService
FYI, the Timer and TimeTask classes have been supplanted by the Executors framework. Specifically for your purpose, the ScheduledExecutorService. Search Stack Overflow for many examples and discussions.
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 and 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 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….
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.

JodaTime - Number of days in each months between 2 dates

I have 2 dates like this :
DateTime startingDate = new DateTime(STARTING_YEAR, STARTING_MONTH, STARTING_DAY, 0, 0);
DateTime endingDate = new DateTime(ENDING_YEAR, ENDING_MONTH, ENDING_DAY, 0, 0);
TOTAL_DAYS = Days.daysBetween(startingDate, endingDate).getDays();
It is easy to know the total days between, but I'm not familiar at all with the API and would like to know if there is an easier way to find the number of days in each months between 2 dates without loops and ifs.
Example :
DateTime startingDate = new DateTime(2000, 1, 1, 0, 0);
DateTime endingDate = new DateTime(2000, 2, 3, 0, 0);
Would give 31 for January and 2 for February.
Thanks!
I did it with a loop finally.
DateTime startingDate = new DateTime(STARTING_YEAR, STARTING_MONTH, STARTING_DAY, 0, 0);
DateTime endingDate = new DateTime(ENDING_YEAR, ENDING_MONTH, ENDING_DAY, 0, 0);
TOTAL_DAYS = Days.daysBetween(startingDate, endingDate).getDays();
DateTime currentDate = startingDate;
System.out.println(currentDate.dayOfMonth().getMaximumValue() - currentDate.dayOfMonth().get() + 1);
currentDate = currentDate.plus(Period.months(1));
while (currentDate.isBefore(endingDate)) {
System.out.println(currentDate.dayOfMonth().getMaximumValue());
currentDate = currentDate.plus(Period.months(1));
}
System.out.println(endingDate.dayOfMonth().get());
double days = (endingDate.getMillis()-startingDate.getMillis())/86400000.0;
that gives the number of days as a floating point number. truncate if you only want the number of full days.
This may help:
DateTime startingDate = new DateTime(2000, 1, 1, 0, 0);
DateTime endingDate = new DateTime(2000, 2, 3, 0, 0);
Duration duration = new Duration(startingDate, endingDate);
System.out.println(duration.getStandardDays());//get the difference in number of days
FYI, the Joda-Time project, now in maintenance mode, advises migration to java.time.
java.time
You will need to iterate if you want to address each intervening month individually. But this job is somewhat simplified by the YearMonth class. Furthermore, you can mask away the iteration by using Streams.
Half-Open
The java.time classes wisely use the Half-Open approach to defining a span of time. This means the beginning is inclusive while the ending is exclusive. So a range of months needs to end with the month following the ending target month.
TemporalAdjuster
The TemporalAdjuster interface provides for manipulation of date-time values. The TemporalAdjusters class (note the plural s) provides several handy implementations. Here we need:
TemporalAdjusters.firstDayOfNextMonth()
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate startDate = LocalDate.of( 2000 , 1 , 1 );
YearMonth ymStart = YearMonth.from( startDate );
LocalDate stopDate = LocalDate.of( 2000 , 2 , 3 );
LocalDate stopDateNextMonth = stopDate.with( TemporalAdjusters.firstDayOfNextMonth() );
YearMonth ymStop = YearMonth.from( stopDateNextMonth );
Loop each month in between.
You can ask for a localized name of the month, by the way, via the Month enum object.
YearMonth ym = ymStart;
do {
int daysInMonth = ym.lengthOfMonth ();
String monthName = ym.getMonth ().getDisplayName ( TextStyle.FULL , Locale.CANADA_FRENCH );
System.out.println ( ym + " : " + daysInMonth + " jours en " + monthName );
// Prepare for next loop.
ym = ym.plusMonths ( 1 );
} while ( ym.isBefore ( ymStop ) );
2000-01 : 31 jours en janvier
2000-02 : 29 jours en février
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, & 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. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and 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 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….
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.

Creating a DateTime from two other dates

Basically I want to see if someones birthday is within 3 months of todays date. I am going to use Days to do this and just say "90" days.
My thoughts are as follows:
I will set a new datetime as todays date and then grab the DOB of the person in question.
I will then want to take the day and month from the DOB and the year from Todays date.
Then these days, months and years will be merged into one new date.
For example:
DOB 04/05/1987
Today 10/05/2013
NewBirth 04/05/2013
How can I achieve the part where I grab the days/months from one date, years from another, and put these into one date?
(Only key factors, im aware this rule wouldn't run)
import org.joda.time.ReadableInstant;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Months;
import org.joda.time.Years;
rule"Blah"
salience 1
when
Proposer($dob : dateOfBirth)
then
DateTime NewBirth = new DateTime()
DateTime today = new DateTime();
#grab DOB day and month
#grab Todays year
#turn "NewBirth" into a combination of the above 2 lines
int $birthday = (Days.daysBetween((ReadableInstant)today,(ReadableInstant)NewBirth).getDays());
If ($birthday <= 90){
logger.info("HURRRAAAYYYYYY");
}
end
I would do it with the standard JDK Calendar
boolean isWithin3Month(int y, int m, int d) {
Calendar now = Calendar.getInstance();
Calendar birthday = new GregorianCalendar(y, m, d);
int currentMonth = now.get(Calendar.MONTH);
int birthDayMonth = birthday.get(Calendar.MONTH);
int monthDiff;
if (birthDayMonth < currentMonth) { // eg birth = Jan (0) and curr = Dec (11)
monthDiff = 12 - currentMonth + birthDayMonth;
} else {
monthDiff = birthDayMonth - currentMonth;
}
if (monthDiff < 0 || monthDiff > 3) {
return false;
} else if (monthDiff == 0) {
return birthday.get(Calendar.DATE) >= now.get(Calendar.DATE);
}
return true;
}
java.time
The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
LocalDate
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 );
You apparently want to know if the birthday anniversary lands between today and 90 days from today. So determine that 90 day limit.
LocalDate ninetyDaysFromToday = today.plusDays( 90 );
Get the birthdate.
LocalDate birthdate = LocalDate.of( 1987 , Month.APRIL , 5 ) ;
MonthDay
The MonthDay class represents, well, a month and a day-of-month, without any year. You can adjust into a year to get a date. Perfect for adjusting that birthday into this year.
If the birthday of this year is already past, then we need to consider next year’s birthday, as the 90 day limit may wrap over into the new year.
MonthDay mdBirthday = MonthDay.from( birthdate );
MonthDay mdToday = MonthDay.from( today );
int y = mdBirthday.isBefore( mdToday ) ? ( today.getYear()+1 ) : today.getYear() ;
LocalDate nextBirthday = mdBirthday.atYear( y );
Boolean nextBirthdayIsWithinNextNinetyDays = nextBirthday.isBefore( ninetyDaysFromToday );
Or another way to do the same.
LocalDate nextBirthday = MonthDay.from( birthdate ).atYear( today.getYear() ) ; // Possibly the next birthday, not yet sure.
if( nextBirthday.isBefore( today ) ) {
// This year’s birthday is past, so increment the year to get next birthday.
nextBirthday = nextBirthday.plusYears( 1 );
}
Boolean nextBirthdayIsWithinNextNinetyDays = nextBirthday.isBefore( ninetyDaysFromToday );
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, & 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. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and 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 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….
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.
Try
DateTime newBirth = new DateTime(today.year(), $dob.monthOfYear(), $dob.dayOfMonth(), 00, 00);
instead of the parameterless constructer at the beginning of your then statement.
Ended up managing to do it with Jodatime,
rule"Less than 3months before Birthday Discount"
when
Proposer($dob : dateOfBirth)
then
DateTime today = new DateTime();
DateTime newBirth = new DateTime(today.year().get()+"-"+$dob.monthOfYear().get()+"-"+$dob.dayOfMonth().get());
int $birthday = (Days.daysBetween((ReadableInstant)today,(ReadableInstant)newBirth).getDays());
if($birthday <=90 && $birthday>0){
logger.info("discount applied");
}
end

Joda Time: How to get dates of weekdays on some date interval?

I have two LocalDates that represent some time interval. Now i have to get LocalDates of all fridays, that this interval contains.
Easiest way to do it?
package org.life.java.so.questions;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
/**
*
* #author Jigar
*/
public class JodaTimeDateTraverseQuestion {
public static void main(String[] args) {
DateTime startDt = new DateTime(2010,12,1,0,0,0,0);//1st Dec 2010
DateTime endDt = new DateTime(2010,12,31,0,0,0,0);//31st Dec 2010
DateTime tempDate = new DateTime(startDt.getMillis());
while(tempDate.compareTo(endDt) <=0 ){
if(tempDate.getDayOfWeek() != DateTimeConstants.SATURDAY && tempDate.getDayOfWeek() != DateTimeConstants.SUNDAY){
System.out.println(""+tempDate);
}
tempDate = tempDate.plusDays(1);
}
}
}
Solution: lazily step by one week.
import org.joda.time.LocalDate;
import java.util.Iterator;
public class DayOfWeekIterator implements Iterator<LocalDate>{
private final LocalDate end;
private LocalDate nextDate;
public DayOfWeekIterator(LocalDate start, LocalDate end, int dayOfWeekToIterate){
this.end = end;
nextDate = start.withDayOfWeek(dayOfWeekToIterate);
if (start.getDayOfWeek() > dayOfWeekToIterate) {
nextDate = nextDate.plusWeeks(1);
}
}
public boolean hasNext() {
return !nextDate.isAfter(end);
}
public LocalDate next() {
LocalDate result = nextDate;
nextDate = nextDate.plusWeeks(1);
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Test
import org.joda.time.DateTimeConstants;
import org.joda.time.LocalDate;
public class DayOfWeekIteratorTest {
public static void main(String[] args) {
LocalDate startDate = new LocalDate(2010, 12, 1);//1st Dec 2010
LocalDate endDate = new LocalDate(2010, 12, 31);//31st Dec 2010
DayOfWeekIterator it = new DayOfWeekIterator(startDate, endDate, DateTimeConstants.FRIDAY);
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
tl;dr
java.time.LocalDate.of( 2018 , Month.JANUARY , 23 ) // A date-only class in the modern *java.time* classes that supplant both Joda-Time and the troublesome old date-time classes.
.with(
TemporalAdjusters.next( DayOfWeek.FRIDAY ) // Nifty `TemporalAdjuster` implementation for moving to another date. Immutable Objects pattern means a new object is returned based on the original which remains unmodified.
)
.isBefore( // Compare `LocalDate` objects with `isBefore`, `isAfter`, and `isEqual`.
LocalDate.of( 2018 , Month.FEBRUARY , 27 );
)
java.time
FYI, the Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
Define your stop & start LocalDate objects.
LocalDate start = LocalDate.of( 2018 , Month.JANUARY , 23 );
LocalDate stop = LocalDate.of( 2018 , Month.FEBRUARY , 27 );
// TODO: Verify start.isBefore( stop ).
Collect the Friday dates we find. You might optimize a bit by sizing the collection.
// Pre-size the collection.
int initialCapacity = ( int ) ( ChronoUnit.WEEKS.between( start , stop ) + 2 ); // Adding two for good measure.
List < LocalDate > fridays = new ArrayList <>( initialCapacity );
Determine the first Friday, using the start date if it is itself a Friday. Use a pair of TemporalAdjuster implementations offered in the TemporalAdjusters class: next​(DayOfWeek) & nextOrSame​(DayOfWeek). Pass the desired day-of-week via the DayOfWeek enum, seven pre-defined objects, one for each day of the week Monday-Sunday.
LocalDate friday = start.with( TemporalAdjusters.nextOrSame( DayOfWeek.FRIDAY ) );
while ( friday.isBefore( stop ) )
{
fridays.add( friday ); // Remember this Friday date.
// Setup next loop.
friday = friday.with( TemporalAdjusters.next( DayOfWeek.FRIDAY ) );
}
System.out.println( "From " + start + " to " + stop + " = " + fridays );
From 2018-01-23 to 2018-02-27 = [2018-01-26, 2018-02-02, 2018-02-09, 2018-02-16, 2018-02-23]
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, 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.

Categories

Resources