Calendar (GregorianCalendar) .complete() method not visible? - java

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

Related

Cannot find symbol for method format(DateTimeFormatter)?

I'm having a problem and I absolutely can't wrap my head around it. I am inexperienced in Java (or any language, for that matter), so excuse me if this is a stupid question.
From what I can tell, the format() method from java.time.format.DateTimeFormatter is not working how I thought it did. I am consistently getting the following error message (CLI):
Watch.java:609: error: cannot find symbol
String dateTimeDisplay = dateTime.format(dateTimeFormat);
^
symbol: method format(DateTimeFormatter)
location: variable dateTime of type Object
1 error
And here are the bits of code I think are relevant:
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class Watch {
protected int hour, hourTens, hourOnes, minute, minuteTens, minuteOnes, amPM;
public void watchMethod(String userInput) {
Object dateTime; // Create reference to object called dateTime
switch (userInput) {
case "1":
ZonedDateTime dateTimeHere = ZonedDateTime.now();
hour = dateTimeHere.getHour();
minute = dateTimeHere.getMinute();
// amPM is used exclusively to display AM/PM or a heart (see lines 580 to 567).
amPM = dateTimeHere.getHour();
dateTime = dateTimeHere;
break;
case "2":
ZonedDateTime dateTimeThere = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
hour = dateTimeThere.getHour();
minute = dateTimeThere.getMinute();
// amPM is used exclusively to display AM/PM or a heart (see lines 560 to 567).
amPM = dateTimeThere.getHour();
dateTime = dateTimeThere;
break;
case "3":
hour = -1;
minute = -1;
break;
}
// There is some code that prints things to console depending on the hour, minute, and amPM variables.
// I don't think this is relevant, but that's what's here.
// The following code prints out the actual date and time from a ZonedDateTime object.
DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("hh:mm a 'on' EEEE, MMMM dd, yyyy");
String dateTimeDisplay = dateTime.format(dateTimeFormat); // ERROR
System.out.print("\nIt is currently " + dateTimeDisplay + "\n");
}
}
This is all one class.
I have checked that my imports are correct and that there are no misspellings anywhere! This is what other questions related to my problem have led me to believe was the issue, but it doesn't seem to be the case.
I'm also not very familiar with using Object as a reference type, so if that could be what's causing the problem, I'm not surprised. It's all I could figure out to break dateTimeHere/dateTimeThere out of the switch block.
Anyway, I'd greatly appreciate any help I receive.
QUICK EDIT: I also figured that if there were no suitable dateTime object (i.e. case "3"), this would also cause an error. I briefly added an if/else statement to remedy this, with some code in case "3" indicating that dateTime was null, but this did absolutely nothing. Let me know if I should re-add this, though.
EDIT: Thanks to a comment from #MarsAtomic, I see that this post could have used another read-through. My problem is that at the end of my code, I want to print out the ZonedDateTime data the switch statement retrieved, whether that is from the user's computer location or "Paris/Europe". Eventually, that "Paris/Europe" string will (ideally) have some user input from a subclass (as is the case with userInput, but that particular string was just for choosing one of the 3 cases already shown).
You probably meant to declare dateTime as a ZonedDateTime, as Object's definition does not include a format method.
Revised code:
ZonedDateTime dateTime = null; // Create reference to object called dateTime
//...
DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("hh:mm a 'on' EEEE, MMMM dd, yyyy");
if (dateTime != null) {
String dateTimeDisplay = dateTime.format(dateTimeFormat);
System.out.print("\nIt is currently " + dateTimeDisplay + "\n");
}

Can't create objects with a required API using Calendar

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.

Most efficient way of checking if Date object and Calendar object are in the same month

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));
}

Java Calendar class add method adds zero on first call?

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.

How to determine if the specific time is between given range?

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;
}

Categories

Resources