java.time
The legacy date-time API (java.util
date-time types and their formatting type, SimpleDateFormat
etc.) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time
, the modern date-time API*.
Solution using java.time
, the modern API:
The modern date-time API is rich with intuitive concepts e.g. it provides us with the class, Instant
which represents an instantaneous point on the timeline. There is a class called ZonedDateTime
which represents a date-time with a time-zone in the ISO-8601 calendar system. In order to switch to a different time unit (e.g. day, hour, minute, week, month etc.), the API provides methods named as prepositions and other spoken English constructs. Learn more about the modern date-time API from Trail: Date Time.
The concepts like today, yesterday, same week etc. are bounds to a timezone e.g a moment today in London can be tomorrow in Singapore. Also, the start of the week is Locale
-sensitive e.g. for Locale.France
, it starts on Monday whereas for Locale.US
, it starts on Sunday.
Demo:
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// Test
Stream.of(
1621533017083L,
1621446617083L,
1621619417083L,
1621189684296L,
1621209600000L,
1621814400000L
).forEach(millis -> {
System.out.println(millis);
System.out.println(Instant.ofEpochMilli(millis));
System.out.println("Today: " + isToday(millis, "Europe/London"));
System.out.println("Yesterday: " + isYesterday(millis, "Europe/London"));
System.out.println("In the current week: " + isInTheSameWeek(millis, "Europe/London"));
System.out.println();
});
}
static boolean isToday(long epochMillis, String timezone) {
ZoneId zoneId = ZoneId.of(timezone);
// The start of the day today at this timezone
ZonedDateTime zdtStartOfDayToday = LocalDate.now().atStartOfDay(zoneId);
long millisStartOfDayToday = zdtStartOfDayToday.toInstant().toEpochMilli();
// The start of the next day at this timezone
ZonedDateTime zdtStartOfDayNextDay = LocalDate.now().plusDays(1).atStartOfDay(zoneId);
long millisStartOfDayNextDay = zdtStartOfDayNextDay.toInstant().toEpochMilli();
return (epochMillis >= millisStartOfDayToday && epochMillis < millisStartOfDayNextDay);
}
static boolean isYesterday(long epochMillis, String timezone) {
ZoneId zoneId = ZoneId.of(timezone);
// The start of the day today at this timezone
ZonedDateTime zdtStartOfDayToday = LocalDate.now().atStartOfDay(zoneId);
long millisStartOfDayToday = zdtStartOfDayToday.toInstant().toEpochMilli();
// The start of the day yesterday at this timezone
ZonedDateTime zdtStartOfDayYesterday = LocalDate.now().minusDays(1).atStartOfDay(zoneId);
long millisStartOfDayYesterday = zdtStartOfDayYesterday.toInstant().toEpochMilli();
return (epochMillis >= millisStartOfDayYesterday && epochMillis < millisStartOfDayToday);
}
static boolean isInTheSameWeek(long epochMillis, String timezone) {
ZoneId zoneId = ZoneId.of(timezone);
// The start of the day today at this timezone
ZonedDateTime zdtStartOfDayToday = LocalDate.now().atStartOfDay(zoneId);
// The start of the week at this timezone
ZonedDateTime zdtStartOfTheWeek = zdtStartOfDayToday.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
long millisStartOfTheWeek = zdtStartOfTheWeek.toInstant().toEpochMilli();
// The start of the next week at this timezone
ZonedDateTime zdtStartOfTheNextWeek = zdtStartOfDayToday.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
long millisStartOfTheNextWeek = zdtStartOfTheNextWeek.toInstant().toEpochMilli();
return (epochMillis >= millisStartOfTheWeek && epochMillis < millisStartOfTheNextWeek);
}
}
Output:
1621533017083
2021-05-20T17:50:17.083Z
Today: true
Yesterday: false
In the current week: true
1621446617083
2021-05-19T17:50:17.083Z
Today: false
Yesterday: true
In the current week: true
1621619417083
2021-05-21T17:50:17.083Z
Today: false
Yesterday: false
In the current week: true
1621189684296
2021-05-16T18:28:04.296Z
Today: false
Yesterday: false
In the current week: false
1621209600000
2021-05-17T00:00:00Z
Today: false
Yesterday: false
In the current week: true
1621814400000
2021-05-24T00:00:00Z
Today: false
Yesterday: false
In the current week: false
ONLINE DEMO
* 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.