java.time
The java.util
Date-Time API and their formatting API, SimpleDateFormat
are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time
, the modern Date-Time API:
The solution uses following functions:
ZonedDateTime#now(ZoneId)
: Returns the current date-time from the system clock in the specified timezone.
ZonedDateTime#getDayOfWeek
: Returns the day-of-week field, which is an enum DayOfWeek
.
TemporalAdjusters#next
: Returns the next day-of-week adjuster, which adjusts the date to the first occurrence of the specified day-of-week after the date being adjusted.
ZonedDateTime#toLocalDate
: Returns the LocalDate
part of this date-time.
LocalTime#atStartOfDay(ZoneId)
: Returns a zoned date-time from this date at the earliest valid time according to the rules in the time-zone.
ChronoUnit#between
: Calculates the amount of time between two temporal objects.
Demo:
import static java.time.DayOfWeek.SATURDAY;
import static java.time.DayOfWeek.SUNDAY;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.TextStyle;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Tests
process(ZonedDateTime.now(ZoneId.systemDefault()));
process(ZonedDateTime.of(LocalDate.of(2021, 6, 23), LocalTime.of(10, 20, 30, 123456789),
ZoneId.systemDefault()));
process(ZonedDateTime.of(LocalDate.of(2021, 6, 26), LocalTime.of(10, 20, 30, 123456789),
ZoneId.systemDefault()));
}
static long millisBetween(ZonedDateTime start, ZonedDateTime end) {
return ChronoUnit.MILLIS.between(start, end);
}
static boolean isWeekend(ZonedDateTime now) {
DayOfWeek dow = now.getDayOfWeek();
return dow == SATURDAY || dow == SUNDAY;
}
static void process(ZonedDateTime now) {
String dow = now.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH);
if (isWeekend(now)) {
System.out.printf("It's %s (a weekend) now. Monday is %d milliseconds ahead.%n", dow,
millisBetween(now, now.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).toLocalDate()
.atStartOfDay(ZoneId.systemDefault())));
} else {
System.out.printf("It's %s (a weekday) now. Saturday is %d milliseconds ahead.%n", dow,
millisBetween(now, now.with(TemporalAdjusters.next(DayOfWeek.SATURDAY)).toLocalDate()
.atStartOfDay(ZoneId.systemDefault())));
}
}
}
Output from a sample run:
It's Sunday (a weekend) now. Monday is 30258373 milliseconds ahead.
It's Wednesday (a weekday) now. Saturday is 221969876 milliseconds ahead.
It's Saturday (a weekend) now. Monday is 135569876 milliseconds ahead.
ONLINE DEMO
Note: For the code to work for a timezone different from the JVM's timezone, replace ZoneId.systemDefault()
with the applicable timezone ID e.g. ZoneId.of("America/New_York")
.
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.