When adding 1 year to a Calendar object the first iteration adds zero years, even though it should add 1. Each subsequent call adds 1 year, as it should. For example:
calendarObject.add(Calendar.YEAR,1); //This actually adds nothing
calendarObject.add(Calendar.YEAR,1); // now it works.
Note: calendarObject has been set to have a year of 1995 with no other properties set.
It just works fine.
import java.util.Calendar;
public class CalTest
{
public static void main(String[] args)
{
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1995);
System.out.println(cal.get(Calendar.YEAR));
cal.add(Calendar.YEAR, 1);
System.out.println(cal.get(Calendar.YEAR));
cal.add(Calendar.YEAR, 1);
System.out.println(cal.get(Calendar.YEAR));
}
}
output:
1995
1996
1997
The Note is the source of the problem. You need to have more of the Calendar properties set other than just year. Vikdor's example works because he is using the default Calendar instance returned, which has all class members filled out. Just specifying "1995" will cause odd behavior.
Related
So I read through a few different threads but none of them seem to directly address how I fix my issue. I'm trying to create a Calendar (Gregorian) and then use the .complete() method so that in my classes using this (Paycheck) class I can find relative dates and create new Calendar(s) from those dates to determine wages payed and wages owed. However, it's telling me that .complete() .computeTime() and .computeFields() are all not visible.
From what I've read, this seems to be because they are protected methods and even though I import the java.util for them, I can't access them because that class is not in my package. How do I get this so that I can call the .complete() method?
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class Paycheck {
//fields
protected double grossAmount;
protected Calendar paymentDate;
protected Calendar payPeriodStart;
public Paycheck(double grossAmount, int iYear, int iMonth, int iDay, int sYear, int sMonth, int sDay) {
this.grossAmount = grossAmount;
TimeZone tz1 = TimeZone.getTimeZone("America/Chicago");
this.paymentDate = new GregorianCalendar(iYear, iMonth, iDay);
this.paymentDate.setTimeZone(tz1);
this.paymentDate.complete(); //says "method not visible"
this.payPeriodStart = new GregorianCalendar(sYear, sMonth, sDay);
this.payPeriodStart.setTimeZone(tz1);
}
In a comment you wrote:
I don't care about the actual time, I just want it to give me the date so I can determine the dayofweek (important based on various state laws).
That is very easy to do, and don't need any call to internal methods.
Calendar cal = new GregorianCalendar(2016, Calendar.SEPTEMBER, 22);
cal.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
System.out.println("Day of week (1=Sun, ..., 7=Sat): " + cal.get(Calendar.DAY_OF_WEEK));
Output
Day of week (1=Sun, ..., 7=Sat): 5
Output is 5 because today is Thu 9/22/2016, and that's the date that was given.
Let's compare the typing effort:
this.paymentDate = new GregorianCalendar(iYear, iMonth, iDay);
this.paymentDate.complete(); // Why do you need to call this one?
vs the code having the same effect
this.paymentDate = new GregorianCalendar(iYear, iMonth, iDay, 0, 0, 0);
// constructor taking extra hours, minutes, seconds ----------^
So why do you try the almost-impossible of calling a protected method?
In some cases, very limited in number, one really needs to call a protected/private method and this may be possible. Exemplifying:
Class<GregorianCalendar> clazz=GregorianCalendar.class;
Method completeMethod = clazz.getDeclaredMethod("complete");
// this does the trick if it doesn't throw security exceptions
completeMethod.setAccessible(true);
completeMethod.invoke(this.paymentDate);
See the Javadoc for AccesibleObject.setAccessible, Method being derived from AccessibleObject
I am trying to create multiple objects of a train schedule using the required constructor,
public Station(String city, Calendar arrival, Calendar departure, int day)
However when I create the objects I can't pass the arrival and departure times because 20:30 etc is considered an int. I would love to just change Calendar to int in the constructor, but apparently it has to be done with Calendar.
Station stop1= new Station("Vancouver",null , 2030, 1)
This is want I try to create but like I said it won't take the parameters.
So obviously I need to think outside the box here and start messing around with Calendar but I'm not sure if I should be doing that under the constructor below:
public Station(String city, Calendar arrival, Calendar departure, int day){
this.city=city;
this.arrival=arrival;
this.departure=departure;
this.day=day;
}
or if I have to create some new method and tie it all together. On my research I came across a method that I altered a bit, but I still can't seem to implement it into my object creation using those parameters of "arrival" and "departure".
private static Calendar getCalendar(int hour, int minute) {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, hour);
c.set(Calendar.MINUTE, minute);
return c;
}
So I guess I'm wondering if anyone can drop some hints, point me in the right direction of something else maybe I should be looking up online. This is the last and hardest question on my assignment and I can't even get the 10 objects created to start the train schedule.
I would love to just change Calendar to int in the constructor, but apparently it has to be done with Calendar.
I am not sure what you mean exactly with this, but lets say for some reason you prefer to keep the constructor as it is now, then what you need to do with the code you already posted is something like this
Station stop1= new Station("Vancouver",null , getCalendar(20, 30) , 1)
Otherwise you can do as suggested in the other answers
I like the composite approach.
public StationAdapter {
private readonly Station station;
public StationAdapter(String city, int arrival, int departure, int day) {
// Create station
}
}
Or eventually a Builder Pattern.
Firstly, bear with me – I'm only about a month into Java.
In an exercise, I'm asked to proof (with a test unit) that from a certain year (x) to a certain other year (y) that there are only one day between 31st of December and the 1st of January. They suggest that I should use a for-loop to make it run through all the years in-between our x and y year.
A predefined method called daysTill is already created.
So far, I've come up with this ugly piece of code, which doesn't work:
public void testYearEnd()
{int i;
for(i = 1635; i <=2300; i++);
Date date1 = new Date(i, 31, 12);
Date date2 = new Date(i, 01, 01);
assertEquals(1, date1.daysTill(date2));
}
Can anyone bear to point out exactly where my code is failing on me?
Two problems here: you have a stray ; that's ending your for-statement without a body, making it a no-op, and missing braces around the intended body. (Without the ;, this wouldn't compile as the Date declaration isn't a statement.)
You can also move the declaration of i into the for-statement (you couldn't before because the for-statement ended early due to the ;, so i was undefined for the Date constructors).
The code should be
public void testYearEnd() {
for (int i = 1635; i <= 2300; i++) {
Date date1 = new Date(i, 31, 12);
Date date2 = new Date(i, 01, 01);
assertEquals(1, date1.daysTill(date2));
}
}
I am working on a project that will run many thousands of comparisons between dates to see if they are in the same month, and I am wondering what the most efficient way of doing it would be.
This isn't exactly what my code looks like, but here's the gist:
List<Date> dates = getABunchOfDates();
Calendar month = Calendar.getInstance();
for(int i = 0; i < numMonths; i++)
{
for(Date date : dates)
{
if(sameMonth(month, date)
.. doSomething
}
month.add(Calendar.MONTH, -1);
}
Creating a new Calendar object for every date seems like a pretty hefty overhead when this comparison will happen thousands of times, soI kind of want to cheat a bit and use the deprecated method Date.getMonth() and Date.getYear()
public static boolean sameMonth(Calendar month, Date date)
{
return month.get(Calendar.YEAR) == date.getYear() && month.get(Calendar.MONTH) == date.getMonth();
}
I'm pretty close to just using this method, since it seems to be the fastest, but is there a faster way? And is this a foolish way, since the Date methods are deprecated? Note: This project will always run with Java 7
I can't comment on whether to use the deprecated methods, but if you choose not to there's no need to instantiate a new Calendar for every Date you check. Just use one other Calendar and call setTime(date) before the check (or one Calendar for every thread if you parallelize it).
As a side note, I do have to agree with ChristopheD's comment that this is something worthy of a database.
I think you can define a static DateFormat to extract the month and year from Date and use both objects as date only.
public static DateFormat formatter= new SimpleDateForm("MMyyyy");
public static boolean sameMonth(Date date1, Date date2)
{
return formatter.format(date1).equals(formatter.format(date2));
}
Problem: I have a list containg hours, for example:
08:15:00
08:45:00
09:00:00
12:00:00
...
application is allowing user to make an appointment for a specific hour let'say: 8:15:00, each meeting takes half an hour.
Question: How to determine if there is a slot needed for appointment like this? I know that Calendar class have methods before() nad after(), but it doesn'solve my problem. I mean if there is appointment at 12:00 and another one at 12:00, how to prevent before making another one at 12:15?
edit:
I've tried using methods I mentioned before, like:
Calendar cal1 = Calendar.getInstance(); // for example 12:00:00
Calendar cal2 = Calendar.getInstance(); // for exmaple 12:30:00
Calendar userTime = Calendar.getInstance(); // time to test: 12:15:00
if(user.after(cal1)&& user.before(cal2)){
... // do sth
}
Check if the date to check is between the two provided:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm");
Date before = sdf.parse("07/05/2012 08:00");
Date after = sdf.parse("07/05/2012 08:30");
Date toCheck = sdf.parse("07/05/2012 08:15");
//is toCheck between the two?
boolean isAvailable = (before.getTime() < toCheck.getTime()) && after.getTime() > toCheck.getTime();
To book for a determinate hour, I would do a class with two dates and a method to check this:
public class Appointment{
private Date start;
private Date end;
public boolean isBetween(Date toCheck){....}
}
Then you can simply do an Schedule class extending ArrayList, adding a method isDateAvailable(Date toCheck), iterating the list of Appointments and checking that there is no one conflicting.
I'd have some kind of appointment class with either a start timestamp and a duration or a start time and an end time. Then when adding new appointments to the schedule, check that the appointment with the start time before the new appointment doesn't run over the start time of the proposed new appointment.
Well how you would do it specifically depends on how you are storing your data, format, etc., but generally what you would do is simply check if there is an appointment for any time between the requested time to the requested time + requested length.
// Example (using int time(1 = 1 minute), assuming that appointments can only be at 15min intervals)
boolean isHalfHourTimeSlotAvaliable(int time) {
for (int i = 0; i < appointments.size(); i++) {
if (appointments.get(i).time == time || appointments.get(i).time == time + 15) {
return false;
}
}
return true;
}