I have a data class that extends Application and one of the data sets its supposed to be storing is a HashMap of POI locations and Time visited
public class CharacterSheet extends Application {
private HashMap<PointOfInterest, Date> coolDowns = new HashMap<>();
public HashMap GetAllCoolDowns() { return coolDowns; } //dev only?
public Date GetCoolDown(PointOfInterest poi) {return coolDowns.get(poi);}
public Date PutCoolDown(PointOfInterest poi, Date date) {return coolDowns.put(poi, date);}}
Then on a google maps activity I grab the OnPOIclick
#Override
public void onPoiClick(final PointOfInterest poi) {
//POI Cool Down
Date currentTime = Calendar.getInstance().getTime();
Date lastTime = ((CharacterSheet) this.getApplication()).GetCoolDown(poi);//this ONLY returns null??
if (lastTime != null){
int timeDiff = currentTime.compareTo(lastTime);
makeToast("Time Since last visit: " + timeDiff );
} else { makeToast("First");
}
((CharacterSheet) this.getApplication()).PutCoolDown(poi, currentTime);
makeToast("This?" + ((CharacterSheet) this.getApplication()).GetCoolDown(poi));}
The order should be Click poi, Get current time.. get last time visited, if last time is null.. never been before, store time and date in a hashmap with poi as key
Next time turn up and this time last time should not be null as we stored this poi and time already.. but no matter what it returns null..
Last line of code is a makeToast helper telling me what is in the Data Class.. this gives me a date value of when I clicked not a null value
There is a fragment generated later on in the OnPOIClick, but still before the user can do anything, which you end up looking at and have to "back" out of, I don't know how this could effect it as all the code is finished before even calling for data for the fragment but feel It should be mentioned
PlacesClient placesClient = Places.createClient(this);
String placeId = poi.placeId;
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.TYPES);
FetchPlaceRequest request = FetchPlaceRequest.newInstance(placeId, placeFields);
placesClient.fetchPlace(request).addOnSuccessListener(new OnSuccessListener<FetchPlaceResponse>() {
#Override
public void onSuccess(FetchPlaceResponse fetchPlaceResponse) {
Place place = fetchPlaceResponse.getPlace();
PlaceDataHolder holder = new PlaceDataHolder(place);
String placeName = poi.name;
makeLootFragment(holder,placeName);
The Fragment launched is the entire point of clicking the POI so if this is the case I'll need to think of another way of handling the cooldowns.. but I really don't see why it would interfere.
I was not being thoughtful enough about the PointOfInterest that was returned. It comes with a UUID for every time the request is made, rendering it useless as a key as every time I clicked it changed.. this was discovered by changing my post operation check from making sure it had gone into the hashMap, to seeing the contents of the entire hashMap, soon saw that the entries where building up despite only clicking one poi
To solve this was simple enough. I created a new String variable from poi.name and used that in place of the poi, had to change the HashMap to accept a String rather than a PointOfInterest
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
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*/
);
Is there any problem with below code?
I want to use the method parseDateToInteger in a process that execute million times. This process can be accessed in multithread way, so I synchronized the method. I avoid to create the Calendar instance inside the method, cause its take a precious time. But I don't sure about this code behaviour. There are any problem in use this code?
private static final Calendar CALENDAR_BRASIL = GregorianCalendar.getInstance(LOCALE_BRASIL);
public synchronized static int parseDateToInteger(Date data) {
CALENDAR_BRASIL.setTime(data);
int ano = CALENDAR_BRASIL.get(Calendar.YEAR);
int mes = CALENDAR_BRASIL.get(Calendar.MONTH)+1;
int dia = CALENDAR_BRASIL.get(Calendar.DATE);
return ano * 10000 + mes * 100 + dia;
}
EDIT:
I See this article that makes me afraid, but the author don't used a synchronized method.
http://blog.bielu.com/2008/08/javautilcalendar-confusion-is-it-safe_28.html
This is a bad idea. Although you've avoided creating all of those objects, you now have a method that can only be used by one object at a time. So instead of creating a million objects, partially in parallel, you're going to have processes that have to wait their turn to use the Calendar.
Just create the instance for each thread.
I'm trying to compare two instances of calendar but something does not work as I expect it. My code goes as following:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar now = Calendar.getInstance();
Calendar past = Calendar.getInstance();
past.set(2014,2,30);
Log.d("ppp",String.valueOf(now.after(past)) +" \n Past: " + past.toString() +" \n Now: "+ now.toString());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I would expect the above code to return true, but looking at the logCat this is what I get:
false
Past: java.util.GregorianCalendar[time=1396174280322,areFieldsSet=true,lenient=true,zone=Europe/Amsterdam,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=2,WEEK_OF_YEAR=14,WEEK_OF_MONTH=6,DAY_OF_MONTH=30,DAY_OF_YEAR=89,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=5,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=11,SECOND=20,MILLISECOND=322,ZONE_OFFSET=3600000,DST_OFFSET=3600000]
Now: java.util.GregorianCalendar[time=1394622680322,areFieldsSet=true,lenient=true,zone=Europe/Amsterdam,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=2,WEEK_OF_YEAR=11,WEEK_OF_MONTH=3,DAY_OF_MONTH=12,DAY_OF_YEAR=71,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=11,SECOND=20,MILLISECOND=322,ZONE_OFFSET=3600000,DST_OFFSET=0]
In particular I don't understand why for example MONTH is the same for both objects (why isn't the current one 3?) while DAY_OF_YEAR is actually higher in the past Calendar than in the current one.
What am I missing here?
Works as intended. Read the docs.
Android java.util.Calendar looks to behave in a similar way to the standard Java version.
Java docs say:
Any field values set in a Calendar will not be interpreted until it
needs to calculate its time value (milliseconds from the Epoch) or
values of the calendar fields. Calling the get, getTimeInMillis,
getTime, add and roll involves such calculation.
Android docs say:
set(f, value) changes field f to value. In addition, it sets an
internal member variable to indicate that field f has been changed.
Although field f is changed immediately, the calendar's milliseconds
is not recomputed until the next call to get(), getTime(), or
getTimeInMillis() is made. Thus, multiple calls to set() do not
trigger multiple, unnecessary computations.