• Post Reply Bookmark Topic Watch Topic
  • New Topic

Iterating through months while keeping in mind different length of month  RSS feed

 
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello dear Big Moose community,
I have a problem i spent several hours on that I cant seem to get my mind around.
I have to create a method to find the current month with the input being a number of milliseconds using System.currentTimeMillis().

Now I was able to solve the problem with the following extremely cumbersome method:


I first go through a loop that goes through all the years and subtracting the number of days of a normal year or a leap year in milliseconds from the total milliseconds.
At the end I should have a rest value of milliseconds that represents the amount of milliseconds that have passed already this year.
Out of this number I then find the month we are currently in.

My problem is that the above methid is way to large and I get a checkstyle warning: "NPath Complexity is 12,288 (max allowed is 80)".

I know that this can somehow be solved with a for loop iterating through the time and counting up months until there is no more month left.
My problem though is the different lengths of the months. If each month was the same I could just subtract the amount of days in each month from the rest value.
But since they are different lengths I dont know how to solve this.

Any Ideas?

(some of you might mention that since I already got it down to <= 12 months, I shouldnt bother with the extra days to find the month. Yet if I want to find the month when the date is the first or last day of the month it is important to be very precise)

Thanks!
 
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can use overloaded constructor of date class which takes milli seconds as a parameter. Through that you can get desired output. You can refer here
 
Dennis Von Valkenburgh
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tushar Goel wrote:You can use overloaded constructor of date class which takes milli seconds as a parameter. Through that you can get desired output. You can refer here

Hello, I think for our assignment we have to write it all ourselves. Unless im misunderstanding what you mean.
 
Saloon Keeper
Posts: 18800
74
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The java.util.Date(long) constructor is not "overloaded" according to Java's use of the term, it is one of the base constructors for that class. The only other non-deprecated constructor is the no-arguments construct, which is functionally equivalent to Date(0). The long value argument is the number of milliseconds since the Epoch, which in the Java world started at midnight GMT Sunday January 1, 1970.

 
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

One possible option is to declare the days of the months in an array, instead of twelve different variables. This way, you can use a loop (and one if statement), instead of twelve consecutive if statements.

Henry
 
Marshal
Posts: 56608
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would suggest you use an enumerated type for months. Also look through the Java® Language Specification (=JLS) about enums because although the JLS is often difficult to read, it has several examples in.
I would suggest you might do well to stop using int arithmetic. The shortest month in the year (=February) has 28 × 24 × 60² × 1000ms = 2419200000, which is considerably greater than the largest positive int (=2147483647), so there is a severe risk of overflow errors.
Do all your arithmetic with longs. For days in month, February = 24L.
Are you using milliseconds since 1st January 1970? If you use currentTimeMillis, that is what you will get.

Have you considered taking the opposite approach? You can divide the number of milliseconds by milliseconds per day (24 × 60² × 1000 = 86400000L). That gives you the number of completed days since 1st January 1970. So 1st January 1970 is day 0, 2nd January 1970 day 1, etc. 31st December 1970=day 364. You must assume that midnight is not the end of one day but the beginning of the next, so 86400000ms is not the end of 1st January but the beginning of 2nd January.
Remember there are 365 days in a year, so there are 1461 days in four years. By taking days ÷ 365 or days ÷ 1461, you can work out the year remembering the 3rd year in each 4 (=year2=1972) is a leap year. There has been no missed leap year for a century since 1970; the last xx00 year with 365 days was 1900, so you can simplify your calculations of leap years.

Then try taking days off.
As well as dividing by 86400000 or 365, take the remainder from those divisions. If it is not 0 you are not on 1st January or at midnight. I trust you are not required to correct for timezones.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!