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);
	}
}