I'm trying to get a date with a Month number, week of month number and a day of week number
I thought this will be easy and did this:
LocalDate nextbookingDate = LocalDate.now().plusYears(1);
nextBookingDate = nextBookingDate.with(Month.of(1));
nextBookingDate = nextBookingDate.with(WeekFields.ISO.weekOfMonth(), 1);
nextBookingDate = nextBookingDate.with(DayOfWeek.of(1));
System.out.println(nextBookingDate); //2019-12-30
nextBookingDateshould be 2020-01-06 because its the first Monday in January.
But why do I get 2019-12-30 and how do I solve this?
In each new line, you are overwriting what you have done in the previous line.
Try something like this:
nextBookingDate = now()
.with(Month.of(1))
.with(WeekFields.ISO.weekOfMonth(), 1)
.with(DayOfWeek.of(1));
but be aware that December 30, 2019 is actually the first day of week 1 of 2020.
Because the question has been updated, a more relevant answer would be:
LocalDate nextBookingDate = LocalDate.now().plusYears(1)
.with(Month.JANUARY)
.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY));
and you can replace the 1 as argument for dayOfWeekInMonth with a number from 2 through 5 as appropriate.
It’s not completely clear to me what result you want in general, and why. If I may assume that you want the next date that is an nth some-day-of-week of some month, it’s a little more complicated than your code. EDIT: NorthernSky is correct in the comment under his/her answer that .with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY)) more directly and briefly gets us what we need. This should work:
ZoneId zone = ZoneId.of("Africa/Bamako");
LocalDate today = LocalDate.now(zone);
LocalDate nextBookingDate = today.with(Month.JANUARY)
.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY));
if (nextBookingDate.isBefore(today)) {
// Take next year instead
nextBookingDate = today.plusYears(1)
.with(Month.JANUARY)
.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY));
}
System.out.println("Next booking date: " + nextBookingDate);
Output when I ran the code just now, was:
Next booking date: 2020-01-06
TemporalAdjusters.dayOfWeekInMonth() will get us the 1st Monday, 3rd Tuesday, etc., of the month. So feed any day of week and any number up to 4 or 5 into this method.
Please supply your desired time zone where I put Africa/Bamako since it is never the same date in all time zones.
Link: Documentation of TemporalAdjusters.dayOfWeekInMonth().
Related
I'm trying to write an application that calculates the week number according to the broadcast calendar. The Wikipedia definition says:
Every week in the broadcast calendar starts on a Monday and ends on a Sunday
[...] the first week of every broadcast month always contains the Gregorian calendar first of the month
So I thought I could use WeekFields class and tried implementing it this way:
val broadcastCalendar = WeekFields.of(DayOfWeek.MONDAY, 1)
val march1 = LocalDate.of(2022, 3, 1)
val weekOfMarch1 = march1.get(broadcastCalendar.weekOfYear())
println("March 1 2022: $weekOfMarch1") // 10
This works fine most of the time but when trying to figure out the week numbers at the end and beginning of the year it fails:
val lastDayOf2022 = LocalDate.of(2022, 12, 31)
val lastWeekOf2022 = lastDayOf2022.get(broadcastCalendar.weekOfYear())
val firstDayOf2023 = LocalDate.of(2023, 1, 1)
val firstWeekOf2023 = firstDayOf2023.get(broadcastCalendar.weekOfYear())
println("last week of 2022: $lastWeekOf2022") // 53
println("first week of 2023: $firstWeekOf2023") // 1
According to Wikipedia's definition, the last week of 2022 should be 52 (Dec 19 - Dec 25) and the first one in 2023 should be 1 (Dec 26 - Jan 1) - see here.
How can I use WeekFields (or any other way) to fetch the correct week number?
From these quotes in the Wikipedia article, it seems like this calendar system uses a week-based year.
For example, if January 1 falls on a Saturday, then the broadcast calendar year would begin on the preceding Monday, December 27.
Broadcast calendar years can have either 52 or 53 weeks.
Because of this is, you should use weekOfWeekBasedYear:
val broadcastCalendar = WeekFields.of(DayOfWeek.MONDAY, 1)
val lastDayOf2022 = LocalDate.of(2022, 12, 31)
val lastWeekOf2022 = march1.get(broadcastCalendar.weekOfWeekBasedYear())
println(lastWeekOf2022) // 1
This represents the concept of the count of weeks within the year where weeks start on a fixed day-of-week, such as Monday and each week belongs to exactly one year.
Date rentDate = new Date(2323223232L);
Date currentDate = new Date();
if(rentDate.compareTo(currentDate)<30){
System.out.println("OVERDUE!!!");
}
I want to check if this rent date for a bike is overdue. It becomes overdue 30 days after the rent date.
LocalDate rentDate = LocalDate.of(2019, Month.MARCH, 15);
LocalDate dueDate = rentDate.plusDays(30);
if (dueDate.isBefore(LocalDate.now(ZoneId.of("Europe/Malta")))) {
System.out.println("Overdue; was due on " + dueDate);
}
When I ran it just now, it printed:
Overdue; was due on 2019-04-14
Please make sure you specify the desired time zone since it is never the same date everywhere on Earth.
Tip: Avoid shouting and exclamation marks in messages. Some users will feel bad about them, and they really don’t add anything helpful to the message. The user will understand the message fine without them.
Link: Oracle tutorial: Date Time explaining how to use java.time.
I have the following:
Date now = new Date();
Date futureDate = new Date(now.getYear(), now.getMonth(), now.getDay() + 30);
I want to set the future date value to be 30 days in the future, based on the current date (now).
When I debug this, now is the correct date, and the futureDate is:
Sat Jan 05 00:00:00 EST 2013
Today's date, the value of now is: Sat Dec 29 17:31:58 EST 2012.
This doesn't make sense to me?
I'm using util.Date.
Because getDay() returns day of the week, not day of the month.
So your
now.getDay() + 30
becomes Saturday + 30 = 6 + 30 = 36th December = 5th January
A quick fix would be to replace your code with:
now.getDate() + 30
But as others already suggest, java.util.Date is kind of deprecated. And you should use Calendar.add(). So your code would become something like:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, +30);
You should use Calendar and its method Calendar.add
If you want to use Date, you'll see working with adding days is all kinds of deprecated:
http://docs.oracle.com/javase/7/docs/api/java/util/Date.html
Use new Date(now.getTime() + (MILLISECONDS_IN_DAY * 30)) instead. Or if you're not stuck with Date, use Calendar.
Not only is that constructor deprecated, it only accepts valid days (1-31).
try using java.util.Calendar instead.
Date is not supposed to be used for such calculations.
Have a look at JodaTime which is exelent for such things.
I have a situation that requires me to get the 12 past months in a list.
Example:
The current month is March, and the current year is 2012. So I want to get a list that looks like this:
March (2011), April (2011)...December (2011), January (2012), February (2012), and March (2012).
I've been trying to accomplish this using Date and Calendar, I didn't quite manage to get the alorithm correct.
Any ideas?
Here's a Groovy way to do it:
use(groovy.time.TimeCategory) {
def today = new Date()
println today
12.times { i ->
println today - (i+1).months
}
}
You can read more about Groovy dates here
Here's a complete, functioning version based on doelleri's suggestion:
use(groovy.time.TimeCategory) {
def today = new Date()
13.times { i ->
println( (today - i.months).format('MMMM (yyyy)') )
}
}
The changes I made:
I modified the loop so that the printing could occur in the same place (instead of printing the current month in a different place).
I used the format method to render the date exactly as you requested. If you want the output to line up nicer, try using 'MMM (yyyy)' as the format, which uses 3-letter months.
You'll probably want to get these as a list, so you might be better off using:
def months
use(groovy.time.TimeCategory) {
def today = new Date()
months = (0..13).collect { (today - it.months).format('MMMM (yyyy)') }
}
Which stores the month data into an array called months.
findCalendarStart: time into Calendar: 1260575897
findCalendarStart: set hour : 13
findCalendarStart: after hour : 1249775897
findCalendarStart: after hour string: Thu Jan 15 11:09:35 UTC 1970
findCalendarStart: set minutes : 13
findCalendarStart: after minutes: 1250015897
findCalendarStart: what calendar returns: 1250015897
I place a Date (initialized by passing long from a millisecond from today) in a Calendar. Calendar is correctly initialized. In the first calculation, I change the hour of day to 13. At this point, startCalTime.set(Calendar.HOUR_OF_DAY, ((new Integer(m.group(1)).intValue())*2)-1 );
I am passing the right hour of day values and minutes because Im seeing them in the logger. What could possibly be causing calendar to come up with such strange dates after I only change the hour of day from todays Date object?
More code:
Calendar startCalTime = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
Date d = new Date(creationTime);
startCalTime.setTime(d);
startCalTime.getTimeInMillis();
..regex..
if(m.find()){
//SET HOUR OF DAY
_logger.warning("set hour 1 : " + new Integer((new Integer(m.group(1)).intValue())-1)); startCalTime.set(Calendar.HOUR_OF_DAY, new Integer(m.group(1)).intValue()-1 );
_logger.warning("after hour 1: " + new Long(startCalTime.getTime().getTime()));
_logger.warning("after hour 1 string: " + startCalTime.getTime().toString());
//SET MINUTE
_logger.warning("set minutes 1 : " + new Integer(m.group(2).toString()));
startCalTime.set(Calendar.MINUTE, new Integer(m.group(2)).intValue());
_logger.warning("after minutes 1: " + new Long(startCalTime.getTime().getTime()));}
Thanks,
culov
Let's see how you initialize your date. I suspect that instead of milliseconds, you are passing it seconds since epoch start - this (seconds, not milliseconds) is how regular Unix timestamps are defined. Java uses milliseconds for better granularity.
Calendar startCalTime = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
Date d = new Date(creationTime);
What happens there? startCalTime and creationTime don't seem to be connected, I'd assume they should be?
Also for very slightly better performance/memory footprint, avoid new Integer/Long as much as possible and use Long/Integer.valueOf() instead.
Those times in your Calendar don't look right. If those are supposed to be times in milliseconds, then 126..... represents a time of only 350 hours, which looks to be off by almost 40 years.
The reason seems to be that your initialization is not really setting your calendar to today's date. The initial date seems to be just a few hours past the epoch.
Please post some more code and we can fix it for you.