Java Calendar Setting Incorrectly - java

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.

Related

How to implement a broadcast calendar in Kotlin (or 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.

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

Why is my date not being set correctly to 30 days in the future?

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.

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

Listing 12 prior months

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.

Categories