Reputation: 100398
I want to create an interval between the beginning of the week, and the end of the current week.
I have the following code, borrowed from this answer:
private LocalDateTime calcNextSunday(LocalDateTime d) {
if (d.getDayOfWeek() > DateTimeConstants.SUNDAY) {
d = d.plusWeeks(1);
}
return d.withDayOfWeek(DateTimeConstants.SUNDAY);
}
private LocalDateTime calcPreviousMonday(LocalDateTime d) {
if (d.getDayOfWeek() < DateTimeConstants.MONDAY) {
d = d.minusWeeks(1);
}
return d.withDayOfWeek(DateTimeConstants.MONDAY);
}
But now I want the Monday LocalDateTime
to be at 00:00:00, and the Sunday LocalDateTime
at 23:59:59. How would I do this?
Upvotes: 52
Views: 55997
Reputation: 34657
DateTime.now().withTimeAtStartOfDay(); // start of day
DateTime.now().plusDays(1).withTimeAtStartOfDay().minusSeconds(1); // end of day
Upvotes: 0
Reputation: 5609
With Kotlin you could write an extension function:
fun DateTime.withTimeAtEndOfDay() : DateTime = this.withTime(23,59,59,999)
This would allow you to write:
d.withDayOfWeek(DateTimeConstants.SUNDAY).withTimeAtEndOfDay()
Upvotes: 2
Reputation: 2465
begin = d
// Go to previous or same Sunday
.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY))
// Beginning of day
.truncatedTo(ChronoUnit.DAYS)
end = d
// Go to next Sunday
.with(TemporalAdjusters.next(DayOfWeek.SUNDAY))
// Beginning of day
.truncatedTo(ChronoUnit.DAYS)
I also think it is a bad idea to represent the end of week interval with small amount of time before the actual, exclusive end. It is better to treat begin as inclusive, and end as exclusive instead (when doing comparisons etc.).
Upvotes: 0
Reputation: 1242
For those coming here looking for the answer for "js-joda", you have two options depending on what you're looking to accomplish
Option 1: You want the start of the day in the same timezone
Since you've chosen to calculate your times based on an instant in time in relation to a timezone, you should use ZonedDateTime:
import { ZonedDateTime, LocalDate, ZoneId, DateTimeFormatter} from "js-joda";
import 'js-joda-timezone';
const nowInNewYorkCity = ZonedDateTime.now(ZoneId.of("America/New_York"))
const startOfTodayInNYC = nowInNewYorkCity.truncatedTo(ChronoUnit.DAYS);
console.log(startOfTodayInNYC.toString()) // Prints "2019-04-15T00:00-04:00[America/New_York]"
// And if you want to print it in ISO format
console.log(startOfTodayInNYC.format(DateTimeFormatter.ISO_INSTANT)) // "2019-04-14T04:00:00Z"
Option 2: You know the exact day that you want to get the time for
Then you can use the following methods off of LocalDate to derive the relative time (i.e. ZonedDateTime) you'd like:
atStartOfDay(): LocalDateTime
atStartOfDay(zone: ZoneId): ZonedDateTime
atStartOfDayWithZone(zone: ZoneId): ZonedDateTime
Option 3: I want just the day the instant occurred on
Notice with this code, you get the day that it would be relative to where you are. So for those in New York City, it's "2019-04-14" and for those in London it would be "2019-04-15" (which is great!) because the instant in time was during the period of time where it's actually tomorrow in London ("2019-04-15T00:00:05Z"). Pretend that you were calling someone in London from NYC, and the Londoner would say, "geez, why are you calling me so early... it's 5 seconds past midnight."
import { ZonedDateTime, LocalDate, ZoneId} from "js-joda";
import 'js-joda-timezone';
const aTimeWhenLondonIsAlreadyInTomorrow = "2019-04-15T00:00:05.000Z";
const inBetweenTimeInLondon = ZonedDateTime.parse(aTimeWhenLondonIsAlreadyInTomorrow);
const inBetweenTimeInNYC = inBetweenTimeInLondon.withZoneSameInstant(ZoneId.of("America/New_York"))
const dayInLondon = inBetweenTimeInLondon.toLocalDate();
const dayInNYC = inBetweenTimeInNYC.toLocalDate();
console.log(inBetweenTimeInLondon.toString()); // "2019-04-15T00:00:05Z"
console.log(dayInLondon.toString()); // "2019-04-15"
console.log(inBetweenTimeInNYC.toString()) // "2019-04-14T20:00:05-04:00[America/New_York]"
console.log(dayInNYC.toString()); // "2019-04-14"
References: https://js-joda.github.io/js-joda/class/src/LocalDate.js~LocalDate.html#instance-method-atStartOfDayWithZone
Upvotes: 1
Reputation: 63385
You can use the withTime
method:
d.withTime(0, 0, 0, 0);
d.withTime(23, 59, 59, 999);
Same as Peter's answer, but shorter.
Upvotes: 156
Reputation: 6173
How about:
private LocalDateTime calcNextSunday(LocalDateTime d) {
return d.withHourOfDay(23).withMinuteOfHour(59).withSecondOfMinute(59).withDayOfWeek(DateTimeConstants.SUNDAY);
}
private LocalDateTime calcPreviousMonday(final LocalDateTime d) {
return d.withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).withDayOfWeek(DateTimeConstants.MONDAY);
}
Upvotes: 25