How to implement a broadcast calendar in Kotlin (or Java) - java

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.

Related

Java-Zoned time not returning correct year [duplicate]

This question already has answers here:
Difference between 'YYYY' and 'yyyy' in NSDateFormatter
(4 answers)
Closed 3 years ago.
Due to the new year,I detected a bug in my project.
I am showing date and time in my order history using the following code:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm a MM/dd/YY", Locale.US).withZone(ZoneId.systemDefault());
String formattedOrderDate = formatter.withZone(ZoneId.of(order.timeZone)).format(order.order.pickupAt);
textView.setText(formattedOrderDate );
Here are the values received from server:
order.order.pickupAt = {ZonedDateTime#8390} "2020-01-02T17:50Z"
order.timeZone = "America/Denver"
But the output is not showing the perfect year for the end of December:
As you can clearly see, year 2019 is showing as 2020.
But it is only showing for the last of December.Another order from mid of December is showing the correct date(year).
I am not able to detect what is going wrong over here.I am suspecting that this might be due to the timezone(America/Denver).But I have changed the timezone to my local timezone,still it is showing 2020 instead of 2019.
Use yy instead of YY
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm a MM/dd/yy", Locale.US).withZone(ZoneId.systemDefault());
String formattedOrderDate = formatter.withZone(ZoneId.of(order.timeZone)).format(order.order.pickupAt);
textView.setText(formattedOrderDate );
YY is for week-based calendar year and yy is for calendar year. Last few days of December was actually the first week of 2020, so it is showing 2020 for those days.
Change your code to use yy, then it will show correct year -
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm a MM/dd/yy", Locale.US).withZone(ZoneId.systemDefault());

Java date-manipulation

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().

getting incorrect date using Calender in Java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calendar returns wrong month
I want to retrieve the date and time for my application, for which I wrote the following code
Calendar c = Calendar.getInstance();
System.err.println("Date is: " + c.get(Calendar.DATE));
System.err.println("Month is: " + c.get(Calendar.MONTH));
System.err.println("Year is: " + c.get(Calendar.YEAR));
System.err.println("Hour is: " + c.get(Calendar.HOUR_OF_DAY));
However the preceding code snippet is providing incorrect result.
SEVERE: Date is: 31
SEVERE: Month is: 11
SEVERE: Year is: 2012
SEVERE: Hour is: 17
NOTE: The time on my machine is perfect, no problem there
You are expecting 12 instead of 11 for the month.
c.get(Calendar.MONTH) returns 0 based index.
From the javadoc :
public static final int MONTH
Field number for get and set indicating the month. This is a calendar-specific value. The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; the last depends on the number of months in a year.
Month is zero indexed. So, 11 means its December.
The output that you are getting is correct.
I think you are confused why you are getting month as 11 instead of 12. Right? If that is the question then don't bother. Months are 0 based and hence 0 is January, 1 is Feb and so on...
So output as 11 means is December.
Read Docs
If you want proper month with wording as month, use below.
Calendar rightNow = Calendar.getInstance();
java.text.SimpleDateFormat df1 = new java.text.SimpleDateFormat("MM");
java.text.SimpleDateFormat df2 = new java.text.SimpleDateFormat("MMM");
java.text.SimpleDateFormat df3 = new java.text.SimpleDateFormat("MMMM");
System.out.println(df1.format(rightNow.getTime()));
System.out.println(df2.format(rightNow.getTime()));
System.out.println(df3.format(rightNow.getTime()));
it will give
12
Dec
December
Demo
Note: In demo you will see Jan 2013 as the server of this site is somewhere where 2013 already begun. World Time

Java Calendar Setting Incorrectly

I'm having some trouble with Java's Calendar. I'm parsing some data from a txt file, and need to create a date. After completion of the following code:
tmpYear = Double.parseDouble(row[yearIndex]);
tmpMonth = Double.parseDouble(row[monthIndex]);
tmpDay = Double.parseDouble(row[dayIndex]);
if(timeIndex != -1)
tmpTime = Double.parseDouble(row[timeIndex]);
if(secondsIndex != -1)
tmpSeconds = Double.parseDouble(row[secondsIndex]);
I can debug and see that the variables are as follows:
tmpYear == 2010
tmpMonth == 12
tmpDay == 30
tmpTime == 15 (This is the hour of the day)
tmpSeconds == 0
But when running the following code:
cal.set((int)tmpYear,(int)tmpMonth,(int)tmpDay,(int)tmpTime,
(int)((tmpTime - (int)tmpTime)*100),(int)tmpSeconds);
System.out.println(cal.getTime().toString());
I'm getting this for an output:
Sun Jan 30 15:00:00 CST 2011
Can someone explain what a possible reason for this would be? Thank you all in advance for the help!
months are indexed 0-11 instead of 1-12.
0 = January
1 = February
...
11 = December
Use tmpMonth = value -1 instead.
I believe the month's value starts at 0 rather than 1 so it interprets 0 as Jan, 1 as Feb ... and then Jan again as 12.
From the API:
month - the value used to set the
MONTH time field. Month value is
0-based. e.g., 0 for January.
When you set the Calendar.MONTH field, it is zero-based. {January=0... December=11}
The reason is quite simple: design fault in the Calendar API. That's why the JSR 310 is on its way in order to improve the java support for dates.
Technically, the authors of the class thought it was good to use only static fields. So what you need to do is to use the following:
calendar = ...
calendar.setMonth(Calendar.JANUARY);
They didn't think that people might need dynamic settings to a calendar, just like you need (and most of us, for that matters).
The month values go from 0 (January) to 11 (December). Try using ((int) tmpMonth) - 1 when setting the month to get December.

java.util.Calendar not reporting the correct timeInMillis

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.

Categories