73. Extracting the count of milliseconds since midnight
So, we have a date-time (let’s say a LocalDateTime or LocalTime) and we want to know how many milliseconds have been passed from midnight to this date-time. Let’s consider that the given date-time is right now:
LocalDateTime now = LocalDateTime.now();
Midnight is relative to now, is in the past at 00:00:00, so we can create it as follows:
LocalDateTime midnight = LocalDateTime.of(now.getYear(),
now.getMonth(), now.getDayOfMonth(), 0, 0, 0);
Finally, compute the difference in milliseconds between midnight and now. This can be accomplished in several ways, but probably the most concise solution relies on java.time.temporal.ChronoUnit. This API exposes a set of units useful to manipulate a date, time, or date-time including milliseconds:
System.out.println(“Millis: “
+ ChronoUnit.MILLIS.between(midnight, now));
In the bundled code you can see more examples of ChronoUnit.
74. Splitting a date-time range into equal intervals
Let’s consider given a date-time range (bounded by a start date and an end date represented by two LocalDateTime instances) and an integer n. In order to split the given range into n equal intervals we start by defining a java.time.Duration is as follows:
Duration range = Duration.between(start, end);
Having this date-time range, we can rely on dividedBy() to obtain a copy of it divided by the specified n:
Duration interval = range.dividedBy(n – 1);
Finally, we can begin from the start date (the left head of the range) and repeatedly increment it with the interval value until we reach the end date (the right head of the range). After each step, we store the new date in a list that will be returned at the end. Here is the complete code:
public static List<LocalDateTime> splitInEqualIntervals(
LocalDateTime start, LocalDateTime end, int n) {
Duration range = Duration.between(start, end);
Duration interval = range.dividedBy(n – 1);
List<LocalDateTime> listOfDates = new ArrayList<>();
LocalDateTime timeline = start;
for (int i = 0; i < n – 1; i++) {
listOfDates.add(timeline);
timeline = timeline.plus(interval);
}
listOfDates.add(end);
return listOfDates;
}
The resulting listOfDates will contain n dates at equal intervals.
75. Explaining the difference between Clock.systemUTC() and Clock.systemDefaultZone()
Let’s start with the following three lines of code:
System.out.println(Clock.systemDefaultZone());
System.out.println(system(ZoneId.systemDefault()));
System.out.println(Clock.systemUTC());
The output reveals that the first two lines are similar. Both of them display the default time zone (in my case, Europe/Bucharest):
SystemClock[Europe/Bucharest]
SystemClock[Europe/Bucharest]
The third line is different. Here we see Z time zone, which is specific to the UTC time zone and indicates the presence of a zone-offset:
SystemClock[Z]
On the other hand, creating an Instant reveals that Clock.systemUTC() and Clock.systemDefaultZone() produces the same result:
System.out.println(Clock.systemDefaultZone().instant()); System.out.println(system(ZoneId.systemDefault()).instant());
System.out.println(Clock.systemUTC().instant());
The instant time is the same in all three cases:
2023-02-07T05:26:17.374159500Z
2023-02-07T05:26:17.384811300Z
2023-02-07T05:26:17.384811300Z
But, the difference occurs when we try to create a date, time, or date-time from these two clocks. For instance, let’s create a LocalDateTime from Clock.systemUTC():
// 2023-02-07T05:26:17.384811300
System.out.println(LocalDateTime.now(Clock.systemUTC()));
And, a LocalDateTime from Clock.systemDefaultZone():
// 2023-02-07T07:26:17.384811300
System.out.println(LocalDateTime.now(
Clock.systemDefaultZone()));
My time (default time zone, Europe/Bucharest) is 07:26:17. But, the time via Clock.systemUTC() is 05:26:17. This is because Europe/Bucharest is at an offset of UTC-2, so systemUTC() produces date-time in UTC time zone, while systemDefaultZone() produces date-time in current default time zone. However, both of them produce the same Instant.