I have an ArrayList of integer numbers that represent day-of-month.For example my list contains 2,8,15(always in increasing order) so it will represent dates 2nd ,8th and 15th of any month.On these dates i have to generate some invoice.So like if I am generating invoice on 15th of any month then i need to get data from some table where date should be between previous invoice date(which is 8 according to arraylist) and 15th.Like if I am generating invoice on 2nd of any month then i need to get data between previous invoice date(which will be 15th of previous month according to arraylist) and 2nd of current month.
So my question is like if my code is running today and date is 2nd then how will i get previous invoice date as java date object.So that i can pass today's date and previous invoice date to filter out and get data from the table.
You need to use java8+ or jodatime. Java 8 adopted jodatime so that's why there's a distinction. Jodatime's api is exactly what you are looking for.
You can just use the following code:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date d = sdf.parse("21/12/2012");
the string that you are parsing, which in this example is "21/12/2012" can be changed to whatever you want.
Hope this helps, if not, let me know what issue you're facing.
Your question is confusing, but I can get you started. I do suggest you rewrite your question to be crystal clear, for your own benefit, to come to understand your problem thoroughly in plain language before you start coding.
First use precise terms to clarify your thinking. You do not start with an ArrayList of date, you have an ArrayList of integer numbers that represent day-of-month.
Next you need today's date. That requires a time zone. For any given moment the date varies around the globe by zone.
ZoneId z = ZoneId.of( "America/Montreal" );
The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate today = LocalDate.now( z );
You might find YearMonth class handy.
YearMonth ym = YearMonth.from( today );
You can get a date from that YearMonth.
LocalDate ld = ym.atDay( 15 );
You can get last day of month.
LocalDate endOfMonth = ym.atEndOfMonth();
You can do math, adding or subtracting months to the YearMonth.
YearMonth previousYm = ym.minusMonths( 1 );
You can retrieve a day-of-month from a LocalDate.
int dayOfMonth = myLocalDate.getDayOfMonth();
You can increment LocalDate with plus and minus methods.
LocalDate nextDate = myLocalDate.plusDays( 1 );
You should be able to put those pieces together to perform your particular business logic.
Tip: Stay away from the troublesome old legacy date-time classes. Use only java.time classes.
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.
finally i solved my problem from below code.
private Date getPreviousInvoiceDateFromList(List<String> invoiceDatesList, int dayOfMonth,
int lastDayOfMonth) {
String dayOfMonthStr = String.valueOf(dayOfMonth);
if (invoiceDatesList.size() == 1) {
return new LocalDate().minusMonths(1).toDate();
}
int prevInvoiceDateIndex = -1;
int todaysDateIndex = invoiceDatesList.indexOf(dayOfMonthStr);
if (todaysDateIndex == 0) {
prevInvoiceDateIndex = invoiceDatesList.size() - 1;
String prevInvoiceDate = invoiceDatesList.get(prevInvoiceDateIndex);
int prevInvoiceDateVal = Integer.parseInt(prevInvoiceDate);
int noOfDaysDiff = lastDayOfMonth - prevInvoiceDateVal;
int totalDaysDiff = noOfDaysDiff + dayOfMonth;
return new LocalDate().minusDays(totalDaysDiff - 1).toDate();
} else {
prevInvoiceDateIndex = todaysDateIndex - 1;
String prevInvoiceDate = invoiceDatesList.get(prevInvoiceDateIndex);
int prevInvoiceDateVal = Integer.parseInt(prevInvoiceDate);
int diff = dayOfMonth - prevInvoiceDateVal;
return new LocalDate().minusDays(diff).toDate();
}
}
Related
I am having quarter end date of last quarter let it be 30-09-20 , the requirement is to find end date of next quarter i.e 31-12-20. I am using below code to do the same but is it giving wrong output in some scenarios. This solution should be correct for all quarters.
String str = "30-09-20";
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yy");
Date date = format.parse(str);
Date newDate = DateUtils.addMonths(date, 3);
System.out.println(newDate);//Dec 30 - It should be 31 Dec
To answer your question, I think you are looking for this :
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yy");
LocalDate end = LocalDate.parse("30-09-20", formatter)
.plusMonths(3) // add three months to your date
.with(TemporalAdjusters.lastDayOfMonth()); // with the last day of the month
Note: don't use the legacy Date library, you tagged your question Java-8 which mean you can use java-time API.
Get last day of current quarter
#deHaar have reason, to get the end date of curent quarter, I would suggest to use :
public LocalDate lastDayFromDateQuarter(String date) {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yy");
LocalDate ld = LocalDate.parse(date, formatter);
int quarter = ld.get(IsoFields.QUARTER_OF_YEAR); // Get the Quarter, 1, 2, 3, 4
// Then create a new date with new quarter * 3 and last day of month
return ld.withMonth(quarter * 3).with(TemporalAdjusters.lastDayOfMonth());
}
Get last day of next quarter
To get the last day of the next quarter, then you just can add three months to your date like so :
public static LocalDate lastDayFromDateQuarter(String date) {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yy");
LocalDate ld = LocalDate.parse(date, formatter);
int quarter = ld.get(IsoFields.QUARTER_OF_YEAR);
return ld.withMonth(quarter * 3)
.plusMonths(3)
.with(TemporalAdjusters.lastDayOfMonth());
}
tl;dr
Use YearQuarter class from ThreeTen-Extra.
YearQuarter // A class available in the ThreeTen-Extra library.
.from( // Factory method rather than calling `new`.
LocalDate.of( 2020 , Month.SEPTEMBER , 30 ) // Returns a `LocalDate` object, represent a date-only value without a time-of-day and without a time zone.
) // Returns a `YearQuarter` object.
.plusQuarters( 1 ) // Perform date-math, resulting in a new `YearQuarter` object (per immutable objects pattern).
.atEndOfQuarter() // Determine the date of last day of this year-quarter.
.toString() // Generate text in standard ISO 8601 format.
2020-12-31
org.threeten.extra.YearQuarter
The ThreeTen-Extra library provides classes that extend the functionality of the java.time classes built into Java 8 and later. One of its classes is YearQuarter to represent a specific quarter in a specific year. The quarters are defined by calendar-year: Jan-Mar, Apr-June, July-Sept, Oct-Dec.
LocalDate localDate = LocalDate.of( 2020 , Month.SEPTEMBER , 30 ) ;
YearQuarter yearQuarter = YearQuarter.from( localDate ) ;
Move to the next quarter by adding one quarter to our current year-quarter.
The java.time and ThreeTen-Extra classes use immutable objects. So rather than alter ("mutate") the original object, when adding we produce a new object.
YearQuarter followingYearQuarter = yearQuarter.plusQuarters( 1 ) ;
Determine the last day of that quarter.
LocalDate lastDateOfFollowingYearQuarter = followingYearQuarter.atEndOfQuarter() ;
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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, Java SE 11, and later - 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
Most 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.
Here is my version (hopefully more readable) of finding the last day of next quarter for any date:
public LocalDate lastDayOfNextQuarter(LocalDate date) {
Month firstMonthOfCurrentQuarter = date.getMonth().firstMonthOfQuarter();
LocalDate lastMonthOfCurrentQuarter = date.with(firstMonthOfCurrentQuarter.plus(2));
LocalDate lastMonthOfNextQuarter = lastMonthOfCurrentQuarter.plusMonths(3);
return lastMonthOfNextQuarter.with(lastDayOfMonth());
}
And a corresponding test method:
#ParameterizedTest
#CsvSource({"2020-01-01,2020-06-30", "2020-02-01,2020-06-30", "2020-03-01,2020-06-30", "2020-04-10,2020-09-30",
"2020-05-10,2020-09-30", "2020-06-10,2020-09-30", "2020-07-20,2020-12-31", "2020-08-20,2020-12-31",
"2020-09-30,2020-12-31", "2020-10-30,2021-03-31", "2020-11-30,2021-03-31", "2020-12-31,2021-03-31"})
public void testLastDayOfNextQuarter(LocalDate input, LocalDate expected) {
LocalDate result = timeUtils.lastDayOfNextQuarter(input);
assertEquals(expected, result);
}
You can manipulate quarter easily with TemporalAdjusters. See below:
LocalDate localDate = LocalDate.now();
LocalDate firstDayOfQuarter = localDate.with(IsoFields.DAY_OF_QUARTER, 1);
System.out.println(firstDayOfQuarter);
LocalDate lastDayOfQuarter = firstDayOfQuarter.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth());
System.out.println(lastDayOfQuarter);
LocalDate firstDateOfNextQuarter = lastDayOfQuarter.plusDays(1);
LocalDate lastDayOfNextQuarter = firstDateOfNextQuarter.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth());
System.out.println(lastDayOfNextQuarter);
Output:
2020-01-01
2020-03-31
2020-06-30
You can use a Calendar instance to get the last day of the month.
String str = "30-12-20";
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yy");
Date date = format.parse(str);
Date newDate = DateUtils.addMonths(date, 3);
Calendar cal = new GregorianCalendar();
cal.setTime(newDate);
System.out.println(cal.getActualMaximum(Calendar.DAY_OF_MONTH));
I have a requirement to show a list of dates between the start and end dates in my app. I have a list of checkboxes which have the days of the week beside them ie; Monday to Sunday and two date pickers which helps the user to select a start and end date. If a user doesn't select any checkbox containing the days of the week, I need to display all the dates alongwith the days of the week coming in between the start and end date. If a user selects some checkboxes ie; Monday, Wednesday, Friday I need to show only those dates and days of the week between the start and end date. Could you please let me know if there is any way in which this can be achieved?
Thank you.
This can give you a list of the dates between two dates
List<Calendar> datelist = new ArrayList<Calendar>();
Calendar cStart = Calendar.getInstance();
cStart.set(2014, 04, 01);
Calendar cEnd = Calendar.getInstance();
cEnd.set(2014, 05, 2);
while(cStart.compareTo(cEnd) < 1){
datelist.add(cStart);
cStart.add(Calendar.DAY_OF_MONTH, 1);
}
msg = String.valueOf(datelist.size());
java.time
The java.time classes supplant the troublesome old date-time classes bundled with earliest versions of Java.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
Define your start and stop dates. Then loop to populate your list of all possible dates.
LocalDate start = LocalDate( 2016 , 1 , 2 );
LocalDate stop = start.plusWeeks( 1 );
List<LocalDate> allDates = new ArrayList<>();
LocalDate ld = start ;
while( ld.isBefore( stop ) ) {
allDates.add( ld );
// Set up next loop.
ld = ld.plusDays( 1 );
}
DayOfWeek
The DayOfWeek enum defines objects to represent each of the seven days of the week, Monday-Sunday.
The EnumSet in Java is an extremely fast and low-memory implementation of Set to represent a collection of enum objects. As the user enables/disables the day-of-week checkboxes, redefine your EnumSet collection of DayOfWeek values.
for( DayOfWeek dow in DayOfWeek.values() ) {
if ( … ) { // if your checkbox is checked for this day-of-week
dows.add( dow );
}
}
Next, define a collection of dates from which we allow the user to choose. This collection backs the user-interface widget.
List<LocalDate> dates = new ArrayList<>();
Now loop all the possible dates, testing each one’s day-of-week against the user-selected days.
for( LocalDate localDate in allDates ) {
if( dows.contains( localDate.getDayOfWeek() ) ) {
dates.add( localDate );
}
}
Strings
To populate your user-interface widget, you will likely need Strings to represent the value of each LocalDate object. You can create such Strings with an explicit formatting pattern you define. But I suggest letting the DateTimeFormatter class localize automatically.
Locale l = Locale.CANADA_FRENCH; // Defines how to create the string: translation, abbreviation, punctuation, order-of-parts, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ).withLocale( l );
Loop your dates you want to present, generating a String for each one’s presentation.
String output = localDate.format( f );
Optimizing
I would expect there are some clever ways to optimize the code shown above. For example:
Rather than rebuild the EnumSet and look at each of the checkboxes, you could add or remove individual DayOfWeek objects for just the one single checkbox checked/unchecked by the user.
Rather than rebuild the days list on every user-interaction, you could probably scrounge up a List implementation that acts as a mask over the allDates list with a feature to include/exclude certain elements.
But test real-world performance before prematurely optimizing. I suspect that any savings in execution time would be insignificant.
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.
Joda-Time
Update: The Joda-Time project, now in maintenance mode, advises migration to java.time classes.
Write a loop using the Joda-Time library with its LocalDate (no time of day) class.
To get you started…
LocalDate start = new LocalDate( year, month, day );
LocalDate next = start.plusDays( 1 );
int dayOfWeek = next.getDayOfWeek();
if ( dayOfWeek == DateTimeConstants.MONDAY ) { // Add to list };
I trying to calculate a date window based on 3 days prior and after the current plus 30,60,90 days. I really don't no a correct way to do it with calendar this is besides this dirty way.
public static void main(String []args) throws ParseException {
Calendar cal = GregorianCalendar.getInstance();
System.out.println("Curent date is " + cal.getTime() + "\n");
int [] remainingPeriodArr = {30,60,90,180};
int [] expiredArr = {30,60,90};
for(int i = 0; i < remainingPeriodArr.length; i++) {
getSupportPeriod(remainingPeriodArr[i]);
}
for(int i = 0; i < expiredArr.length; i++) {
getSupportPeriod(expiredArr[i]);
}
}
public static void getSupportPeriod(int period) {
Calendar c1 = GregorianCalendar.getInstance();
c1.add(Calendar.DATE, -3);
c1.add(Calendar.DATE, period);
System.out.println( period + " days from prior window " + c1.getTime() + "\n");
Calendar c2 = GregorianCalendar.getInstance();
c2.add(Calendar.DATE, 3);
// Date d2 = c2.getTime();
c2.add(Calendar.DATE, period);
System.out.println( period+ " days in the future window " + c2.getTime() + "\n");
}
}
Barring the new JDK8 date library or Joda Time, the easiest is to work off the current time in milliseconds:
long now = System.currentTimeMilliseconds();
long threeDaysAgoMillis = now - (3 * 24 * 60 * 60 * 1000);
long nowPlus30Millis = now + (30 * 24 * 60 * 60 * 1000);
Date threeDaysAgo = new Date(threeDaysAgoMillis);
Date nowPlus30 = new Date(nowPlus30Millis);
If you're using JDK8, check out this tutorial. If you can use Joda time, look here.
If you go the old JDK way then be aware of following pitfalls:
A) Avoid inherited static methods in general, but use the concrete value object type.
Calendar c1 = GregorianCalendar.getInstance();
Better use:
GregorianCalendar c1 = new GregorianCalendar();
Why? If you are in Thailand you will not get the gregorian calendar with your approach by using a static Calendar-method on GregorianCalendar-class. Instead you get the buddhist calendar.
B) Use domain specific type dependent on your problem
Unfortunately GregorianCalendar is not a date-only type so it does not fit well your requirements for date arithmetic. And in old JDK there is no such type at all so you have to live with ugly work-arounds. In Java 8 you can use java.time.LocalDate, in JodaTime you can use org.joda.time.LocalDate. In my coming time library you can use net.time4j.PlainDate (first release still this month).
C) Otherwise try to mimic a plain date type
Using GregorianCalendar you need to zero out all time fields, that is:
gcal.set(year, month, dayOfMonth);
gcal.set(Calendar.HOUR_OF_DAY, 0);
gcal.set(Calendar.MINUTE, 0);
gcal.set(Calendar.SECOND, 0);
gcal.set(Calendar.MILLISECOND, 0);
Note that this approach is not perfect under some rare conditions related to time zone offset changes, but will probably be sufficient in US and Europe.
If you evaluate such calendar objects as result of addition operations like add(Calendar.DATE, period), you should only print its date part and ignore the time part - in most cases by selecting a date-only format according to your local or as ISO-8601-format (mostly limited to year, month, day-of-month).
If you compare such calendar objects then don't apply comparisons based on the method getTime(), but only by explicit extracting year, month and day-of-month (writing a specialized Comparator is a good idea).
D) Avoid self-made date/time-arithmetic, trust the library
Code like long nowPlus30Millis = now + (30 * 24 * 60 * 60 * 1000); will probably fail if you have a daylight-saving switch in the meantime. The add()-method of java.util.GregorianCalendar can take this in account, but in general not self-made arithmetic.
tl;dr
LocalDate.now().plusDays( 3 )
java.time
The modern approach uses 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.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
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(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Math
One way to add days is with the LocalDate::plusDays method. Similar for subtraction.
LocalDate later = ld.plusDays( 3 ) ;
LocalDate earlier = ld.minusDays( 3 ) ;
Or, use objects to represent the span-of-time to be added or subtracted. This has the advantage of being able to label your span-of-time with variable name. For years-months-days, use Period. For hours-minutes-seconds, use Duration.
Period periodBookIsLate = Period.ofDays( 3 ) ;
LocalDate dueDate = ld.plus( periodBookIsLate ) ;
LocalDateRange
You may find the LocalDateRange class useful, available from the ThreeTen-Extra project.
LocalDateRange thirtyDayRange = LocalDateRange.of( ld.minusDays( 30 ) , ld.plusDays( 30 ) ) ;
Learn about the handy methods in that class such as abuts, contains, intersection, and more.
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.
AIM: I would like to get the last day of the week (Sunday) for the next 12 weeks into seperate Strings using Date()
I have the below which gives me the correct date format. I just need suggestions on the best solution to achieve my goal.
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date date = new Date(0);
System.out.println(dateFormat.format(date));
Java's date system baffles me, but I think you want to do this:
1) Instead of making a Date, make a GregorianCalendar.
2) Calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY) to get the date for the sunday of this week.
3) In a for loop, add 7 days to the calendar twelve times. Do something on each loop (For instance, use getTime() to get a Date from the GregorianCalendar)
try
GregorianCalendar c = new GregorianCalendar();
for (int i = 0; i < 12;) {
c.add(Calendar.DATE, 1);
if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
System.out.println(DateFormat.getDateInstance().format(c.getTime()));
i++;
}
}
Firstly, the last of the week is not always the same as Sunday since it is depending on which Locale you are using.
If you are using Java 8, the solution is pretty straightforward:
LocalDate firstJanuary = LocalDate.parse("01/01/2015",
DateTimeFormatter.ofPattern("MM/dd/yyyy"));
//last day of the week
TemporalField fieldUS = WeekFields.of(Locale.US).dayOfWeek();
LocalDate lastDayOfWeek = firstJanuary.with(fieldUS,7);
System.out.println(lastDayOfWeek);
//sunday
LocalDate sunday = firstJanuary.with(DayOfWeek.SUNDAY);
System.out.println(sunday);
and to iterate to the weeks after, simply use:
sunday.plusWeeks(1);
tl;dr
LocalDate.now(
ZoneId.of( "Africa/Tunis" )
)
.withNextOrSame( DayOfWeek.SUNDAY )
.plusWeeks( 1 )
java.time
The modern approach uses the java.time classes.
Today
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 pseudo-zones such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate today = LocalDate.now( z );
Day of week
To find the next Sunday on or after today, use a TemporalAdjuster implementation found in the TemporalAdjusters class.
LocalDate nextOrSameSunday = today.withNextOrSame( DayOfWeek.SUNDAY ) ;
Collection
Collect a dozen such sequential dates.
int countWeeks = 12 ;
List< LocalDate > sundays = new ArrayList<>( 12 ) ;
for( int i = 0 , i < countWeeks , i ++ ) {
sundays.add( nextOrSameSunday.plusWeeks( i ) ) ; // + 0, + 1, + 2, … , + 11.
}
Tip: Focus on working with representative data objects rather than mere Strings. When needed for display, loop your collection and generate strings with a call to toString or format( DateTimeFormatter ).
for( LocalDate ld : sundays ) { // Loop each LocalDate in collection.
String output = ld.toString() ; // Generate a string in standard ISO 8601 format.
…
}
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.
I am trying to create a method in Java that returns true if the current time of day is between a set interval (startTime and endTime).
The date is irrelevant. What is the best way to do this?
Here is my attempt it doesn't work:
public boolean isNowBetweenDateTime()
{
final Date now = new Date();
return now.after(startTime) && now.before(endTime);
}
What is the best way (in java) to check if time is within two Date objects, ignoring year, month day?
Your code looks good. Just set the date of now, startTime and endTime to some hard coded value.
tl;dr
Interval.of( start.toInstant() , stop.toInstant() ).contains( Instant.now() )
Half-Open
In date-time handling, the Half-Open approach is commonly used for defining a span of time. The beginning is inclusive while the ending is exclusive. So a week is defined as starting at the first moment of a Monday and running up to, but not including, the first moment of the following Monday. We sometimes use this Half-Open approach intuitively, where a lunch period of 12 to 1 means start at the stroke of noon but be back at your job or class before the clock strikes 1 PM. Using Half-Open consistently throughout your date-time work will make the logic and programming cleaner, clearer, and simpler.
So your logic should be, “Is now not before beginning AND now is before ending”. Notice that “not before” is a compact way of saying “is equal to OR is after”.
boolean isNowBetweenDateTime = ( ! now.before(startTime) ) && now.before(endTime) ; // Not before start AND is before stop.
ZonedDateTime
The Question and other Answers use troublesome old legacy date-time classes now supplanted by the java.time classes.
The ZonedDateTime class represents a moment on the timeline with an assigned time zone.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( z );
ZonedDateTime start = now.minusWeeks( 1 ); // Simulating input.
ZonedDateTime stop = now.plusWeeks( 2 ); // Simulating input.
You could write the logic yourself to test if now is between.
Boolean isBetween = ( ! now.isBefore( start ) ) && stop.isBefore( stop );
Interval
If doing more of this kind of work, look at the ThreeTen-Extra project. This library extends the java.time classes with additional functionality. Specifically the Interval class will be helpful, representing a pair of moments on the timeline. Implements a variety of comparison methods such as contains, encloses, abuts, and overlaps.
Instantiate a Interval with a pair of Instant objects. Instant represents a moment on the timeline in UTC. We can extract an Instant object from each ZonedDateTime object.
Interval interval = Interval.of( start.toInstant() , stop.toInstant() );
Boolean isBetween = interval.contains( now.toInstant() ); // Or pass `Instant.now()`.
You can also get the current moment as an Instant with a call to Instant.now().
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.
First of all, I would recommend to use Calendar instead of Date. I had some problems before, using date.
And I would use the time in milliseconds to compare dates, this is the safest way. The code wuoul be sth like:
Date now = new Date();
long startTimeInMillis = startTime.getTime();
long endTimeInMillis = endTime.getTime();
return now.getTime >= startTimeInMillis && now.getTime < endTimeInMillis;
If you want to ignore the Date and only consider the time of day, consider using Joda-Time's LocalTime, which is designed specifically to hold only the time portion.
Here is an example:
java.util.Date startTime = ... ;
java.util.Date endTime = ... ;
public boolean isNowBetweenDateTime()
{
// get current time
final LocalTime now = new LocalTime();
// convert the java.util.Dates to LocalTimes and then compare
return now.isAfter(LocalTime.fromDateFields(startTime)) &&
now.isBefore(LocalTime.fromDateFields(endTime));
}
This java function returns true if the current time is between two other times. It ignores the year/month/day.
import java.text.*;
import java.util.Date;
public static boolean isNowBetweenHours() throws ParseException
{
String leftBoundaryHours = "01:00:00"; //01:00 hours, military time.(1AM)
String rightBoundaryHours = "14:00:00"; //14:00 hours, military time.(2PM)
//returns true if current time is between
//leftBoundaryHours and rightBoundaryHours.
//This formatter converts a bare string to a date.
DateFormat formatter = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
//add the hand specified time to 1970-01-01 to create left/right boundaries.
Date leftTimeBoundary = formatter.parse("1970-01-01 " + leftBoundaryHours);
Date rightTimeBoundary = formatter.parse("1970-01-01 " + rightBoundaryHours);
//extract only the hours, minutes and seconds from the current Date.
DateFormat extract_time_formatter = new SimpleDateFormat("HH:mm:ss");
//Get the current time, put that into a string, add the 1970-01-01,
Date now = formatter.parse("1970-01-01 " +
extract_time_formatter.format(new Date()));
//So it is easy now, with the year, month and day forced as 1970-01-01
//all you do is make sure now is after left, and now is before right.
if (now.after(leftTimeBoundary) && now.before(rightTimeBoundary))
return true;
else
return false;
}
Invoke the function like this:
try {
System.out.println(isNowBetweenHours());
} catch (ParseException e) {
}
If the current time is after 01:00 hours but before 14:00 hours, it returns true. Else it returns false.