I have the date of several events expressed in milliseconds[1], and I want to know which events are inside the current week and the current month, but I can't figure out how to obtain the first day (day/month/year) of the running week and convert it to milliseconds, the same for the first day of the month.
[1]Since January 1, 1970, 00:00:00 GMT
java.time
The java.time framework in Java 8 and later supplants the old java.util.Date/.Calendar classes. The old classes have proven to be troublesome, confusing, and flawed. Avoid them.
The java.time framework is inspired by the highly-successful Joda-Time library, defined by JSR 310, extended by the ThreeTen-Extra project, and explained in the Tutorial.
Instant
The
Instant
class represents a moment on the timeline in UTC.The java.time framework has a resolution of nanoseconds, or 9 digits of a fractional second. Milliseconds is only 3 digits of a fractional second. Because millisecond resolution is common, java.time includes a handy factory method.
ZonedDateTime
To consider current week and current month, we need to apply a particular time zone.
Half-Open
In date-time work, we commonly use the Half-Open approach to defining a span of time. The beginning is inclusive while the ending in exclusive. Rather than try to determine the last split-second of the end of the week (or month), we get the first moment of the following week (or month). So a week runs from the first moment of Monday and goes up to but not including the first moment of the following Monday.
Let's the first day of the week, and last. The java.time framework includes a tool for that, the
with
method and theChronoField
enum.By default, java.time uses the ISO 8601 standard. So Monday is the first day of the week (1) and Sunday is last (7).
Oops! Look at the time-of-day on those values. We want the first moment of the day. The first moment of the day is not always
00:00:00.000
because of Daylight Saving Time (DST) or other anomalies. So we should let java.time make the adjustment on our behalf. To do that, we must go through theLocalDate
class.And same for the month.
YearMonth
Another way to see if a pair of moments are in the same month is to check for the same
YearMonth
value.For example, assuming
thisZdt
andthatZdt
are bothZonedDateTime
objects:Milliseconds
I strongly recommend against doing your date-time work in milliseconds-from-epoch. That is indeed the way date-time classes tend to work internally, but we have the classes for a reason. Handling a count-from-epoch is clumsy as the values are not intelligible by humans so debugging and logging is difficult and error-prone. And, as we've already seen, different resolutions may be in play; old Java classes and Joda-Time library use milliseconds, while databases like Postgres use microseconds, and now java.time uses nanoseconds.
Would you handle text as bits, or do you let classes such as
String
,StringBuffer
, andStringBuilder
handle such details?But if you insist, from a
ZonedDateTime
get anInstant
, and from that get a milliseconds-count-from-epoch. But keep in mind this call can mean loss of data. Any microseconds or nanoseconds that you might have in yourZonedDateTime
/Instant
will be truncated (lost).Get First date of next month:-
I have created some methods for this:
You can see more here.
Attention!
is good idea, but there is some issue: For example, i'm from Ukraine and calendar.getFirstDayOfWeek() in my country is 2 (Monday). And today is 1 (Sunday). In this case calendar.add not called.
So, correct way is change ">" to "!=":