Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


MySQL Deadlock

A deadlock is a situation where different transactions are unable to proceed because each holds a lock that the other needs. Because both transactions are waiting for a resource to become available, neither ever release the locks it holds. A deadlock can occur when transactions lock rows in multiple tables (through statements such as  UPDATE  or  SELECT ... FOR
UPDATE
 ), but in the opposite order. A deadlock can also occur when such statements lock ranges of index records and gaps, with each transaction acquiring some locks but not others due to a timing issue.

To avoid deadlock

To reduce the possibility of deadlocks, use transactions rather than  LOCK TABLES  statements; keep transactions that insert or update data small enough that they do not stay open for long periods of time; when different transactions update multiple tables or large ranges of rows, use the same order of operations (such as  SELECT ... FOR
UPDATE
 ) in each transaction. Using both row-level locking and the TRANSACTION_READ_COMMITTED isolation level makes it likely that you will avoid deadlocks (both settings are Derby defaults). However, deadlocks are still possible.

Minimize and handle deadlocks

Deadlocks are a classic problem in transactional databases, but they are not dangerous unless they are so frequent that you cannot run certain transactions at all. Normally, you must write your applications so that they are always prepared to re-issue a transaction if it gets rolled back because of a deadlock.

InnoDB uses automatic row-level locking. You can get deadlocks even in the case of transactions that just insert or delete a single row. That is because these operations are not really “atomic”; they automatically set locks on the (possibly several) index records of the row inserted or deleted.

Keep transactions small and short in duration to make them less prone to collision.

Commit transactions immediately after making a set of related changes to make them less prone to collision. In particular, do not leave an interactive mysql session open for a long time with an uncommitted transaction.

When modifying multiple tables within a transaction, or different sets of rows in the same table, do those operations in a consistent order each time. Then transactions form well-defined queues and do not deadlock. For example, organize database operations into functions within your application, or call stored routines, rather than coding multiple similar sequences of INSERT, UPDATE, and DELETE statements in different places.

 

Deadlock detection

When a transaction waits more than a specific amount of time to obtain a lock (called the deadlock timeout), Derby can detect whether the transaction is involved in a deadlock.

When you configure your system for deadlock and lockwait timeouts and an application could be chosen as a victim when the transaction times out, you should program your application to handle them.

Run this command to show the latest deadlock

SHOW ENGINE INNODB STATUS ;

 

October 13, 2020

What is Docker?

What is docker?

Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Building and deploying new applications is faster with containers. Docker containers wrap up your application and everything it needs such as dependencies and libraries into one package. This guarantees that your application will always run the same way regardless of the environments(Mac, Linux, Unix, Windows, etc). If the docker engine is installed on the environment your application will work. By doing this, you the developer can rest assured that your application will run on your local, Dev, QA, and production environment.

In a way, Docker is like a virtual machine. a virtual machine creates a whole virtual operating system, a docker container uses the same underlying operating system (Linux kernel) as the server that it is running on. Docker only requires applications to be shipped with things not already running on the host server. This gives a significant performance boost and reduces the size of the application.

What is docker for?

Docker is designed to benefit both developers and system administrators, making it a part of many DevOps (developers + operations) toolchains. For developers, it means that they can focus on writing code without worrying about the system that it will ultimately be running on. It also allows them to get a head start by using one of the thousands of programs already designed to run in a Docker container as a part of their application. Things like MySQL, Redis Cache, and Messaging System(ActiveMQ) can be on their own containers and you run them together with your application.

Without docker containers, your application can behave differently in different environments. I have seen applications working on my local machine but not on my dev environment. One of the most frustrating things of deployment is when you have a working application on your local machine, but you deploy it to production and it does not work. Trust me I have seen this mess more than once. With Docker containers, you are confident that your applications will work on local, Dev, QA, and production.

 
October 11, 2020

Javascript Fundamentals Part 1

Javascript is case-sensitive

Everything in JavaScript including variables , function names,  class names, and operators are case-sensitive. It means that counter and Counter variables are different.

Comments

JavaScript supports both single-line (//) and block(/**/) comments.

// This is a single line comment

/*
* This is a multiple line 
* comment block
*/

Semicolon

Although JavaScript does not require to end a statement with a semicolon (;), it is recommended to always use the semicolon to end a statement which makes your code more readable.

var number1 = 1;
var number2 = 2;

Javascript variables

JavaScript variables are loosely typed which means that variables can hold values with any type of data. Variables are just placeholders for values.

To declare a variable, you use the var or let keyword followed by the variable name.

var pointer = "Welcome!";
point = 100;

Undefined and undeclared variables

An undefined variable is a variable that has been declared. Because we have not assigned it a value, the variable used the undefined as its initial value.

var undefinedMessage;

console.log(undefinedMessage); // undefined

An undeclared variable is the variable that has not been declared.

console.log(undeclaredVariable); // ReferenceError: undeclaredVariable is not defined

Global and local variables

In JavaScript, all variables exist within a scope that determines the lifetime of the variables and which part of the code can access them.

Local variables

Variables declared within a JavaScript function, become locally accessible to the function and only that function.

function sayHi(){
    //helloMsg is a local variable to the sayHi() function
    var helloMsg = "Welcome!";
    console.log("helloMsg: "+helloMsg);
}

sayHi();

console.log("helloMsg: "+helloMsg);//Uncaught ReferenceError: helloMsg is not defined

Global variables

A variable declared outside a function, becomes global which all functions on a web page can access it. 

/*
* Global variables
*/
var message = "Hello";
function sayHello() {
    // local variable
    message = 'Hi';
    console.log(message); // which message?
}
sayHello();// Hi
console.log(message); // Hi

If a local variable is not declared, Javascript will create it as a global variable.

But to avoid creating a global variable accidentally inside a function because of omitting the var keyword, you use the strict mode by adding the “use strict”; at the beginning of the JavaScript file (or the function). Note that by using “use strict” modern javascript will be enforced.

<script>
"use strict";
window.onload = function() {

}
</script>

Javascript Data Types

JavaScript has six primitive data types:

  1.  null
  2.  undefined
  3.  boolean
  4.  number
  5.  string
  6.  symbol – available only from ES6
  7. object

JavaScript has dynamic types. This means that the same variable can be used to hold different data types.

var x;           // Now x is undefined
x = 10;           // Now x is a Number
x = "Folau";      // Now x is a String

To get the current type of the value of a variable, you use the typeof operator.

let count = 120; // count is a number
console.log(typeof(count)); // "number"

count = false;   // count is now a boolean
console.log(typeof(count)); // "boolean"

count = "Hi";   // count is now a string
console.log(typeof(count)); // "string"

The null type

Javascript defines that null is an empty object pointer. It is a good practice to assign a variable that later holds an object to null so that you can check whether the object is null or not by using the if statement.

let obj = null;
console.log(typeof obj); // object

if(obj != null) {
   // call method of the object
}

The undefined type

The undefined type is a primitive type that has one value undefined. By default, when a variable is declared but not initialized, it is assigned the value undefined.

The number type

Variables that hold whole number values

var num = 100;
var dec = 2.5;

The boolean type

Variables that hold true or false

var isSafe = true;

The NAN type

JavaScript has a special numeric value called NAN, which stands for Not a Number. In fact, it means an invalid number.

console.log('john'/2);//NaN;
console.log(NAN/2);//NAN
console.log(NAN==NAN);//false

The string type

In JavaScript, a string is a sequence of zero or more characters. A literal string begins and ends with either a single quote(‘) or double quote (“). A string that starts with a double quote must end with a double quote and a string that begins with a single quote must end with a single quote.

let greeting = 'Hi';
let s = "It's a valid string";
let str = 'I\'m also a string'; // use \ to escape the single quote (')

The object type

In JavaScript, an object is a collection of properties, where each property is defined as a key-value pair.

let user = {
    firstName: 'Folau',
    lastName: 'Kaveinga'
};

 

Null check with ??

The nullish coalescing operator is written as two question marks ??.

The result of a ?? b is:

  • if a is defined, then a,
  • if a isn’t defined, then b.
let collegeName;

console.log("collegeName: "+ (collegeName ?? "no collegeName"));//collegeName: no collegeName

collegeName = "BYU";
console.log("collegeName: ", collegeName ?? "no collegeName");// BYU

 

Source code on Github

October 10, 2020

Springboot Retry

Spring framework has a retry project that is very useful when you have a business logic failure that you want to be able to retry to complete.

 

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

 

@Configuration
@EnableRetry
public class GlobalConfig {

}

 

 

@Service
@Slf4j
public class UserServiceImp implements UserService {

    @Retryable(value = {RuntimeException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000))
    @Override
    public boolean sendEmail(User user) throws RuntimeException {
        log.info("send email");
        if (true) {
            throw new RuntimeException("error");
        }

        return false;
    }

    @Recover
    @Override
    public boolean recover(RuntimeException e, User user) {
        log.info("recover");
        return true;
    }

}

 

October 7, 2020

Java Date

LocalDate
LocalDate is a class in the Java 8 Date and Time API (java.time package) that represents a date without a time component and without a time zone. It represents a date in the ISO calendar system (year, month, day). Since it does not store time information, it is suitable for scenarios where you need to deal with dates only, such as birthdays, anniversaries, and other datebased operations.

Key methods of the LocalDate class:

  1. now(): Returns the current date based on the system clock and the default time zone.
  2. of(int year, int month, int dayOfMonth): Creates a LocalDate instance with the specified year, month, and day.
  3. parse(CharSequence text): Parses a text string in the format “yyyy-MM-dd” to create a LocalDate instance.
  4. getYear(), getMonth(), getDayOfMonth(): Get the year, month, and day components of the LocalDate.
  5. plusDays(long daysToAdd), plusMonths(long monthsToAdd), plusYears(long yearsToAdd): Add days, months, or years to the LocalDate and return a new instance.
  6. minusDays(long daysToSubtract), minusMonths(long monthsToSubtract), minusYears(long yearsToSubtract): Subtract days, months, or years from the LocalDate and return a new instance.
// Create a LocalDate for the current date
LocalDate currentDate = LocalDate.now();
System.out.println("Current Date: " + currentDate);

// Create a LocalDate with a specific date
LocalDate specificDate = LocalDate.of(2023, 7, 20);
System.out.println("Specific Date: " + specificDate);

// Parse a text string to create a LocalDate
// Parses a text string in the format "yyyy-MM-dd"
LocalDate parsedDate = LocalDate.parse("2023-07-20");
System.out.println("Parsed Date: " + parsedDate);

// Get individual components of the LocalDate
int year = specificDate.getYear();
int month = specificDate.getMonthValue();
int day = specificDate.getDayOfMonth();
System.out.println("Year: " + year + ", Month: " + month + ", Day: " + day);

// Add or subtract days, months, or years
LocalDate modifiedDate = specificDate.plusDays(5).minusMonths(1).plusYears(2);
System.out.println("Modified Date: " + modifiedDate);

// Check if a date comes before or after another date
LocalDate futureDate = LocalDate.of(2024, 1, 1);
if (futureDate.isAfter(specificDate)) {
    System.out.println("Future date is after specific date.");
} else {
    System.out.println("Future date is not after specific date.");
}

// Check if a date is in the past
LocalDate pastDate = LocalDate.of(2022, 1, 1);
if (pastDate.isBefore(currentDate)) {
    System.out.println("Past date is before current date.");
} else {
    System.out.println("Past date is not before current date.");
}

Output

Current Date: 2023-07-23
Specific Date: 2023-07-20
Parsed Date: 2023-07-20
Year: 2023, Month: 7, Day: 20
Modified Date: 2025-06-25
Future date is after specific date.
Past date is before current date.

LocalTime

LocalTime is a class in the Java 8 Date and Time API (java.time package) that represents a time of day without a date and time zone. It contains information about hours, minutes, seconds, and nanoseconds. LocalTime is useful when you need to handle time-specific operations, such as setting reminders, scheduling events, or measuring time durations without considering the date.

Key methods of the LocalTime class:

  1. now(): Returns the current time based on the system clock and the default time zone.
  2. of(int hour, int minute), of(int hour, int minute, int second), of(int hour, int minute, int second, int nanoOfSecond): Creates a LocalTime instance with the specified hour, minute, second, and nanosecond.
  3. parse(CharSequence text): Parses a text string in the format “HH:mm:ss” or “HH:mm:ss.SSSSSSSSS” to create a LocalTime instance.
  4. getHour(), getMinute(), getSecond(), getNano(): Get the hour, minute, second, and nanosecond components of the LocalTime.
  5. plusHours(long hoursToAdd), plusMinutes(long minutesToAdd), plusSeconds(long secondsToAdd), plusNanos(long nanosToAdd): Add hours, minutes, seconds, or nanoseconds to the LocalTime and return a new instance.
  6. minusHours(long hoursToSubtract), minusMinutes(long minutesToSubtract), minusSeconds(long secondsToSubtract), minusNanos(long nanosToSubtract): Subtract hours, minutes, seconds, or nanoseconds from the LocalTime and return a new instance.
// Create a LocalTime for the current time
LocalTime currentTime = LocalTime.now();
System.out.println("Current Time: " + currentTime);

// Create a LocalTime with a specific time
LocalTime specificTime = LocalTime.of(12, 34);
System.out.println("Specific Time: " + specificTime);

// Create a LocalTime with a specific time including seconds and nanoseconds
LocalTime specificTimeWithSeconds = LocalTime.of(12, 34, 56);
System.out.println("Specific Time with Seconds: " + specificTimeWithSeconds);

// Parse a text string to create a LocalTime
LocalTime parsedTime = LocalTime.parse("13:45:30");
System.out.println("Parsed Time: " + parsedTime);

// Get individual components of the LocalTime
int hour = specificTime.getHour();
int minute = specificTime.getMinute();
int second = specificTimeWithSeconds.getSecond();
System.out.println("Hour: " + hour + ", Minute: " + minute + ", Second: " + second);

// Add or subtract hours, minutes, seconds, or nanoseconds
LocalTime modifiedTime = specificTime.plusHours(2).minusMinutes(15).plusSeconds(30).plusNanos(500000000);
System.out.println("Modified Time: " + modifiedTime);

// Check if a time comes before or after another time
LocalTime futureTime = LocalTime.of(14, 0);
if (futureTime.isAfter(specificTime)) {
    System.out.println("Future time is after specific time.");
} else {
    System.out.println("Future time is not after specific time.");
}

// Check if a time is in the past
LocalTime pastTime = LocalTime.of(11, 0);
if (pastTime.isBefore(currentTime)) {
    System.out.println("Past time is before current time.");
} else {
    System.out.println("Past time is not before current time.");
}

Ouput

Current Time: 21:41:29.249370
Specific Time: 12:34
Specific Time with Seconds: 12:34:56
Parsed Time: 13:45:30
Hour: 12, Minute: 34, Second: 56
Modified Time: 14:19:30.500
Future time is after specific time.
Past time is before current time.

ZonedDateTime

ZonedDateTime is a class in the Java 8 Date and Time API (java.time package) that represents a date and time in a specific time zone. It combines the functionalities of LocalDateTime and ZoneId to represent an instant in time with the time zone information. It allows you to perform operations that consider both the local date and time and the time zone.

// Get the current date and time in a specific time zone
ZonedDateTime currentDateTime = ZonedDateTime.now(ZoneId.systemDefault());
System.out.println("Current Date and Time in New York: " + currentDateTime);

// Create a ZonedDateTime for a specific date and time in a specific time zone
ZonedDateTime specificDateTime = ZonedDateTime.of(2023, 7, 20, 12, 34, 56, 0, ZoneId.of("Asia/Tokyo"));
System.out.println("Specific Date and Time in Tokyo: " + specificDateTime);

// Convert a LocalDateTime to ZonedDateTime with a specified time zone
ZonedDateTime convertedDateTime = ZonedDateTime.of(LocalDateTime.now(), ZoneId.of("Europe/London"));
System.out.println("Converted Date and Time in London: " + convertedDateTime);

// Convert a ZonedDateTime to an OffsetDateTime
OffsetDateTime offsetDateTime = specificDateTime.toOffsetDateTime();
System.out.println("Offset Date and Time: " + offsetDateTime);

// Get the time zone information from a ZonedDateTime
ZoneId zoneId = specificDateTime.getZone();
System.out.println("Time Zone: " + zoneId);

// Check if a ZonedDateTime occurs before or after another ZonedDateTime
ZonedDateTime futureDateTime = specificDateTime.plusDays(1);
if (futureDateTime.isAfter(specificDateTime)) {
    System.out.println("Future date is after specific date.");
} else {
    System.out.println("Future date is not after specific date.");
}

Output

Current Date and Time in New York: 2023-07-23T21:44:31.318829-06:00[America/Denver]
Specific Date and Time in Tokyo: 2023-07-20T12:34:56+09:00[Asia/Tokyo]
Converted Date and Time in London: 2023-07-23T21:44:31.319092+01:00[Europe/London]
Offset Date and Time: 2023-07-20T12:34:56+09:00
Time Zone: Asia/Tokyo
Future date is after specific date.

Duration
Duration is a class in the java.time package that represents a time-based duration. It measures the amount of time between two points in time in terms of hours, minutes, seconds, and nanoseconds. Duration is primarily used to represent a duration between two instances of Instant, but it can also be used with LocalTime, LocalDateTime, or any other time-based object that supports nanosecond precision.

Key points about Duration:

  1. Duration is an immutable class, meaning once created, the value cannot be changed.
  2. It represents a time duration in seconds and nanoseconds.
  3. The Duration class provides various methods for arithmetic operations like addition, subtraction, and multiplication with a scalar value.
  4. You can use Duration.between(startInstant, endInstant) to calculate the duration between two Instant objects.
  5. Duration provides the toMinutes(), toHours(), toDays(), and other methods to convert the duration to different units.
// Create a Duration between two Instants
Instant start = Instant.now();
// Simulate some operation
try {
    Thread.sleep(2000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
Instant end = Instant.now();

Duration duration = Duration.between(start, end);
System.out.println("Duration in seconds: " + duration.getSeconds());
System.out.println("Duration in milliseconds: " + duration.toMillis());

// Add and subtract duration
Duration fiveMinutes = Duration.ofMinutes(5);
Instant futureInstant = end.plus(fiveMinutes);
Instant pastInstant = start.minus(fiveMinutes);
System.out.println("Future Instant: " + futureInstant);
System.out.println("Past Instant: " + pastInstant);

// Compare durations
Duration oneMinute = Duration.ofMinutes(1);
Duration twoMinutes = Duration.ofMinutes(2);
if (oneMinute.compareTo(twoMinutes) < 0) {
    System.out.println("One minute is less than two minutes.");
} else if (oneMinute.compareTo(twoMinutes) > 0) {
    System.out.println("One minute is greater than two minutes.");
} else {
    System.out.println("One minute is equal to two minutes.");
}

// Check if a duration is zero or negative
Duration zeroDuration = Duration.ZERO;
Duration negativeDuration = Duration.ofSeconds(-10);
System.out.println("Is zero duration? " + zeroDuration.isZero());
System.out.println("Is negative duration? " + negativeDuration.isNegative());

Output

Duration in seconds: 2
Duration in milliseconds: 2003
Future Instant: 2023-07-24T03:54:47.283713Z
Past Instant: 2023-07-24T03:44:45.280Z
One minute is less than two minutes.
Is zero duration? true
Is negative duration? true

Period
Period is a class in the java.time package that represents a date-based period between two dates. It measures the difference between two LocalDate instances in terms of years, months, and days. Period is useful when you need to deal with date-based durations, such as calculating the difference between two dates, representing a period of time, or adding/subtracting time units to a date.

Key points about Period:

  1. Period is an immutable class, meaning once created, the value cannot be changed.
  2. It represents a date-based duration in years, months, and days.
  3. The Period class provides various methods for arithmetic operations like addition, subtraction, and multiplication with a scalar value.
  4. You can use Period.between(startDate, endDate) to calculate the period between two LocalDate objects.
  5. Period provides the getYears(), getMonths(), getDays(), and other methods to access individual components of the period.
// Create a Period between two LocalDates
       LocalDate startDate = LocalDate.of(2023, 7, 1);
       LocalDate endDate = LocalDate.of(2023, 12, 31);

       Period period = Period.between(startDate, endDate);
       System.out.println("Period: " + period);
       System.out.println("Years: " + period.getYears());
       System.out.println("Months: " + period.getMonths());
       System.out.println("Days: " + period.getDays());

       // Add and subtract periods
       Period threeMonths = Period.ofMonths(3);
       LocalDate futureDate = endDate.plus(threeMonths);
       LocalDate pastDate = startDate.minus(threeMonths);
       System.out.println("Future Date: " + futureDate);
       System.out.println("Past Date: " + pastDate);

       // Check if a period is zero or negative
       Period zeroPeriod = Period.ZERO;
       Period negativePeriod = Period.ofYears(-1);
       
       System.out.println("Is zero period? " + zeroPeriod.isZero());
       System.out.println("Is negative period? " + negativePeriod.isNegative());

Output

Period: P5M30D
Years: 0
Months: 5
Days: 30
Future Date: 2024-03-31
Past Date: 2023-04-01
Is zero period? true
Is negative period? true

We demonstrated how to create and use Period objects. We calculated the period between two LocalDate objects using Period.between(), performed arithmetic operations like addition and subtraction, and compared two Period objects. We also checked if a period is zero or negative using the isZero() and isNegative() methods.

Period is a useful class when you need to work with date-based durations, and it can simplify date-related calculations and logic in your Java applications

The class Date epresents a specific instant in time, with millisecond precision.

After Method

Returns true if the invoking Date object contains a date that is later than the one specified by date, otherwise, it returns false.

Date today = DateUtils.addDays(new Date(), 0);
Date yesterday = DateUtils.addDays(new Date(), -1);

System.out.println("today - " + today.toInstant().toString());
System.out.println("yesterday - " + yesterday.toInstant().toString());
System.out.println("today.after(yesterday) - " + today.after(yesterday));
System.out.println("today.equals(yesterday) - " + today.equals(yesterday));
System.out.println("yesterday.after(today) - " + yesterday.after(today));

// Output
today - 2020-10-02T04:34:35.465Z
yesterday - 2020-10-01T04:34:35.480Z
today.after(yesterday) - true
today.equals(yesterday) - false
yesterday.after(today) - false

 

Before Method

Returns true if the invoking Date object contains a date that is earlier than the one specified by date, otherwise, it returns false.

Date today = DateUtils.addDays(new Date(), 0);
Date yesterday = DateUtils.addDays(new Date(), -1);

System.out.println("today - " + today.toInstant().toString());
System.out.println("yesterday - " + yesterday.toInstant().toString());

System.out.println("today.before(yesterday) - " + today.before(yesterday));
System.out.println("today.equals(yesterday) - " + today.equals(yesterday));
System.out.println("yesterday.before(today) - " + yesterday.before(today));

// output
today - 2020-10-02T15:48:24.823Z
yesterday - 2020-10-01T15:48:24.837Z
today.before(yesterday) - false
today.equals(yesterday) - false
yesterday.before(today) - true

 

Check if same two dates are the same day

/**
 * Check if day1 is the same day as day2<br/>
 * day1 - 2020-6-12, day2 - 2020-6-13, return false <br/>
 * day1 - 2020-6-12, day2 - 2020-6-12, return false <br/>
 * day1 - 2020-6-13, day2 - 2020-6-12, return false <br/>
 */
public static boolean isSameDay(Date day1, Date day2) {
    if (day1 == null || day2 == null) {
        return false;
    }
    final Calendar cal1 = Calendar.getInstance();
    cal1.setTime(day1);
    final Calendar cal2 = Calendar.getInstance();
    cal2.setTime(day2);

    return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
            && cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);
}

 

Check if day1 is after day2

/**
 * Check if day1 is after day2<br/>
 * day1 - 2020-6-12, day2 - 2020-6-13, return false <br/>
 * day1 - 2020-6-12, day2 - 2020-6-12, return false <br/>
 * day1 - 2020-6-13, day2 - 2020-6-12, return true <br/>
 */
public static boolean isAfterDay(Date day1, Date day2) {
    if (day1 == null || day2 == null) {
        return false;
    }
    final Calendar cal1 = Calendar.getInstance();
    cal1.setTime(day1);
    final Calendar cal2 = Calendar.getInstance();
    cal2.setTime(day2);

    if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) {
        return false;
    } else if (cal1.get(Calendar.MONTH) < cal2.get(Calendar.MONTH)) {
        return false;
    } else if (cal1.get(Calendar.DAY_OF_MONTH) <= cal2.get(Calendar.DAY_OF_MONTH)) {
        return false;
    }

    return true;
}

Check if day1 is before day2

/**
 * Check if day1 is before day2<br/>
 * day1 - 2020-6-12, day2 - 2020-6-13, return true <br/>
 * day1 - 2020-6-12, day2 - 2020-6-12, return false <br/>
 * day1 - 2020-6-13, day2 - 2020-6-12, return false <br/>
 */
public static boolean isBeforeDay(Date day1, Date day2) {
    if (day1 == null || day2 == null) {
        return false;
    }
    final Calendar cal1 = Calendar.getInstance();
    cal1.setTime(day1);
    final Calendar cal2 = Calendar.getInstance();
    cal2.setTime(day2);

    if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) {
        return false;
    } else if (cal1.get(Calendar.MONTH) > cal2.get(Calendar.MONTH)) {
        return false;
    } else if (cal1.get(Calendar.DAY_OF_MONTH) >= cal2.get(Calendar.DAY_OF_MONTH)) {
        return false;
    }

    return true;
}

 

October 2, 2020