How to check a time period is overlapping another time period in the same day.
For example,
7:00AM to 10:30AM is overlapping 10:00AM to 11:30AM
7:00AM to 10:30AM is overlapping 8:00AM to 9:00AM
7:00AM to 10:30AM is overlapping 5:00AM to 8:00AM
There is a simple solution, expressed here as a utility method:
public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
return start1.before(end2) && start2.before(end1);
}
This code requires there to be at least one millisecond to be shared between the two periods to return true.
If abutting time periods are considered to "overlap" (eg 10:00-10:30 and 10:30-11:00) the logic needs to be tweaked ever so slightly:
public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
return !start1.after(end2) && !start2.after(end1);
}
This logic more often comes up in database queries, but the same approach applies in any context.
Once you realise just how simple it is, you at first kick yourself, then you put it in the bank!
tl;dr
( startA.isBefore( stopB ) ) && ( stopA.isAfter( startB ) )
LocalTime
If you really want to work with a generic time-of-day without the context of a date and time zone, use the LocalTime class.
LocalTime startA = LocalTime.of( 7 , 0 );
LocalTime stopA = LocalTime.of( 10 , 30 );
LocalTime startB = LocalTime.of( 10 , 0 );
LocalTime stop2B = LocalTime.of( 11 , 30 );
Validate the data, being sure the ending is after the beginning (or equal). A briefer way of saying that is “beginning is not after ending”.
Boolean validA = ( ! startA.isAfter( stopA ) ) ;
Boolean validB = ( ! startB.isAfter( stop2B ) ) ;
Per this Answer by Meno Hochschild, using the Half-Open approach to defining a span of time where the beginning is inclusive while the ending is exclusive, we can use this logic:
(StartA < EndB) and (EndA > StartB)
Boolean overlaps = (
( startA.isBefore( stopB ) )
&&
( stopA.isAfter( startB ) )
) ;
Note that LocalTime is constrained to a single generic 24-hour day. The times cannot go past midnight, cannot wrap around into another. There are no other days to consider. Validate your inputs to verify the beginning time comes before the end, or they are equal (if that suits your business rules).
if( stopA.isBefore( startA ) ) { … handle error }
if( stopB.isBefore( startB ) ) { … handle error }
ZonedDateTime
If you want to test actual moments on the timeline, you must adjust these time-of-day objects into the context of dates and a time zone. Apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
ZonedDateTime zdt = ZonedDateTime.of( today , startA , z);
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.
If interval is opened (for example, some process is not finished yet) and end date might be null:
public static boolean isOverlapping(Date start1, Date end1, Date start2, Date end2)
{
return
((null == end2) || start1.before(end2)) &&
((null == end1) || start2.before(end1)) ;
}
JOda Time has this functionality baked in. It's very well-built and on JSR route to replace the broken Java Calendar API. You should probably considering using it.
EDIT:
Here is the working method:
public boolean isOverlapping(Date start1, Date end1, Date start2, Date end2) {
return start1.compareTo(end2) <= 0 && end1.compareTo(start2) >= 0;
}
And here is proof for everyone to try it:
#Test
public void isOverlapping_base() {
Assert.assertTrue(isOverlapping(getDate(2014, 1, 1),
getDate(2014, 3, 31), getDate(2014, 1, 2),
getDate(2014, 4, 1)));
Assert.assertTrue(isOverlapping(getDate(2014, 1, 2),
getDate(2014, 4, 1), getDate(2014, 1, 1),
getDate(2014, 3, 31)));
Assert.assertTrue(isOverlapping(getDate(2014, 1, 1),
getDate(2014, 4, 1), getDate(2014, 1, 2),
getDate(2014, 3, 31)));
Assert.assertTrue(isOverlapping(getDate(2014, 1, 2),
getDate(2014, 3, 31), getDate(2014, 1, 1),
getDate(2014, 4, 1)));
Assert.assertFalse(isOverlapping(getDate(2014, 1, 1),
getDate(2014, 1, 31), getDate(2014, 3, 1),
getDate(2014, 3, 31)));
Assert.assertFalse(isOverlapping(getDate(2014, 3, 1),
getDate(2014, 3, 31), getDate(2014, 1, 1),
getDate(2014, 1, 31)));
}
Date getDate(int year, int month, int date) {
Calendar working = Calendar.getInstance();
working.set(year, month - 1, date, 0, 0, 0);
working.set(Calendar.MILLISECOND, 0);
return working.getTime();
}
Related
I am new to Java and I already have c# code which I have to convert it into java, but am not able to find good alternative to it.
Below is the code that I want to convert:
private string GetDate(object value)
{
DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var lastWeek = DateTime.Today.AddDays(-6);
var date = start.AddMilliseconds((long)value).ToLocalTime();
if (date >= lastWeek)
{
if (date.DayOfWeek == DateTime.Now.DayOfWeek)
return "Today";
else
return date.DayOfWeek.ToString();
}
else
return date.ToString("dd-MM-yyy");
}
I tried using Calendar class at first, but it's giving error that integer number too large:
Calendar cal = Calendar.getInstance();
cal.set(1970, 0, 1, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
long result = cal.getTimeInMillis();
long value = result + 1406205185123;
Any solution/suggestion will be helpful.
I haven't checked if it satisfies all your requirements regarding the output, but I think it will give enough pointers to help you out. Depending on your needs you need a ZonedDateTime (which has a timezone), or a LocalDateTime, which is the date as people speak about it in a country.
private String getDate(long value) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime start = LocalDateTime.of(1970, 1, 1, 0, 0, 0, 0);
LocalDateTime lastWeek = now.minusDays(6);
LocalDateTime date = start.plus(value, ChronoUnit.MILLIS);
if (lastWeek.isBefore(date)) {
DayOfWeek dayOfWeek = date.getDayOfWeek();
if (dayOfWeek == now.getDayOfWeek()) {
return "Today";
} else {
return dayOfWeek.name();
}
}
return date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT));
}
I've also took the liberty to convert the code style to what is usual in Java, which is the placing of the opening brace, the capitalization of functions.
More on the date/time classes can be found in the Oracle Trail on date/time.
tl;dr
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ; // The time zone of your business context.
LocalDate input = Instant.ofEpochMilli( yourMillis ).atZone( z ).toLocalDate() ;
LocalDate today = LocalDate.now( z ) ;
LocalDate weekAgo = today.minusDays( 6 ) ;
if ( input.isAfter( today ) ) { … error }
else if ( input.isEqual( today ) ) { return "Today" ; }
else if ( ! input.isBefore( weekAgo ) ) { return input.getDayOfWeek().getDisplayName( TextStyle.FULL , Locale.US ) ; }
else if ( input.isBefore( weekAgo ) ) { return input.format( DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) ) ; }
else { … error, unreachable point }
Details
DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
Instead, for a point on the timeline in UTC, use 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).
Your example of first moment of 1970 UTC happens to be the epoch reference used by the java.time framework. And it happens to be defined as a constant.
Instant start = Instant.EPOCH ;
Add your count of milliseconds.
Instant later = start.plusMillis( yourMillis ) ;
But if your count of milliseconds is always a count since the epoch reference, then you can shorten that code above.
Instant instantInput = Instant.ofEpochMilli( yourMillis ) ; // Determine a moment in UTC from a count of milliseconds since 1970-01-01T00:00Z.
Apparently your goal is to compare dates or day-of-week. Both of those require a time zone. You ignore this crucial issue in your Question. For any given moment, the date varies around the globe by zone. At this moment right now is Monday in the United States, but in New Zealand it is “tomorrow” Tuesday.
Apply a ZoneId to get a ZonedDateTime. Same moment, same point on the timeline, but seen through the wall-clock time used by the people of a particular region (a time zone).
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtInput = instantInput.atZone( z ) ;
Extract the date-only, without a time-of-day and without a time zone.
LocalDate ldInput = zdtInput.toLocalDate() ;
Extract the day-of-week, represented by the DayOfWeek enum.
DayOfWeek dowInput = ldInput.getDayOfWeek() ;
Subtract six days from now. Represent the six days as TemporalAmount, either six calendar days in a Period or six chunks of 24-hours as a Duration.
Period sixDays = Period.ofDays( 6 ) ;
LocalDate today = LocalDate.now( z ) ;
LocalDate sixDaysBeforeToday = today.minus( sixDays ); // Or LocalDate.now( z ).plusDays( 6 )
Compare. Let's simplify your branching logic. We will work chronologically in reverse order through five cases: future, today, past six days, prior, impossible.
if( ldInput.ifAfter( today ) ) {
System.out.println( "ERROR - input is in the future. Not expected." ) ;
} else if( ldInput.isEqual( today ) ) {
return "Today" ;
} else if ( ! ldInput.isBefore( sixDaysBeforeToday ) ) { // A shorter way of asking "is equal to OR later" is asking "is NOT before".
return dowInput.getDisplayName( TextStyle.FULL , Locale.US ) ; // Let java.time localize the name of the day-of-week.
} else if ( ldInput.isBefore ( sixDaysBeforeToday ) ) {
return ldInput.format( DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) ) ;
} else {
System.out.println( "ERROR - Reached impossible point." ) ; // Defensive programming.
}
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I would like to create a DateHelper class and for that I'm using DateUtils from Apache Commons Lang 2.6.
I'm having problems understanding the result returned when extract field from a date. Here is my test class which extract the day of month after truncate the date :
public class DateTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// Date date = createDate(2000, 1, 2, 3, 4, 5, 6);
Calendar calendar = createEmptyUTCCalendar();
calendar.set(Calendar.YEAR, 2000);
calendar.set(Calendar.MONTH, 0); // january
calendar.set(Calendar.DAY_OF_MONTH, 2);
calendar.set(Calendar.HOUR_OF_DAY, 3);
calendar.set(Calendar.MINUTE, 4);
calendar.set(Calendar.SECOND, 5);
calendar.set(Calendar.MILLISECOND, 6);
Date date = calendar.getTime();
System.out.println("Input date\n" + date);
// Truncate from day of month.
Date dateTruncate = getDatePart(date);
System.out.println("Truncate the date\n" + dateTruncate);
System.out.println("\n*** Extract day of month ***");
// Extract the field day of month from the truncated date.
int fieldDayOfMonth = getField(dateTruncate, Calendar.DAY_OF_MONTH);
System.out.println("Expected result is 2\nActual result is " + fieldDayOfMonth);
assert fieldDayOfMonth == 2;
}
public static int getField(Date date, int calendarField) {
Calendar calendar = createEmptyUTCCalendar();
calendar.setTime(date);
int value = calendar.get(calendarField);
if (calendarField == Calendar.MONTH) {
value++;
}
return value;
}
public static Date getDatePart(Date date) {
return DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
}
private static Calendar createEmptyUTCCalendar() {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
return calendar;
}
}
I expect the result of extracting the field Calendar.DAY_OF_MONTH to be 2 but I got 1.
Input date
Sun Jan 02 04:04:05 CET 2000
Truncate the date
Sun Jan 02 00:00:00 CET 2000
*** Extract day of month ***
Expected result is 2
Actual result is 1
tl;dr
LocalDate.of( 2000 , Month.JANUARY , 2 )
.getDayOfMonth()
2
java.time
You can just use Java now, no need for Apache DateUtils. And truncation is the wrong way to think about it; just interrogate for the day-of-month property.
Specify your date using LocalDate class. Note that java.time uses sane month numbering, 1-12 for January to December.
LocalDate ld = LocalDate.of( 2000 , 1 , 2 ) ; // January 2, 2000.
Or use the Month enum.
LocalDate ld = LocalDate.of( 2000 , Month.JANUARY , 2 ) ; // January 2, 2000.
2000-01-02
Interrogate for day-of-month. You can call getDayOfMonth on a LocalDate, OffsetDateTime, and ZonedDateTime.
int dayOfMonth = ld.getDayOfMonth() ;
2
If receiving a Calendar object, it is likely a GregorianCalendar. If so, you can easily convert to java.time classes.
if( myCalendar instanceOf GregorianCalendar ) {
GregorianCalendar gc = ( GregorianCalendar ) myCalendar ; // Cast.
ZonedDateTime zdt = gc.toZonedDateTime() ; // Convert from legacy class to modern class.
int dayOfMonth = zdt.getDayOfMonth() ;
}
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.
It seems that the thing is on the timezones. Your calendar is on UTC and your date on your local zone, if you avoid the line:
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
the thing should work.
When you pass calendar to Date, the date object gets default time zone CET in your case. Then you truncate and pass again to a UTC calendar, and due to the diffenrence between CET and UTC you day is the previous one.
My input is a beginning date and an end date. And I want to check that it is between December 1 and March 31. (The year can change, and there will be only dates in, or dates outside this period).
So far I didn't found any solution with Joda-time. Can somebody give me a starting point how to do(not code, just the logic)?
I didn't checked the code yet, but it is VERY Ugly, and I want to find an algorithmic solution
public static boolean isInWinter(Contract contract) {
logger.info("begin isInWinter:");
DateTime beginDate = contract.getBeginningDate();
DateTime endDate = contract.getEndDate();
/*
* If the year is different (etc 2012 dec,2013 marc) check that the
* beginning month is december, and the end month is jan,feb,marc
*/
if (endDate.getYear() - beginDate.getYear() == 1) {
if ((beginDate.getMonthOfYear() == 12)
&& ((endDate.getMonthOfYear() == 1
|| endDate.getMonthOfYear() == 2 || endDate
.getMonthOfYear() == 3))) {
logger.info("return true different year");
return true;
}
/*
* Same year can be if begin and end date is december or begin and
* and date is jan,febr,marc TODO REMOVE Auto formatter
*/
} else if (endDate.getYear() - beginDate.getYear() == 0) {
if ((beginDate.getMonthOfYear() == 12 && endDate.getMonthOfYear() == 12)
|| ((beginDate.getMonthOfYear() == 1
|| beginDate.getMonthOfYear() == 2 || beginDate
.getMonthOfYear() == 3) && (endDate
.getMonthOfYear() == 1
|| endDate.getMonthOfYear() == 2 || endDate
.getMonthOfYear() == 3))) {
logger.info("return true same year");
return true;
}
}
logger.info("return false");
return false;
}
Joda-Time
Joda-Time and its Interval class with the overlap method is just what you need. Very easy.
Time Zone
Unlike java.util.Date, a DateTime truly knows its assigned time zone. Generally better to specify than rely on default. Note that if you are tracking date+time (a DateTime rather than a LocalDate), then time zone is critical. The definition of a "day" beginning and ending depends on time zone. Businesses that work across time zones may choose to use UTC for this purpose.
Span of Time
FYI, besides Interval, Joda-Time also offers the Period and Duration classes for working with a span of time.
Start of Day
When working with date-time values but focusing on a "day", then adjust the time portion to the first moment of the day for that particular time zone. In Joda-Time, simply call the withTimeAtStartOfDay method.
Avoid the "midnight"-related classes and methods. They are no longer recommended by the Joda-Time team.
Half-Open
Joda-Time uses the "Half-Open" approach when comparing spans of time. The beginning in inclusive and the ending is exclusive. That means since you want from December 1 to March 31 that we define an Interval of the first moment of the day of December 1 to the first moment of the day of April 1. If you ponder this, and search StackOverflow for other postings on "joda interval", you'll come to see the wisdom of this approach.
Comparison
The Interval class offers handy comparison methods: contains, abuts, overlap, and gap. Be sure to read the doc to understand exact details.
java.time
Java 8 brings the new java.time package, inspired by Joda-Time, defined by JSR 310. Joda-Time continues to work in Java 8, but you may want to learn java.time rather than Joda-Time if you are new to date-time work.
Example Code
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Budapest" ); // Or, perhaps DateTimeZone.UTC
// Inputs
DateTime contractStart = new DateTime( 2014, 1, 2, 0, 0, 0, timeZone );
DateTime contractStop = new DateTime( 2014, 5, 6, 0, 0, 0, timeZone );
Interval contractInterval = new Interval( contractStart, contractStop );
// Target to test
DateTime targetStart = new DateTime( 2013, DateTimeConstants.DECEMBER, 1, 0, 0, 0, timeZone );
DateTime targetStop = targetStart.plusMonths( 4 );
Interval targetInterval = new Interval( targetStart, targetStop );
boolean targetContainsContract = targetInterval.contains( contractInterval );
boolean targetOverlapsContract = ( targetInterval.overlap( contractInterval ) != null );
Dump to console…
System.out.println( "contractInterval: " + contractInterval );
System.out.println( "targetInterval: " + targetInterval );
System.out.println( "targetContainsContract: " + targetContainsContract );
System.out.println( "targetOverlapsContract: " + targetOverlapsContract );
When run…
contractInterval: 2014-01-02T00:00:00.000+01:00/2014-05-06T00:00:00.000+02:00
targetInterval: 2013-12-01T00:00:00.000+01:00/2014-04-01T00:00:00.000+02:00
targetContainsContract: false
targetOverlapsContract: true
Create an interval with the beginning and end date you get as inputs.
Create an interval going from March to December.
Your condition is true if either:
the march to december interval entirely contains the input interval,
or there is no overlap between the two intervals.
In code that would be:
marchToDecember.contains(interval) || marchToDecember.overlap(interval) == null
Javadàoc for Interval
Since you mention that the dates will be either both in or both out the period, you'll only need to test one of them.
So just test whether beginDate.getMonthOfYear() returns either 12, 1, 2 or 3.
I am wondering how I would loop through a date/time or any type of variable to go from 00:00 to 24:00 every 30 Mins?
So I need a variable that shows times in 24HR format (01:00, 09:00) and every time I loop through it, to add 30 mins to the time? I then need to use this value in a string.
The time needs to start at 00:00AM and will end with 24:00.
Any ideas how should I go with it?
output should be like this - 00:00 00:30 01:00 ....24:00
Possibly a little over kill, but it does all the auto rolling and allows the use of DateFormat
DateFormat df = new SimpleDateFormat("HH:mm");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
int startDate = cal.get(Calendar.DATE);
while (cal.get(Calendar.DATE) == startDate) {
System.out.println(df.format(cal.getTime()));
cal.add(Calendar.MINUTE, 30);
}
You can't have 24:00 as it's 00:00...
Try to use this this code
private void displayTimeSlots() {
String timeValue = "T00:00:4.896+05:30";
SimpleDateFormat sdf = new SimpleDateFormat("'T'hh:mm:ss.SSS");
try {
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(sdf.parse(timeValue));
if (startCalendar.get(Calendar.MINUTE) < 30) {
startCalendar.set(Calendar.MINUTE, 30);
} else {
startCalendar.add(Calendar.MINUTE, 30); // overstep hour and clear minutes
startCalendar.clear(Calendar.MINUTE);
}
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(startCalendar.getTime());
// if you want dates for whole next day, uncomment next line
//endCalendar.add(Calendar.DAY_OF_YEAR, 1);
endCalendar.add(Calendar.HOUR_OF_DAY, 24 - startCalendar.get(Calendar.HOUR_OF_DAY));
endCalendar.clear(Calendar.MINUTE);
endCalendar.clear(Calendar.SECOND);
endCalendar.clear(Calendar.MILLISECOND);
SimpleDateFormat slotTime = new SimpleDateFormat("hh:mm a");
while (endCalendar.after(startCalendar)) {
startCalendar.add(Calendar.MINUTE, 30);
String Timeslots = slotTime.format(startCalendar.getTime());
Log.e("DATE", Timeslots);
}
} catch (ParseException e) {
// date in wrong format
}
}
tl;dr
myLocalTime.plusMinutes( gapInMinutes ) // Using `java.time.LocalTime` class.
Details
I am answering your Question as written, for a 24-hour day. But beware that days are not always that length. They may be 23, 25, or some other number of hours.
No such thing as 24:00 as that means rolling over to 00:00. So a duration of 30 minutes means ending at 23:30.
java.time
The modern approach uses the java.time classes that supplant the troublesome old date-time time classes.
LocalTime & Duration
The LocalTime class represents a time-of-day without date and without time zone. This class assumes a generic 24-hour day (unrealistic though that is).
The Duration class represents a span-of-time not attached to the timeline.
int gapInMinutes = 30 ; // Define your span-of-time.
int loops = ( (int) Duration.ofHours( 24 ).toMinutes() / gapInMinutes ) ;
List<LocalTime> times = new ArrayList<>( loops ) ;
LocalTime time = LocalTime.MIN ; // '00:00'
for( int i = 1 ; i <= loops ; i ++ ) {
times.add( time ) ;
// Set up next loop.
time = time.plusMinutes( gapInMinutes ) ;
}
System.out.println( times.size() + " time slots: " ) ;
System.out.println( times ) ;
See this code run live at IdeOne.com.
48 time slots:
[00:00, 00:30, 01:00, 01:30, 02:00, 02:30, 03:00, 03:30, 04:00, 04:30, 05:00, 05:30, 06:00, 06:30, 07:00, 07:30, 08:00, 08:30, 09:00, 09:30, 10:00, 10:30, 11:00, 11:30, 12:00, 12:30, 13:00, 13:30, 14:00, 14:30, 15:00, 15:30, 16:00, 16:30, 17:00, 17:30, 18:00, 18:30, 19:00, 19:30, 20:00, 20:30, 21:00, 21:30, 22:00, 22:30, 23:00, 23:30]
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.
try this -
Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("hh:mm:ss a").parse("00:00:00 AM"));
System.out.println(instance.getTime());
int i=1;
while(i++!=49){
instance.add(Calendar.MINUTE, 30);
System.out.println(instance.getTime());
}
How do I find the difference in Days between two Joda-Time DateTime instances?
With ‘difference in days’ I mean if start is on Monday and end is on Tuesday I expect a return value of 1 regardless of the hour/minute/seconds of the start and end dates.
Days.daysBetween(start, end).getDays() gives me 0 if start is in the evening and end in the morning.
I'm also having the same issue with other date fields so I was hoping there would be a generic way to 'ignore' the fields of lesser significance.
In other words, the months between Feb and 4 March would also be 1, as would the hours between 14:45 and 15:12 be. However the hour difference between 14:01 and 14:55 would be 0.
Annoyingly, the withTimeAtStartOfDay answer is wrong, but only occasionally. You want:
Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()
It turns out that "midnight/start of day" sometimes means 1am (daylight savings happen this way in some places), which Days.daysBetween doesn't handle properly.
// 5am on the 20th to 1pm on the 21st, October 2013, Brazil
DateTimeZone BRAZIL = DateTimeZone.forID("America/Sao_Paulo");
DateTime start = new DateTime(2013, 10, 20, 5, 0, 0, BRAZIL);
DateTime end = new DateTime(2013, 10, 21, 13, 0, 0, BRAZIL);
System.out.println(daysBetween(start.withTimeAtStartOfDay(),
end.withTimeAtStartOfDay()).getDays());
// prints 0
System.out.println(daysBetween(start.toLocalDate(),
end.toLocalDate()).getDays());
// prints 1
Going via a LocalDate sidesteps the whole issue.
Days Class
Using the Days class with the withTimeAtStartOfDay method should work:
Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays()
you can use LocalDate:
Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays()
tl;dr
java.time.temporal.ChronoUnit.DAYS.between(
earlier.toLocalDate(),
later.toLocalDate()
)
…or…
java.time.temporal.ChronoUnit.HOURS.between(
earlier.truncatedTo( ChronoUnit.HOURS ) ,
later.truncatedTo( ChronoUnit.HOURS )
)
java.time
FYI, the Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
The equivalent of Joda-Time DateTime is ZonedDateTime.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
Apparently you want to count the days by dates, meaning you want to ignore the time of day. For example, starting a minute before midnight and ending a minute after midnight should result in a single day. For this behavior, extract a LocalDate from your ZonedDateTime. The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;
Use the ChronoUnit enum to calculate elapsed days or other units.
long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;
Truncate
As for you asking about a more general way to do this counting where you are interested the delta of hours as hour-of-the-clock rather than complete hours as spans-of-time of sixty minutes, use the truncatedTo method.
Here is your example of 14:45 to 15:12 on same day.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 14 , 45 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 17 , 15 , 12 , 0 , 0 , z );
long hours = ChronoUnit.HOURS.between( start.truncatedTo( ChronoUnit.HOURS ) , stop.truncatedTo( ChronoUnit.HOURS ) );
1
This does not work for days. Use toLocalDate() in this case.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
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.
The accepted answer builds two LocalDate objects, which are quite expensive if you are reading lot of data.
I use this:
public static int getDaysBetween(DateTime earlier, DateTime later)
{
return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis());
}
By calling getMillis() you use already existing variables.
MILLISECONDS.toDays() then, uses a simple arithmetic calculation, does not create any object.
java.time.Period
Use the java.time.Period class to count days.
Since Java 8 calculating the difference is more intuitive using LocalDate, LocalDateTime to represent the two dates
LocalDate now = LocalDate.now();
LocalDate inputDate = LocalDate.of(2018, 11, 28);
Period period = Period.between( inputDate, now);
int diff = period.getDays();
System.out.println("diff = " + diff);
(KOTLIN) For Difference between a constant date and current date (Joda)
You can use Days.daysBetween(jodaDate1,jodaDate2)
Here is an example:
val dateTime: DateTime = DateTime.parse("14/09/2020",
DateTimeFormat.forPattern("dd/MM/yyyy"))
val currentDate = DateTime.now()
//To calculate the days in between
val dayCount = Days.daysBetween(dateTime,currentDate).days
//Set Value to TextView
binding.daysCount.text = dayCount.toString()
DateTime dt = new DateTime(laterDate);
DateTime newDate = dt.minus( new DateTime ( previousDate ).getMillis());
System.out.println("No of days : " + newDate.getDayOfYear() - 1 );
public static int getDifferenceIndays(long timestamp1, long timestamp2) {
final int SECONDS = 60;
final int MINUTES = 60;
final int HOURS = 24;
final int MILLIES = 1000;
long temp;
if (timestamp1 < timestamp2) {
temp = timestamp1;
timestamp1 = timestamp2;
timestamp2 = temp;
}
Calendar startDate = Calendar.getInstance(TimeZone.getDefault());
Calendar endDate = Calendar.getInstance(TimeZone.getDefault());
endDate.setTimeInMillis(timestamp1);
startDate.setTimeInMillis(timestamp2);
if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) {
int day1 = endDate.get(Calendar.DAY_OF_MONTH);
int day2 = startDate.get(Calendar.DAY_OF_MONTH);
if (day1 == day2) {
return 0;
} else {
return 1;
}
}
int diffDays = 0;
startDate.add(Calendar.DAY_OF_MONTH, diffDays);
while (startDate.before(endDate)) {
startDate.add(Calendar.DAY_OF_MONTH, 1);
diffDays++;
}
return diffDays;
}