Java static variable update with quartz scheduler - java

I have a JobClass wherein I am calling another class named as MainClass. The quartz trigger schedule to run the Main class via JobClass every 5 minutes. Now in the main class I have to collect the current date time something like below:-
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd/hh/mm/ss");
Calendar calendar = Calendar.getInstance();
String CurrentDateTime = dateFormat.format(calendar.getTime());
public String[] splitMe = CurrentDateTime.split("/");
public String year = splitMe[0];
public String month = splitMe[1];
public String day = splitMe[2];
public String hour = splitMe[3];
public String minute = splitMe[4];
public String second = splitMe[5];
String FilePrefix = year.concat(month).concat(day).concat("_").concat(hour).concat(minute).concat(second);
String FilePrefix4ControlFile = year.concat(month).concat(day).concat(" ").concat(hour).concat(minute).concat(second);
String EarliestTime = year.concat("-").concat(month).concat("-").concat(String.valueOf(Integer.parseInt(day) - 1));
String LatestTime = year.concat("-").concat(month).concat("-").concat(day);
This way I can get all my date time individual variable to create some strings with different combinations. Every single job runs I need to have a unique set of values however whatever number of times these variables are called within one job run then the values should be same.
Now I tried doing it using Static variables which kind of solved one problem of having same values during 1 run. However as the static variables are created on class initialisation ( main class) then they will always have same value unless the class is reloaded which I don't want to do , indeed not that easily possible in java.
I am sure I am doing some silly mistake, any pointers on this will be helpful.
PS: I just started Java by my own recently.
Thanks guys!
RJay

Related

How to write a java function in Spring data derivative

Right now I write the function to get the number of working days myself. Instead of course it is much better to make use of Spring data and let the database make the calculation.
So how could I write the second function in Spring data.
It should be something like. Count by Date Distinct group by date from WorkingDay . A workingDayObject can occur more than once per day if somebody worked on different projects . That's way I use a hashset in my function to get just the days.
private double calculateOvertimeHours(WorkingMonth month)
{
double workedHours = Util.convertTimeToDoubleDecimal(month.getWorkedHours());
//Here I use a Spring data method as you can see
List<WorkingDay> lstWorkingDays = workingDayDao.findByWorkingMonthOrderByDateAsc(month);
return workedHours - calcNumberWorkDays(lstWorkingDays) * 8;
}
private int calcNumberWorkDays(List<WorkingDay> lstWorkingDays)
{
Set<Integer> hashSetDays = new HashSet<Integer>();
Calendar cal = Calendar.getInstance();
for(WorkingDay workingDay : lstWorkingDays)
{
cal.setTime(workingDay.getDate());
hashSetDays.add(cal.get(Calendar.DAY_OF_MONTH));
}
return hashSetDays.size();
}

Java Unit Testing method that uses new Date() for current date [duplicate]

This question already has answers here:
Unit testing time-based logic in Java
(3 answers)
Handling unit tests with a condition on the current time
(6 answers)
Setting time and date in JUnit test fixture
(4 answers)
Writing and testing convenience methods using Java 8 Date/Time classes
(1 answer)
Closed 3 years ago.
So I have a class that has a method "getDaysUntil(Date date)" which returns the number of days until the date given as parameter. I mention that I cannot change the class below:
public class A {
public int getDaysUntil(Date givenDate) {
... // code
Date currentDate = new Date() //it creates a date object holding the current day
...// code that calculates the nr of days between currentDate and givenDate.
}
I have to do some unit testing and you might see the problem, it creates currentDate inside the method and the returned value will be different from day to day. I have tried to mock a Date object or "override" System.currentTimeMillis() with PowerMock but to no avail.
Is there any way to properly test these kind of methods?
Use a class that serves as a DateFactory, which is called to construct Date objects in your application code.
Then just mock the method of that DateFactory in your unit test. That way you can make it return whatever date you want as a virtual "current date"
One solution where System.currentTimeMillis() is mocked is as follows, using the JMockit library (it should be possible with PowerMock too):
#Test #SuppressWarnings("deprecation")
public void daysUntilCurrentDate() {
final long fakeCurrentDateInMillis = new Date(2017, 2, 1).getTime();
new MockUp<System>() {
#Mock long currentTimeMillis() { return fakeCurrentDateInMillis; }
};
A tested = new A();
int daysSinceJan30 = tested.getDaysUntil(new Date(2017, 1, 30));
assertEquals(2, daysSinceJan3O);
}
I understand that you cannot change the method that you need to test. Unfortunately this also means that you are stuck with the old and often not very programmer-friendly Date class (I am assuming java.util.Date).
Edit: The no-arg Date constructor that your method uses in turn uses System.currentTimeMillis(), a static native method. I didn’t know there were tools that could mock contructors and static native methods, but was informed by comment and answer by #Rogério, the developer of JMockit, that such mocking tools exist.
In any case, there is an alternative: you calculate some number of days from today, pass the resulting Date to the method and check that you get the number back you used in your calculation. This will work on any day and requires no mocking/stubbing.
In the code below I am assuming that the getDaysUntil method should discard the hours and minutes and just look at the date in the computer’s time zone. If the real requirements differ, you can probably make the appropriate adjustments to my code.
We want to take into account that the method may run over midnight. If so, I consider the result undefined since we do not know whether the Date object was constructed before or after midnight. In this case I simply try again, assuming the test will finish before the next midnight.
#Test
public void testGetDaysUntil() {
A instanceUnderTest = new A();
for (int daysToTest = 0; daysToTest <= 400; daysToTest++) {
LocalDate today;
int result;
do {
today = LocalDate.now(); // do this in each iteration in case day changes underway
LocalDate targetDate = today.plusDays(daysToTest);
Date midnightAtStartOfDay = Date.from(targetDate.atStartOfDay(ZoneId.systemDefault())
.toInstant());
result = instanceUnderTest.getDaysUntil(midnightAtStartOfDay);
} while (! today.equals(LocalDate.now())); // if we have passed midnight, try again
assertEquals(daysToTest, result);
do {
today = LocalDate.now();
LocalDate targetDate = today.plusDays(daysToTest);
Date nearMidnightAtEndOfDay = Date.from(targetDate.atTime(23, 59, 59, 400_000_000)
.atZone(ZoneId.systemDefault())
.toInstant());
result = instanceUnderTest.getDaysUntil(nearMidnightAtEndOfDay);
} while (! today.equals(LocalDate.now()));
assertEquals(daysToTest, result);
}
}
I have used the Java 8 classes for the date and time calculations. If you cannot use Java 8, Calendar and/or GregorianCalendar can be used, they may be just a little more cumbersome for this job, but at least can be converted to Date easily.

How can I create a jollyday HolidayManager instance from a given Locale?

In my application the user can set her Locale from a list of available locales. The application needs to determine if a given date is a holiday and I am using jollyday for this task.
Here is my current code:
public boolean isHoliday(Calendar cal) {
HolidayManager m = HolidayManager.getInstance();
return m.isHoliday(cal);
}
I can change this to the following code to set a specific HolidayCalendar:
public boolean isHoliday(Calendar cal) {
HolidayManager m = HolidayManager.getInstance(HolidayCalendar.GERMANY);
return m.isHoliday(cal);
}
But this method is deprecated and I would need to figure out which HolidayCalendar I need based on the user locale. What I want to do is something like this:
public boolean isHoliday(Calendar cal, Locale loc) {
HolidayManager m = HolidayManager.getInstance(loc);
return m.isHoliday(cal);
}
I know that HolidayManager is using Locale.getDefault() and there are public methods in Holiday too (see here) but I can not figure out how to do this and the documentation is very brief.
My question: Can I get the holidays based on a particular locale? Do I have to write a major switch statement for all the locales to match a HolidayCalendar?
Update I created a PR to the project and added the functionality myself. The PR already got merged
In the jollyday/util/ResourceUtil.java I see a hashmap for locale-holiday_description pair, but it's private static and not being populated anywhere.
https://github.com/svendiedrichsen/jollyday/blob/master/src/main/java/de/jollyday/util/ResourceUtil.java#L61
private static final Map<Locale, ResourceBundle> HOLIDAY_DESCRIPTION_CACHE = new HashMap<>();
So, I believe, there isn't any direct method to do what you are looking for. And it would default to default Locale as you figured out. But you can fork and modify that package to your needs and use it in your code.
Also, trying opening a issue-request https://github.com/svendiedrichsen/jollyday/issues

How to destruct Object Data On certain time

I have one singleton object which actually store user activity. I wanted to remove this data on certain time ( at every night 12 ). I wanted to know How we can achieve this with out having different thread running.
Add a method to the singleton that returns the last date it ran:
static Date lastRun = new Date(); //when the class initializes
Date lastDateRan() {
return lastRun;
}
Then add another method that checks if today > lastRun (pay attention to check only the date - not time/hour - in case you decide to use TimeStamp or any other library).
Whenever the object is called, check:
if (today > lastRun) {
lastRun = today;
// and clean the object.
}
It won't run every-day exactly at midnight, but it'll have the exact same effect! (the first call after midnight will get "fresh" data)
You can use following code :
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
Object_name.close //your code to cleanup object
}
},
12*60*60*1000 /*time after which it will run again*/
);

Frozen calendar - why?

As an experiment I ran the following code snippet (simplified):
public class SGamePlay extends Activity implements View.OnClickListener
{
Calendar GlobalCal = null;
public void onCreate(Bundle savedInstanceState)
{
GlobalCal = Calendar.getInstance();
}
long time_in_ms()
{
long ans = -1;
long ans2 = -1;
Calendar LocalCal = Calendar.getInstance();
ans = LocalCal.getTimeInMillis();
ans2 = GlobalCal.getTimeInMillis();
Log.e("game","ans="+ans+" ans2="+ans2);
return ans;
}
// much more code here...
}
The time_in_ms() function is called from a sub thread. The problem is that while ans appears to be a correct, constantly updating value, ans2 appears frozen at its initial value. How could this be?
EDIT: I need to resolve this issue because I want to reduce the need for garbage collection in my program.
Calendar is to be thought of as a "mark" in a calendar. It's more like a point in time, than an interface to the current time. (Why else would it have set-functions?)
So, the reason why ans2 is "frozen" is because GlobalCal.getTimeInMillis(); will always refer to the time when you called Calendar.getInstance() in the constructor (which you did once).
I need to resolve this issue because I want to reduce the need for garbage collection in my program.
Is the garbage collection the bottle neck of your program? Is the number of Calendars the bottle neck of the GC? Have you profiled your program?
Never mind... call System.currentTimeMillis instead.
GlobalCal is initialized in the oncreate method. It is not modified after that. How would you want it to change then ?
By the way, a variable name in java begins with a lowercase letter and follows camel case.

Categories