check if this hours is available - java

I have a question.
I am new and I need help with this.
I have an array of lessons in training room, each lesson has date, and time for ex.
KICKBOXING Lesson in on 01/05/2016 from 16:00 to 18:00.
Now i am making a method, that adds a lesson to this array.
but, I have to make sure, while adding a new lesson, that in this lesson's Date and time, I need to make sure that the room is not busy.
I mean that there is no other lesson in has the same date and time.
how should i check that?
I though about a way like this:
but did not work
public boolean checkDate(Date date)
{
for (int i = 0;i<Lesson.length;i++)
if(Lesson[i].getStartDate().getHours() == date.getHours() && Lesson[i].getStartDate().getMinutes() == date.getMinutes())
{
return true;
}
return false;
}
public boolean addLessons(Lesson les)
{
for(int i = 0; i < Lesson.length; i++)
if(les.getRoom().getRoomType() != E_Rooms.GYM && Lesson[i] != null && checkDate(les.getStartDate())== false)
{
for(int a = 0; i<Lesson.length;i++)
if(Lesson[i]==null)
{
Lesson[a] = les;
return true;
}
}
thank you.

I think that this should work
public boolean checkDate(Date beginDate, Date endDate){
for (int i = 0;i<Lesson.length;i++)
if(Lesson[i].getBeginDate() < endDate || Lesson[i].getEndDate() > beginDate){
return false;
}
return true;
}

Try this :
for (int i = 0;i<Lesson.length;i++)
if(Lesson[i].getBeginDate() == beginDate || Lesson[i].getEndDate() == endDate){
return false; //means there's a class in this date/time }
else
return true; // there's no class in this time. do something..

java.time
The troublesome legacy date-time classes have been supplanted by the java.time framework built into Java 8 and later.
Interval
Those classes are further extended by the ThreeTen-Extra project. That project’s classes include the Interval class that may be of use to you. An Interval represents a span of time between a pair of Instant objects. An Instant is a moment on the timeline in UTC with a resolution of nanoseconds. The Interval class has handy methods for comparing: abuts, contains, overlaps, encloses.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt1 = ZonedDateTime.of( LocalDate.of( 2016 , 1 , 2 ) , LocalTime.of( 16 , 0 , 0 ) , zoneId );
Instant start1 = zdt1.toInstant();
Instant stop1 = zdt1.plusHours( 2 ).toInstant(); // 18:00:00.0 = ( 16:00:00.0 + 2 hours ).
Interval reservation1 = Interval.of( start1 , stop1 );
A look to the class doc shows that you can create an Interval with use of a Duration. This might be handy for you.
Duration duration = Duration.of( 2 , ChronoUnit.HOURS );
Interval reservation = Interval( zdt.toInstant() , duration );
You could collect instances of Interval objects, each representing a reservation. Additional Interval objects can be compared to the already-collected objects to see if they overlap.
boolean res1OverlapsRes2 = reservation1.overlaps( reservation2 );
If you are certain reservations do not roll over midnight, you might create a Map with LocalDate as the Key and a collection of that date’s Interval objects collection as the Value. For any ZonedDateTime, call toLocalDate to get a LocalDate object to do lookup in the Map. With that date’s collection of Intervals, loop to see if the Interval being added overlaps with any of the pre-existing Interval objects.
The java.time and ThreeTen-Extra classes use the Half-Open approach where a span of time is defined with the beginning being inclusive while the ending is exclusive. Search for "half-open" to learn more.

Related

How to know if a date is in previous x minutes?

I have an ISO String date like this one: 2019-12-17 15:14:29.198Z
I would like to know if this date is in the previous 15 minutes from now.
Is-it possible to do that with SimpleDateFormat ?
val dateIso = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.FRENCH).parse(isoString)
java.time.Instant
Use Instant class to represent a moment in UTC.
To parse, replace SPACE with a T per the ISO 8601 standard.
Instant instant = Instant.parse( "2019-12-17 15:14:29.198Z".replace( " " , "T" ) ;
Determine the current moment in UTC.
Instant now = Instant.now() ;
Determine 15 minutes ago. Call plus…/minus… methods for date-time math.
Instant then = now.minusMinutes( 15 ) ;
Apply your test. Here we use the Half-Open approach where the beginning is inclusive while the ending is exclusive.
boolean isRecent =
( ! instant.isBefore( then ) ) // "Not before" means "Is equal to or later".
&&
instant.isBefore( now )
;
For older Android, add the ThreeTenABP library that wraps the ThreeTen-Backport library. Android 26+ bundles java.time classes.
If you are doing much of this work, add the ThreeTen-Extra library to your project (may not be appropriate for Android, not sure). This gives you the Interval class and it’s handy comparison methods such as contains.
Interval.of( then , now ).contains( instant )
If you already know the reference date everytime you access the program, you can use java.util.Calendar.
boolean isBefore;
long timeToCheck = 15*60*1000; //15 minutes.
Calendar calendar = Calendar.getInstance(), calendar2 = Calendar.getInstance();
calendar.set(Calendar.DATE, yourDay);
calendar.set(Calendar.HOUR_OF_DAY, yourHour);
calendar.set(Calendar.MINUTE, yourMinute);
calendar.set(Calendar.SECOND, yourSecond);
if (calendar.before(calendar2)){
long timeInMillis = calendar2.getTimeInMillis() - calendar.getTimeInMillis();
if ( timeInMillis >= timeToCheck ) isBefore = true;
else isBefore = false;
}
Is this you want:
int xMinutes = 10 * 60 * 1000;
long dateIsoinMillis = dateIso.getTime();
long xMinsAgo = System.currentTimeMillis() - xMinutes;
if (dateIsoinMillis < xMinsAgo) {
System.out.println("searchTimestamp is older than 10 minutes");
}

How to code new appointments in a planner to be arranged by date

I was tasked with creating an appointment planner in Java. I have everything done except I am having trouble with making the dates of new appointments be sorted by date.
I have tried switching the order around but no matter what I cannot get new appointments to be sorted properly by date.
{"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
int ind1 = 0,ind2 = 0;
for(int i=0;i<12;i++) {
if(monthArray[i].equalsIgnoreCase(month)) {
ind1=i;
}
if(monthArray[i].equalsIgnoreCase(app.getMonth())) {
ind2=i;
}
}
if(ind1<ind2) {
return 1;
}
else if(ind1==ind2) {
if(this.day<app.getDay()) {
return 1;
}
else if(this.getDay()>app.getDay()) {
return -1;
}
else {
if(this.getHour()<app.getHour()) {
return 1;
}
else if(this.getHour()>app.getHour()) {
return -1;
}
else {
if(this.getMin()<app.getMin()) {
return 1;
}
else if(this.getMin()>app.getMin()) {
return -1;
}
else {
return 0;
}
}
}
}
else {
return -1;
}
}
}
I expect new appointments to be sorted by date but they are not.
Time Zone
A proper appointment system must account for the fact that politicians around the world have shown a proclivity for redefining the time zone(s) under their juridiction. They do so surprisingly often, and with little or no warning.
So your Appointment class should carry two member fields:
LocalDateTime to hold the date and the time of day. Note that this does not represent a moment, is not a point on the timeline. If it holds a value of 3 PM on January 23rd next year, we don’t know if that means 3 PM in Tokyo, Kolkata, Paris, or Montreal — all different moments, several hours apart.
ZoneId for the time zone in which we intend that 3 PM appointment.
Example:
LocalDate ld = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 15 , 0 ) ;
this.localDateTime = LocalDateTime.of( ld , lt ) ;
this.zoneId = ZoneId.of( "America/Los_Angeles" ) ;
Sorting
For sorting purposes, your class can implement the Comparable interface, with the required compareTo method.
The trick is that you want the 3 PM appointments on the east coast of the US, for example, to sort above the 3 PM appointments of the west coast which occur a few hours later.
So the compareTo method must dynamically calculate a moment, determine a specific point on the timeline. Then, compare the moments of the various Appointment objects to sort properly.
First step is being sure that your JVM has been updated with the latest rules about the time zones. Remember, as mentioned above, these change quite often. Updates to Java will often include an update to the “tzdata” zone information. If a time zone you care about has changed more recently, you may need to update the tzdata yourself.
Next step is dynamically applying the zone to the date-time to determine a moment. Apply the ZoneId to the LocalDateTime to get a ZonedDateTime.
ZonedDateTime zdt = this.localDateTime.atZone( this.zoneId ) ;
Adjust that to UTC. Extract a Instant object, always in UTC by definition.
Instant thisInstant = zdt.toInstant() ;
Compare the Instant of this Appointment object with the other one passed to your compareTo. We can, in turn, call the Instant::compareTo method to do the work of actually comparing.
return thisInstant.compareTo( other.localDateTime.atZone( other.zoneId ).toInstant() ) ;
Alternatively, you might choose to use Objects.compare.
Java has a DateTime library that could be very helpful, but I'm assuming you don't want that seeing as you're doing it manually.
https://dzone.com/articles/java-comparable-interface-in-five-minutes
I'd recommend reading something like that, which gives a little bit of information about comparables. This allows you to create a method doing what you're doing, comparing two objects to each other. Then you can use a lot of standard solutions such as Collections.sort in order to test out and use your code more easily.
I'm not sure if that's what you're already doing so i thought I'd throw it out there.
But for the actual problem, the best solution is funnily enough using an inbuilt function.
Integer.compareTo(int a, int b) will compare two integers for you. All you're doing is repeatedly comparing integers. You can run your code like
int comp = Integer.compare(monthA, monthB;
if(comp != 0) return comp;
//proceed with rest of comparisons the same way you did the months
If you are getting appointment date then why dont you directing comparing them instead of comparing month ,date and time.
Though you can simply convert your appointment date to valid date object as below.
String sDate1="31/12/1998";
Date date1=new SimpleDateFormat("dd/MM/yyyy").parse(sDate1);
System.out.println(sDate1+"\t"+date1);
Reference link : https://www.javatpoint.com/java-string-to-date
Then simply compare date object
if (date1.compareTo(date2) > 0) {
some opertaion...
}
Reference link : https://www.mkyong.com/java/how-to-compare-dates-in-java/
Hope this will help you.

Find out if a series of dates covering an interval

I have two objects calendar
Calendar startCalendar = new GregorianCalendar(2013,0,31);
Calendar endCalendar = new GregorianCalendar();
I want to know if the interval between the two dates listed above is covered by n of other objects pair calendars without holes between intervals
Example1:
Calendar startCalendar1(2013,0,31);
Calendar endCalendar1(2014,0,31);
Calendar startCalendar2(2013,5,31);
Calendar endCalendar2();
Is GOOD
Example2:
Calendar startCalendar1(2013,0,31);
Calendar endCalendar1(2014,0,31);
Calendar startCalendar2(2014,2,31);
Calendar endCalendar2();
NOT GOOD
I use Java 6
Thanks
First approach: Only using Java 6
When I see your date examples like 2015-01-31 then I get the strong suspicion that you speak about closed date intervals otherwise choosing the end of a month might appear a little bit strange. This is a wide spread and reasonable approach. Unfortunately choosing a data type like java.util.Calendar representing an instant (also a date-time-zone-combo, too) is not in harmony with closed intervals. Such instant-like types work better with half-open intervals. The consequence is:
If you decide to use only Java-6-types then you can try to convert all Calendar-objects to Long-values representing the elapsed millisecs since Unix epoch as suggested by #guillaume girod-vitouchkina (has got my upvote as an example how to do this without any external library) . But you have to add an extra day to every single Calendar-object (if representing an end boundary) in advance to achieve the effect of closed date intervals.
And of course, you have still to do some home grown interval arithmetic yourself as shown in that answer in a sketchy way. If you carefully study the other proposals and your own requirements you will find that the final solution even requires more than just a new interval class or basic comparisons of intervals. You will also need a higher abstraction layer, namely defined operations between several intervals. Doing this all yourself might cause some headache. On the other hand: Implementing a Long-based interval arithmetic might save some performance overhead as typical for an extra interval library if you have good programming skills.
Second approach: Using a dedicated interval library
I only know four libraries which promise to handle intervals. Threeten-Extra as mentioned by #Basil Bourque cannot be used because it requires Java-8. Its interval class has the disadvantage to handle instants only, but not calendar dates. There is also almost no support for handling collections of intervals. The same can be said for Joda-Time (which is at least working on Java-6 and also offers a dedicated calendar date type, namely LocalDate but no date intervals).
An interesting option is using Guava and its class RangeSet, especially if you decide to continue using Calendar-objects and Longs. This class has some support for handling operations between intervals - for me much more appealing than using the simple interval class of Joda-Time.
Finally you also have the option to use my library Time4J which has the range-package. I will show now a complete solution for your problem:
// our test interval
PlainDate start = PlainDate.of(2013, Month.JANUARY, 31);
PlainDate end = SystemClock.inLocalView().today();
DateInterval test = DateInterval.between(start, end);
IntervalCollection<PlainDate> icTest = IntervalCollection.onDateAxis().plus(test);
// two intervals for your GOOD case
PlainDate s1 = PlainDate.of(2013, Month.JANUARY, 31);
PlainDate e1 = PlainDate.of(2014, Month.JANUARY, 31);
DateInterval i1 = DateInterval.between(s1, e1);
PlainDate s2 = PlainDate.of(2013, Month.MAY, 31);
PlainDate e2 = end; // today
DateInterval i2 = DateInterval.between(s2, e2);
IntervalCollection<PlainDate> goodCase =
IntervalCollection.onDateAxis().plus(i1).plus(i2);
boolean covered = icTest.minus(goodCase).isEmpty();
System.out.println("Good case: " + covered); // true
// two intervals for your BAD case
PlainDate s3 = PlainDate.of(2013, Month.JANUARY, 31);
PlainDate e3 = PlainDate.of(2014, Month.JANUARY, 31);
DateInterval i3 = DateInterval.between(s3, e3);
PlainDate s4 = PlainDate.of(2014, Month.MARCH, 31);
PlainDate e4 = end; // today
DateInterval i4 = DateInterval.between(s4, e4);
IntervalCollection<PlainDate> badCase =
IntervalCollection.onDateAxis().plus(i3).plus(i4);
covered = icTest.minus(badCase).isEmpty();
System.out.println("Bad case: " + covered); // false
The biggest part of code is just interval construction. The real interval arithmetic itself is done by this surprisingly small code fragment:
boolean covered =
IntervalCollection.onDateAxis().plus(test).minus(
IntervalCollection.onDateAxis().plus(i1).plus(i2)
).isEmpty();
Explanation: The test interval is covered by intervals i1 and i2 if the remainder of the subtraction of i1 and i2 from test is empty.
By the way: Date intervals in Time4J are closed intervals by default. You can change these intervals to half open intervals however if you really want (simply by calling withOpenEnd() on a given date interval).
And if you plan to migrate to Java-8 later, you can just update the Time4J-version to version line 4.x (version v3.x is for Java-6) and get very easy conversions to Java-8 types like java.time.LocalDate (for example: PlainDate.from(localDate) or LocalDate ld = plainDate.toTemporalAccessor()) so you can continue to use Time4J for extra features not covered by standard Java even in the future.
1 Rude but simple method
Use a Set< Long>
Set<Long> all_times_in_milli=new HashSet<Long>();
// Put every interval
// interval 1
for (long time_in_millis=startCalendar1.getTimeInMillis();
time_in_millis<= endCalendar1.getTimeInMillis();
time_in_millis+=86400000)
all_times_in_milli.add(time_in_millis);
// interval 2
for (long time_in_millis=startCalendar2.getTimeInMillis();
time_in_millis<= endCalendar2.getTimeInMillis();
time_in_millis+=86400000)
all_times_in_milli.add(time_in_millis);
// ETC
// AND TEST !
boolean failed=false;
for (long time_in_millis=startCalendar.getTimeInMillis();
time_in_millis<= endCalendar.getTimeInMillis();
time_in_millis+=86400000)
{
if (all_times_in_milli.contains(time_in_millis))
{
failed=true; break;
}
}
if (failed) System.out.println("Your are done !");
2 SMARTER METHOD
As every interval is an [long - long] interval
assemble your intervals to get continuous intervals (sets of overlaping intervals) => then you get B1-E1, B2-E2, B3-E3 distincts intervals
check if you first interval is inside of of them: B1 <= start <= end <=E1,
or B2 <= start <= end <=E2, ...
interesting only if you have a lot of datas
You using old date-time classes that have been supplanted by the java.time framework in Java 8 and later. Those old classes have proven to be clunky, confusing, and flawed.
java.time
The new java.time classes are inspired by the highly successful Joda‑Time library, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen‑Extra project. See the Tutorial.
The new classes include LocalDate for a date-only value without time-of-day. For your purpose, use this instead of Calendar.
Note that month numbers sensibly start from one, unlike Calendar.
LocalDate start = LocalDate.of( 2013 , 1 , 31 );
Note that in order to determine a date the time zone is crucial. The date is not simultaneously the same around the world. A new day dawns earlier in Paris than Montréal, for example.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );
From there you can call any combination of isAfter, isBefore, or isEqual to do your logic. Your Question is not clear exactly about that logic, so I cannot address that.
The ThreeTen-Extra project that extends java.time includes an Interval class that would help you. Unfortunately that class works only with Instant objects (date-time in UTC), not LocalDate. Specifically the methods for comparing intervals would help, abuts, encloses, and overlaps.
You would whip up your own IntervalLD class for LocalDate objects. Usually I do not recommend rolling your own date-time handling classes because date-time work is surprisingly tricky. But in this case with LocalDate the logic might simple. Here is my quick rough-draft completely untested example to get you started.
package com.example.javatimestuffmaven;
import java.time.LocalDate;
/**
* Similar to the 'Interval'class in the ThreeTen-Extra project, but for LocalDate objects.
*
* #author Basil Bourque
*/
public class IntervalLD {
private LocalDate start, end;
// Constructor
public IntervalLD ( LocalDate startArg , LocalDate endArg ) {
this.start = startArg;
this.end = endArg;
}
public Boolean isBefore ( IntervalLD interval ) {
// True if this one's end is before that one's start.
boolean before = this.getEnd ().isBefore ( interval.getStart () );
return before;
}
public Boolean isAfter ( IntervalLD interval ) {
// True if this one's start is after that one's end.
boolean after = this.getStart ().isAfter ( interval.getStart () );
return after;
}
public Boolean abuts ( IntervalLD interval ) {
// True if the intervals are next to each other on the time line but do not share a date. (exclusive of each other, not half-open)
// True if either one's end is a day ahead of the other's start or vice versa, either's start is day after the other's end.
if ( this.isBefore ( interval ) ) {
if ( this.getEnd ().plusDays ( 1 ).equals ( interval.getStart () ) ) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
} else if ( this.isAfter ( interval ) ) {
if ( this.getStart ().minusDays ( 1 ).equals ( interval.getEnd () ) ) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
} else if ( this.isEqual ( interval ) ) {
return Boolean.FALSE;
}
// Impossible. Should never reach this point.
// TODO: Handle this error condition.
return Boolean.FALSE;
}
public Boolean encloses ( IntervalLD interval ) {
//This checks if the specified interval is fully enclosed by this interval.
// The result is true if the start of the specified interval is contained in this interval, and
// the end is contained or equal to the end of this interval.
boolean thatOneStartsOnOrAfterThisOne = ! interval.getStart ().isBefore ( this.getStart () );
boolean thatOneEndsOnOrAfterThisOne = ! interval.getEnd ().isAfter ( this.getEnd () );
boolean doesEnclose = ( thatOneStartsOnOrAfterThisOne && thatOneEndsOnOrAfterThisOne );
return doesEnclose;
}
public Boolean overlaps ( IntervalLD interval ) {
// True if the two intervals share some part of the timeline.
// True if this interval does NOT start after that one ends OR this interval does NOT end before that one starts.
boolean startsTooLate = this.getStart ().isAfter ( interval.getEnd () );
boolean endsTooEarly = this.getEnd ().isAfter ( interval.getEnd () );
boolean doesOverlap = ( ! startsTooLate && ! endsTooEarly );
return ( doesOverlap );
}
public Boolean isEqual ( IntervalLD interval ) {
boolean sameStart = this.getStart ().isEqual ( interval.getStart () );
boolean sameEnd = this.getEnd ().isEqual ( interval.getEnd () );
return ( sameStart && sameEnd );
}
#Override
public String toString () {
String output = this.getStart () + "/" + this.getEnd ();
return output;
}
// Getters. Read-only (immutable) so no Setters.
/**
* #return the start
*/
public LocalDate getStart () {
return this.start;
}
/**
* #return the end
*/
public LocalDate getEnd () {
return this.end;
}
}

How can I add validation onto a Date that rolls into another year using Java Date class

I'm currently trying to improve an aspect of a project of mine.
Users are allowed to do a specific task, but they must book a date in order to do it.
I'm trying to add some more realistic validation onto my date, so that the tasks can't be booked a year in advance, and only a few months.
Currently I'm only checking the year of the input and comparing it to the current year, so if they try to assign themselves a task on 31st of December, they will not be able to because any date they enter will roll over to the next year, and my validation prevents this.
How can I make it so it will check the amount of months, rather than the current year?
I am able to do this for the current year, I just get stuck when the year comes to december and the months roll into January again.
Edit:
Those looking for a way to fix this, go here: Calculating the difference between two Java date instances
Because the lengths of months are different, I would test the number of days. Here's a couple of utility methods that get the job done in one line:
// Tests if the end date is within so many days of the start date
public static boolean isWithinRange(int days, Date end, Date start) {
return TimeUnit.DAYS.convert(end.getTime() - start.getTime(), TimeUnit.MILLISECONDS) < days;
}
// Tests if the specified date is within so many days of today
public static boolean isWithinRange(int days, Date end) {
return isWithinRange(days, end, new Date());
}
Here I've used the TimeUnit class to do the calculation for me.
you can use your own method. Something like this
public boolean isLaterDay(Date date, Date reference) {
if (date.getYear () > reference.getYear ()) return true;
if (date.getYear () < reference.getYear ()) return false;
return (date.getMonth() > reference.getMonth());
}
Another way of doing this would be as follows.
boolean validDate(Calendar inputDate)
{
Calendar validationDate = Calendar.getInstance().add(Calendar.MONTH, numOfMonths);
return inputDate.before(validationDate);
}
You can do something like this to validate the time
private static final int MAX_MONTHS_IN_ADVANCE = 3;
public boolean isValidDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, MAX_MONTHS_IN_ADVANCE);
return date.before(calendar.getTime());
}
Using the Joda-Time library:
If ( dateTimeInQuestion.isBefore( DateTime.now().plusMonths(3) )
java.time
The modern way to do this work is with the java.time classes. These classes supplant the troublesome old legacy date-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 );
Construct the date desired by the user.
LocalDate ld = LocalDate.of( 2016 , 12 , 31 );
Determine the boundaries, say six months ago and six months from now.
LocalDate past = today.minusMonths( 6 );
LocalDate future = today.plusMonths( 6 );
You can compare LocalDate objects with isBefore, isAfter, equals, and compareTo.
Let's test by asking if the user's date is equal to or later than the before boundary (in other words, not before) AND the user's date is before the future boundary. This comparison uses the Half-Open approach commonly used with date-time work. The beginning is inclusive while the ending is exclusive.
Boolean validDate = ( ( ! ld.isBefore( past) ) && ( ld.isBefore( future) ) );
Interval
If you often work with the spans of time, consider using the Interval class found in the ThreeTen-Extra project that adds onto the java.time classes. That class has handy methods such as contains, abuts, overlaps, and more.

Java Generate all dates between x and y [duplicate]

This question already has answers here:
how to get a list of dates between two dates in java
(23 answers)
Closed 6 years ago.
I attempted to generate the date range between date x and date y but failed. I have the same method in c# so I tried to modify it as much as I can but failed to get result. Any idea what I could fix?
private ArrayList<Date> GetDateRange(Date start, Date end) {
if(start.before(end)) {
return null;
}
int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
ArrayList<Date> listTemp = new ArrayList<Date>();
Date tmpDate = start;
do {
listTemp.add(tmpDate);
tmpDate = tmpDate.getTime() + MILLIS_IN_DAY;
} while (tmpDate.before(end) || tmpDate.equals(end));
return listTemp;
}
To be honest I was trying to get all the dates starting from january 1st till the end of year 2012 that is december 31st. If any better way available, please let me know.
Thanks
Joda-Time
Calendar and Date APIs in java are really weird... I strongly suggest to consider jodatime, which is the de-facto library to handle dates.
It is really powerful, as you can see from the quickstart: http://joda-time.sourceforge.net/quickstart.html.
This code solves the problem by using Joda-Time:
import java.util.ArrayList;
import java.util.List;
import org.joda.time.DateTime;
public class DateQuestion {
public static List<DateTime> getDateRange(DateTime start, DateTime end) {
List<DateTime> ret = new ArrayList<DateTime>();
DateTime tmp = start;
while(tmp.isBefore(end) || tmp.equals(end)) {
ret.add(tmp);
tmp = tmp.plusDays(1);
}
return ret;
}
public static void main(String[] args) {
DateTime start = DateTime.parse("2012-1-1");
System.out.println("Start: " + start);
DateTime end = DateTime.parse("2012-12-31");
System.out.println("End: " + end);
List<DateTime> between = getDateRange(start, end);
for (DateTime d : between) {
System.out.println(" " + d);
}
}
}
You could use this function:
public static Date addDay(Date date){
//TODO you may want to check for a null date and handle it.
Calendar cal = Calendar.getInstance();
cal.setTime (date);
cal.add (Calendar.DATE, 1);
return cal.getTime();
}
Found here.
And what is the reason of fail? Why you think that your code is failed?
tl;dr
Year year = Year.of ( 2012 ) ; // Represent an entire year.
year
.atDay( 1 ) // Determine the first day of the year. Returns a `LocalDate` object.
.datesUntil( // Generates a `Stream<LocalDate>`.
year
.plusYears( 1 ) // Returns a new `Year` object, leaving the original unaltered.
.atDay( 1 ) // Returns a `LocalDate`.
) // Returns a `Stream<LocalDate>`.
.forEach( // Like a `for` loop, running through each object in the stream.
System.out :: println // Each `LocalDate` object in stream is passed to a call of `System.out.println`.
)
;
java.time
The other Answers are outmoded as of Java 8.
The old date-time classes bundled with earlier versions of Java have been supplanted with the java.time framework built into Java 8 and later. See Tutorial.
LocalDate (date-only)
If you care only about the date without the time-of-day, use the LocalDate class. The LocalDate class represents a date-only value, without time-of-day and without time zone.
LocalDate start = LocalDate.of( 2016 , 1 , 1 ) ;
LocalDate stop = LocalDate.of( 2016 , 1 , 23 ) ;
To get the current date, specify a time zone. For any given moment, today’s date varies by time zone. For example, a new day dawns earlier in Paris than in Montréal.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
We can use the isEqual, isBefore, and isAfter methods to compare. In date-time work we commonly use the Half-Open approach where the beginning of a span of time is inclusive while the ending is exclusive.
List<LocalDate> localDates = new ArrayList<>();
LocalDate localDate = start;
while ( localDate.isBefore( stop ) ) {
localDates.add( localDate );
// Set up the next loop.
localDate = localDate.plusDays( 1 );
}
LocalDate::datesUntil
You can obtain a stream of LocalDate objects.
Stream< LocalDate > dates = start.datesUntil( stop ) ;
dates.forEach( System.out::println ) ;
LocalDateRange
If doing much of this work, add the ThreeTen-Extra library to your project. This gives you the LocalDateRange class to represent your pair of start and stop LocalDate objects.
Instant (date-time)
If you have old java.util.Date objects, which represent both a date and a time, convert to the Instant class. An Instant is a moment on the timeline in UTC.
Instant startInstant = juDate_Start.toInstant();
Instant stopInstant = juDate_Stop.toInstant();
From those Instant objects, get LocalDate objects by:
Applying the time zone that makes sense for your context to get ZonedDateTime object. This object is the very same moment on the timeline as the Instant but with a specific time zone assigned.
Convert the ZonedDateTime to a LocalDate.
We must apply a time zone as a date only has meaning within the context of a time zone. As we said above, for any given moment the date varies around the world.
Example code.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate start = ZonedDateTime.ofInstant( startInstant , zoneId ).toLocalDate();
LocalDate stop = ZonedDateTime.ofInstant( stopInstant , zoneId ).toLocalDate();
You can use joda-time.
Days.daysBetween(fromDate, toDate);
Found at joda-time homepage.
similar question in stackoverflow with some good answers.
Look at the Calendar API, particularly Calendar.add().

Categories