I am working on a calendar project for a school seminar. It is supposed to print three months that go after each other. (You specify you want it to print January and it prints December of previous year, January and February).
I have this if statement for this, but I would like to simplify it into three lines of code. How do I do it? Is it possible?
if (month == 1) {
printMonth(12, year-1);
printMonth(month, year);
printMonth(month+1, year);
} else if (month == 12) {
printMonth(month-1, year);
printMonth(month, year);
printMonth(1, year+1);
} else {
printMonth(month-1, year);
printMonth(month, year);
printMonth(month+1, year);
}
Try using ternary operator:
printMonth(month == 1 ? 12 : month - 1, month == 1 ? year - 1 : year);
printMonth(month, year);
printMonth(month == 12 ? 1 : month + 1, month == 12 ? year + 1 : year);
You could use the Joda DateTime class to represent the current year/month, which is probably better than carrying years and month around as independent integers.
Then you could write:
printMonth(dt.minusMonths(1));
printMonth(dt);
printMonth(dt.plusMonths(1));
When I had such a problem myself, I tended to use an approach of combining year and month (also because I wanted to save some lines of code):
int monthAndYear = year * 12 + month;
printMonth(monthAndYear - 1);
printMonth(monthAndYear);
printMonth(monthAndYear + 1);
As you can see, this requires you to adjust the printMonth method, if it is possible of course.
private void printMonth(int monthAndYear) {
int year = monthAndYear / 12;
int month = monthAndYear % 12;
// other code...
}
And these are still four lines though...
Related
As example If i got the month of August 2016 then i should get the start date as 01 Jul 2016 and end date as 30 September 2016(as this comes under 3rd quarter of this year).
Can anybody explain a logic for this.?
You could use Month and LocalDate's methods to get those dates:
public static void printStartEndQuarter(int year, Month month) {
LocalDate start = LocalDate.of(year, month.firstMonthOfQuarter(), 1);
Month endMonth = start.getMonth().plus(2);
LocalDate end = LocalDate.of(year, endMonth, endMonth.length(start.isLeapYear()));
System.out.println(start);
System.out.println(end);
}
public static void printStartEndQuarter(int year, int month) {
double thisMonth = (double)month;
String quarter = thisMonth/3 <= 1 ? "Quarter 1" : thisMonth/3 <= 2 ? "Quarter 2" : thisMonth/3 <= 3 ? "Quarter 3" : "Quarter 4";
if (month % 3 == 2) {
month = month - 1;
}
else if (month % 3 == 0) {
month = month - 2;
}
LocalDate start = LocalDate.of(year, month, 1);
Month endMonth = start.getMonth().plus(2);
LocalDate end = LocalDate.of(year, endMonth, endMonth.length(start.isLeapYear()));
System.out.println("Start Date====" + start);
System.out.println("End Date====" + end);
System.out.println("quarter====" + quarter);
}
Hope this will help some one and it will work for any test case.Thank You #fabin.
What exactly is it you do not understand? 3rd quarter of an year includes the months July, August and September, so start date of the quarter is the 1st day in July and end date is the last day of September. If you have February or March for example the start date will be 01 Jan 2016 and end date will be 31 Mar 2016. It is that simple.
I've made a function that should get the number of weeks for a given month. For January, May, July and October, it should return 5 weeks.
However, it returns 5 for March, June, September. and November. Surprisingly, the total amount of weeks are correct (52).
public static int getNofWeeksWithFirstWeekStartingWhenFirstDayOfMonthOccurs(Calendar calendar) {
while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
calendar.roll(Calendar.DATE, true);
}
int currentMonth = calendar.get(Calendar.MONTH);
int nextMonth = (currentMonth + 1) % 12;
int prePreviousMonth = (currentMonth + 12 - 2) % 12;
int nofWeeks = 0;
do {
int month = calendar.get(Calendar.MONTH);
if (month == nextMonth) {
nofWeeks++;
}
if (month == prePreviousMonth) {
break;
}
calendar.roll(Calendar.WEEK_OF_YEAR, true);
} while (true);
return nofWeeks;
}
public static void main(String[] args) {
int numWeeks;
int totalWeeks=0;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2016);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.MONTH, Calendar.MAY);
numWeeks=getNofWeeksWithFirstWeekStartingWhenFirstDayOfMonthOccurs(calendar);
System.out.println("no of weeks " + numWeeks);
}
Output:
no of weeks 4
Month start is in Week that has first day. e.g.:
25 - 1 May
2 - 8 May
9 - 15 May
16 - 22 May
23 - 29 May
5 Weeks in May:
It sounds to me like you should:
Work out the first day of the month
Determine from that how many "extra" days are "borrowed" from the previous month (e.g. 0 if day 1 is a Monday; 1 if day 1 is a Tuesday etc)
Add that to the number of days in the regular month
Divide by 7 (with implicit truncation towards 0)
There's no need to do half the work you're currently doing.
Using java.util.Calendar, it would be something like:
// Note: day-of-week runs from Sunday (1) to Saturday (7).
// Entry 0 here is not used. We could do this without an array lookup
// if desired, but it's whatever code you think is clearest.
private static final int[] EXTRA_DAYS = { 0, 6, 0, 1, 2, 3, 4, 5 };
// Note: 0-based month as per the rest of java.util.Calendar
public static int getWeekCount(int year, int month) {
Calendar calendar = new GregorianCalendar(year, month, 1);
int dayOfWeekOfStartOfMonth = calendar.get(Calendar.DAY_OF_WEEK);
int extraDays = EXTRA_DAYS[dayOfWeekOfStartOfMonth];
int regularDaysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
int effectiveDaysInMonth = regularDaysInMonth + extraDays;
return effectiveDaysInMonth / 7;
}
If at all possible, I'd recommend using Joda Time or java.time instead, however.
With that code, the results for 2016 are:
January: 5
February: 4
March: 4
April: 4
May: 5
June: 4
July: 5
August: 4
September: 4
October: 5
November: 4
December: 4
From the comments I deduce that you want to count the number of weeks in a month starting at the 1st of the month.
You need to:
Set the day of the month to 1
add forward, not roll backward
start on Sunday instead of Monday
The code would be something like this:
public static int getNofWeeksWithFirstWeekStartingWhenFirstDayOfMonthOccurs(Calendar calendar) {
while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
calendar.roll(Calendar.DATE, true);
}
int currentMonth = calendar.get(Calendar.MONTH);
int nextMonth = (currentMonth + 1) % 12;
int prePreviousMonth = (currentMonth + 12 - 2) % 12;
int nofWeeks = 0;
do {
int month = calendar.get(Calendar.MONTH);
if (month == currentMonth) {
nofWeeks++;
} else {
break;
}
calendar.add(Calendar.WEEK_OF_YEAR, 1);
} while (true);
return nofWeeks;
}
public static void main(String[] args) {
int numWeeks;
int totalWeeks=0;
for (int i = 0; i < 12; i++) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2016);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.MONTH, i);
numWeeks=getNofWeeksWithFirstWeekStartingWhenFirstDayOfMonthOccurs(calendar);
System.out.println("no of weeks " + numWeeks);
}
}
Output:
no of weeks 5
no of weeks 4
no of weeks 4
no of weeks 4
no of weeks 5
no of weeks 4
no of weeks 5
no of weeks 4
no of weeks 4
no of weeks 5
no of weeks 4
no of weeks 4
It's my first question on this site, but I always found this site really useful.
What I mean with my question is:
you ask the person to give a date (eg. Fill in a date [dd-mm-yyyy]:
16-10-2013)
you than have to ask an interval between 2
years (eg. Give an interval [yyyy-yyyy]:1800-2000)
When the program runs, it has to show what day of the week the given date is. In this case it was a Wednesday. Than the program has to look in which year, in between the interval, the date 16 October also fell on a Wednesday.
So in the end it has to look something like this:
Fill in a date: [dd-mm-yyyy]: 16-10-2013
Give an interval [yyyy-yyyy]: 1900-2000
16 October was a wednesday in the following years:
1905 1911 1916 1922 1933 1939 1944 1950 1961 1967 1972 1978 1989 1995 2000
The full date is Wednesday 16 October, 2013
The small (or biggest) problem is, I am not allowed to use the DATE.function in java.
If someone can help me with the second part I would be really really happy, cause I have no idea how I am supposed to do this
To find out what day of the week the given date falls, I use the Zeller Congruence
class Day {
Date date; //To grab the month and year form the Date class
//In this class I check whether the giving date is in the correct form
int day;
int year1; //First interval number
int year2; //Second interval number
final static String[] DAYS_OF_WEEK = {
"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday"
};
public void dayWeekInterval{
int interval.year1;
int interval.year2;
for(int i = year1; year1 =< year2; year1++) {
//check if the day of the week in the giving year, is the same as the
//original year.
}
}
public void dayOfTheWeek {
int m = date.getMonth();
int y = date.getYear();
if (m < 3) {
m += 12;
y -= 1;
}
int k = y % 100;
int j = y / 100;
int day = ((q + (((m + 1) * 26) / 10) + k + (k / 4) + (j / 4)) +
(5 * j)) % 7;
return day;
}
public string ToString(){
return "" + DAYS_OF_WEEK[day] + day;
}
Hey, I changed my code a bit, but I don't know how to knot the tie. Also I forgot to mention, I am not allowed to use the Date and Calendar function of java... And I pretty much did something wrong with the outlook..
Just a simple formula to find day for given date dd - MM - yyxx is,
( dd + m + xx + (xx/4) + (yy%4) ) % 7
% is modulus operator which is remainder in general
The answer got above will tell you day of week i.e. 0 : Mon 1: Tue .... 6 for Sun
Here,
dd - Date given
m - month value which is shown down in list calculated with MM value
yy - first two digits of supplied year
xx - last two digits of year
Now, m value calculation is,
0 for Jan and Oct
1 for May
2 for August
3 for Feb, March and Nov
4 for June
5 for Sept and Dec
6 for July and April
Remember if month supplied is Jan or Feb and the year supplied is leap then subtract 1 from m value in above table i.e. -1 for Jan and 2 for Feb
Leap Year Calculation is
if (yyyy % 4 == 0)
{
if( yyyy % 100 == 0)
{
return (yyyy % 400) == 0;
}
else
return true;
}
I hope rest of programming you can do.
This will help you find the day of week for supplied date and now you just need to add loop for all the years.
You cannot use Datebut can you use Calendar? Then this would be your code:
Calendar c = Calendar.getInstance();
c.set(2013, 9, 16); // month starts at zero
System.out.printf("Original date is: %tc\n", c);
int weekday = c.get(Calendar.DAY_OF_WEEK);
System.out.printf("Weekday of original date is [by number] %d\n", weekday);
for(int year = 1800; year < 2000; year++) {
c.set(Calendar.YEAR, year);
if(weekday == c.get(Calendar.DAY_OF_WEEK))
System.out.printf("%tc was same weekday!\n", c);
}
How to calculate number of Tuesday in one month?
Using calender.set we can set particular month, after that how to calculate number of Mondays, Tuesdays etc. in that month?
Code is :
public static void main(String[] args )
{
Calendar calendar = Calendar.getInstance();
int month = calendar.MAY;
int year = 2012;
int date = 1 ;
calendar.set(year, month, date);
int MaxDay = calendar.getActualMaximum(calendar.DAY_OF_MONTH);
int mon=0;
for(int i = 1 ; i < MaxDay ; i++)
{
calendar.set(Calendar.DAY_OF_MONTH, i);
if (calendar.get(Calendar.DAY_OF_WEEK) == calendar.MONDAY )
mon++;
}
System.out.println("days : " + MaxDay);
System.out.println("MOndays :" + mon);
}
Without writing whole code here is the general idea:
Calendar c = Calendar.getInstance();
c.set(Calendar.MONTH, Calendar.MAY); // may is just an example
c.set(Calendar.YEAR, 2012);
int th = 0;
int maxDayInMonth = c.getMaximum(Calendar.MONTH);
for (int d = 1; d <= maxDayInMonth; d++) {
c.set(Calendar.DAY_OF_MONTH, d);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
if (Calendar.THURSDAY == dayOfWeek) {
th++;
}
}
This code should count number of Thursday. I believe you can modify it to count number of all days of week.
Obviously this code is not efficient. It iterates over all the days in the month. You can optimize it by getting just get day of the week of the first day, the number of days in month and (I believe) you can write code that calculates number of each day of week without iterating over the whole month.
With Java 8+, you could write it in a more concise way:
public static int countDayOccurenceInMonth(DayOfWeek dow, YearMonth month) {
LocalDate start = month.atDay(1).with(TemporalAdjusters.nextOrSame(dow));
return (int) ChronoUnit.WEEKS.between(start, month.atEndOfMonth()) + 1;
}
Which you can call with:
int count = countDayOccurenceInMonth(DayOfWeek.TUESDAY, YearMonth.of(2012, 1));
System.out.println(count); //prints 5
AlexR mentioned the more efficient version. Thought I would give it a whirl:
private int getNumThursdays() {
// create instance of Gregorian calendar
Calendar gc = new GregorianCalendar(TimeZone.getTimeZone("EST"), Locale.US);
int currentWeekday = gc.get(Calendar.DAY_OF_WEEK);
// get number of days left in month
int daysLeft = gc.getActualMaximum(Calendar.DAY_OF_MONTH) -
gc.get(Calendar.DAY_OF_MONTH);
// move to closest thursday (either today or ahead)
while(currentWeekday != Calendar.THURSDAY) {
if (currentWeekday < 7) currentWeekday++;
else currentWeekday = 1;
daysLeft--;
}
// calculate the number of Thursdays left
return daysLeft / 7 + 1;
}
note: When getting the current year, month, day etc. it is dependent on your environment. For example if someone manually set the time on their phone to something wrong, then this calculation could be wrong. To ensure correctness, it is best to pull data about the current month, year, day, time from a trusted source.
Java calendar actually has a built in property for that Calendar.DAY_OF_WEEK_IN_MONTH
Calendar calendar = Calendar.getInstance(); //get instance
calendar.set(Calendar.DAY_OF_WEEK, 3); //make it be a Tuesday (crucial)
//optionally set the month you want here
calendar.set(Calendar.MONTH, 4) //May
calendar.getActualMaximum(Calendar.DAY_OF_WEEK_IN_MONTH); //for this month (what you want)
calendar.getMaximum(Calendar.DAY_OF_WEEK_IN_MONTH); //for any month (not so useful)
Given an instance of java.util.Date which is a Sunday. If there are 4 Sundays in the month in question, I need to figure out whether the chosen date is
1st Sunday of month
2nd Sunday of month
2nd last Sunday of month
Last Sunday of month
If there are 5 Sundays in the month in question, then I need to figure out whether the chosen date is
1st Sunday of month
2nd Sunday of month
3rd Sunday of month
2nd last Sunday of month
Last Sunday of month
I've had a look in JodaTime, but haven't found the relevant functionality there yet. The project is actually a Groovy project, so I could use either Java or Groovy to solve this.
Thanks,
Donal
Solutions given so far will tell you 1st, 2nd, 3rd, 4th, or 5th. But the question said he wanted to know "last" and "second to last". If the questioner really needs to know "last" etc, there's a little extra complexity. You have to figure out how many Sundays are in the month to know whether or not the 4th Sunday is the last. The first way to figure that out that occurs to me is:
GregorianCalendar gc=new GregorianCalendar();
gc.setTime(mydate);
gc.set(Calendar.DAY_OF_MONTH,1); // Roll back to first of month
int weekday=gc.get(Calendar.DAY_OF_WEEK); // day of week of first day
// Find day of month of first Sunday
int firstSunday;
if (weekday==Calendar.SUNDAY)
firstSunday=1;
else
firstSunday=weekday-Calendar.SUNDAY+6;
// Day of month of fifth Sunday, if it exists
int fifthSunday=firstSunday+7*4;
// Find last day of month
gc.add(Calendar.MONTH,1);
gc.add(Calendar.DATE,-1);
int lastDay=gc.get(DAY_OF_MONTH);
int sundays;
if (fifthSunday<lastDay)
sundays=4;
else
sundays=5;
That seems like rather a lot of work. Anybody see an easier way?
DAY_OF_WEEK_IN_MONTH
import java.sql.Date;
import java.util.Calendar;
public class Dow {
public static void main(String[] args) {
Date date = new Date( 2010, 4, 1 );
Calendar cal = Calendar.getInstance();
cal.setTime( date );
for ( int week = 0 ; week < 5 ; week++ ) {
System.out.println( cal.getTime() + " week:" + cal.get( Calendar.DAY_OF_WEEK_IN_MONTH ) );
cal.add( Calendar.WEEK_OF_MONTH, 1 );
}
}
}
> Sun May 01 00:00:00 CEST 3910 week:1
> Sun May 08 00:00:00 CEST 3910 week:2
> Sun May 15 00:00:00 CEST 3910 week:3
> Sun May 22 00:00:00 CEST 3910 week:4
> Sun May 29 00:00:00 CEST 3910 week:5
return dayOfMonth / 7 + 1;
MORE EDIT
Okay, taking Jay's comment in consideration, let's try this one:
int sundayId = dayOfMonth / 7 + 1;
if (sundayId == 1) {
return "1st";
} else if (sundayId == 2) {
return "2nd";
} else if (sundayId == 3) {
return ((dayOfMonth + 14 <= daysInMonth) ? "3rd" : "2nd Last");
} else if (sundayId == 4) {
return ((dayOfMonth + 7 <= daysInMonth) ? "2nd Last" : "Last");
} else {
return "Last";
}
whereas daysInMonth is calculated as follows:
if (month == 2) {
if (year % 100) {
return ((year % 400 == 0) ? 29 : 28);
} else {
return ((year % 4 == 0) ? 29 : 28);
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
return 30;
} else {
return 31;
}
... or in some other way.
int sundayOfMonth = dayOfMonth / 7 + 1;
You can just use java.util.Calendar to do your date calculations:
import java.util.Calendar as CAL
def cal = CAL.getInstance(date)
def isFirst= cal.get(CAL.WEEK_OF_MONTH) == 1
def isSecond = cal.get(CAL.WEEK_OF_MONTH) == cal.getMaximum(CAL.WEEK_OF_MONTH)
Also, do not assume that there are only five weeks in a month with the Calendar object. For instance, the maximum weeks of 05/01/2010 would be 6.
EDIT: Here's my final version:
today = Calendar.instance
dayOfWeekInMonth = today.get(Calendar.DAY_OF_WEEK_IN_MONTH)
// move to last day of week occurrence in current month
today.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1)
maxDayOfWeekInMonth = today.get(Calendar.DAY_OF_WEEK_IN_MONTH)
dayOfWeekCount = ["1st", "2nd", "3rd", "2nd last", "Last"]
turningPoint = maxDayOfWeekInMonth - 2
if (dayOfWeekInMonth <= turningPoint) {
println dayOfWeekCount[dayOfWeekInMonth - 1]
}
else {
// use negative index to access list from last to first
println dayOfWeekCount[dayOfWeekInMonth - maxDayOfWeekInMonth - 1]
}