I want to create an app that will allow the user to check whether or not the current time falls between a specified time interval. More specifically, I created a sql table using sqllite program, with the table specifying an end time and a start time for each record. The problem is that the type of data each field can be is limited to text, number, and other type other than a datetime type. So, how would I be able to check if the current time is between the start and end time since the format of time is in h:mm and not just an integer value that I could just do less than or greater than? Do I have to convert the current time to minutes?
You should be able to do the comparison even if time is not stored in the datetime type, here is a link that explains the conversion from string to time.
If that doesn't work, convert the time to seconds (int) and calculate the difference.
Try this. You can save and retrieve your time as String:
String to long: String.valueOf()
long to String: Long.valueOf()
Then, you use this procedure to check time:
//Time checker
private boolean timeCheck(long startTimeInput, long endTimeInput) {
long currentTime = System.currentTimeMillis();
if ((currentTime > startTimeInput) && (currentTime < endTimeInput)) {
return true;
} else {
return false;
}
}
And in your main program check it like this:
//You kept the times as String
if (timeCheck(Long.valueOf(start), Long.valueOf(end))) {
//it is in the interval
} else {
//not in the interval
}
I hope it helps.
Related
let say i will like to automatically change my textview text at 02:00pm everyday how do I implement this functionality.
val df = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.JAPAN).parse("2:00pm")
val systemDat = Calendar.getInstance(Locale.JAPAN).after(df)
if (systemDat) {
binding.includeTokyoSession.text_one.text = "successful"
} else {
binding.includeTokyoSession.text_one.text = "failure"
}
I suppose you want to change the text of your TextView after a particular time, but it seems that you're not aware of the date when comparing and you have a couple of mistakes in your code.
First, this line of code:
DateFormat.getTimeInstance(DateFormat.SHORT, Locale.JAPAN).parse("2:00pm")
will return a Date instance with this date and time in your local timezone 01-01-1970 02:00:00. However, you need to get a Date instance with today's date and the time 14:00:00.
Second, this line of code:
Calendar.getInstance(Locale.JAPAN).after(df)
this is a wrong usage of the Calendar::after() function, and that's because you can only pass a Calendar object to the function in order to get the right comparison result, otherwise it will always return false.
In your case you're passing a Date object.
Following is the implementation of the Calendar::after() function.
public boolean after(Object when) {
return when instanceof Calendar
&& compareTo((Calendar)when) > 0;
}
If you want to proper compare the current time today with 14:00 (comparing only the time today), here is a modification to your code:
val calendarToCompare = Calendar.getInstance(Locale.JAPAN).apply {
set(Calendar.HOUR_OF_DAY, 14)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
val systemDat = Calendar.getInstance().after(calendarToCompare)
if (systemDat) {
textview.text = "successful"
} else {
textview.text = "failure"
}
If you want to perform a lifecycle-aware view update (ex. to set the text of your textview), you can check this gist.
I have an iteration that runs for a set number of times depending on another value which can vary which is why I'm using an iteration that iterates based on that value, inside that iteration I add 30 days to a date once each iteration and then add the results to a table.
PROBLEMS
I simply end up with the first instance of adding 30 days which is outside the iteration itself. This means that my values inside the iteration are not being stored properly but I can't see why.
I've checked the DateTime operations and displayed the value of newdate and it shows the proper date so it's most likely the storing of the date. But I don't know what's going wrong, it works pre-iteration which is what's got me confused. Why isn't it executing inside the iteration? Does anyone have any idea?
Ex.
InitialDate | 3/29/2015
2ndDate | 4/28/2015<-- This is what's stored which is pre-iteration
3rdDate | 5/28/2015<-- This is what it's supposed to be after the iteration
so on and so forth....
Values pre-iteration
//Date stuff
String startdate = (String.valueOf(Acc._date));
DateTimeFormatter formatter = DateTimeFormat.forPattern("MM-dd-yyyy HH:mm:ss");
DateTime dt = formatter.parseDateTime(startdate);
DateTime startpoint = new DateTime(dt);
DateTime whendue = startpoint.plusDays(30);
DateTime foriteration = whendue;
String formattedDate = whendue.toString(formatter);
//Storing initial date
pay.setDateDue(formattedDate);
db.AddPayment(pay);
Actual iteration
while (i < j) {
//Operation for Date Calculation
DateTime ndt = foriteration.plusDays(30);
foriteration = ndt;
String newdate = ndt.toString(formatter);
//Adding values to PayTable
pay.setDateDue(newdate);
db.AddPayment(pay);
i++;
}
Finally found out what was wrong. Nothing. My roommate played a prank on me and just got back from his trip out of town and explained to me how he changed my getDateDue to execute a plusDays(30) to mimic my code so that when I called AddPayment which calls getDateDue it would look like it would work but in actuality would only add 30 days once to the startdate no matter what I did.
Summary
Roommate is an ass, nothing is wrong with my code. Sorry for this pointless post.
I current have (from server) a date stamp returned as ticks (.NET Date).
In general I managed to convert the above by subtracting by 10000 to produce secs and offset accordingly to get EPOC ms.
Now, the issue is that the ms passed from server include the zone offset and what I needed to do is get a TimeZone object for the zone (always the same) and subtract the ms offset (depending on DST) from the original value to produce a new object to properly get a Date.
Any better way of doing this without so many conversion?
private static long netEpocTicksConv = 621355968000000000L;
public static Date dateTimeLongToDate(long ticks) {
TimeZone greeceTz = TimeZone.getTimeZone("Europe/Athens");
Calendar cal0 = new GregorianCalendar(greeceTz);
long time = (ticks - netEpocTicksConv)/ 10000;
time -= greeceTz.getOffset(time);
cal0.setTimeInMillis(time);
Date res = cal0.getTime();
return res;
}
Here's some code which doesn't quite do the right thing near DST transitions:
private static final long DOTNET_TICKS_AT_UNIX_EPOCH = 621355968000000000L;
private static final TimeZone GREECE = TimeZone.getTimeZone("Europe/Athens");
public static Date dateTimeLongToDate(long ticks) {
long localMillis = (ticks - DOTNET_TICKS_AT_UNIX_EPOCH) / 10000L;
// Note: this does the wrong thing near DST transitions
long offset = GREECE.getOffset(localMillis - GREECE.getRawOffset());
long utcMillis = localMillis - offset;
return new Date(utcMillis);
}
There's no need to use a Calendar here.
You can get it to be accurate around DST transitions unless it's actually ambiguous, in which case you could make it either always return the earlier version or always return the later version. It's fiddly to do that, but it can be done.
By subtracting the offset for standard time, we're already reducing the amount of time during which it will be incorrect. Basically this code now says, "Subtract the standard time (no daylight savings) offset from the local time, to get an approximation to the UTC time. Now work out the offset at that UTC time."
I have some things in my Android application that need to update once per day.
It's pretty simple I think, but I have no idea in what format I need to format the date and time (if time is needed) and how to check if an update has been done today (where today is between 00:01am and 23:59pm in the user's local time). The update should not be done if it was already done for today.
Here's what I DO know how to do:
Save the last update date in SharedPreferences (but how do I get a
string of it, I do not know)
Get things from SharedPreferences (but I
don't know how to compare dates in string format)
It is irrelevant what format you choose. It is just matter of recalculations.
I'd suggest using milliseconds since epoch, as all system calls use it, so it would be easier for you to use the same.
As 1000 millis is 1 second it's easy to figure out that 1000*60*60*24 equals to one day (24hrs). So, if storedMillis is bigger than NOW - 1000*60*60*24, (and NOW is i.e. System.currentTimeMillis()), then it is too early to do the check. If storedMillis is smaller, then save your NOW timestamp and do the check:
long now = System.currentTimeMillis();
long diffMillis = now - lastCheckedMillis;
if( diffMillis >= (3600000 * 24) ) {
// store now (i.e. in shared prefs)
// do the check
} else {
// too early
}
EDIT
I am interested in doing it when the app is first opened for the
current day, even if the last update was done 10 minutes ago.
It's just the matter how to get the proper millis to compare against. Replace long now = System.currentTimeMillis(); from above code with following code block:
Calendar cal = Calendar.getInstance();
cal.clear(Calendar.HOUR);
cal.clear(Calendar.HOUR_OF_DAY);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
long now = cal.getTimeInMillis();
which shall do the trick.
If you store your date in format 20121122 (YYYYmmdd) then you can compare is like 20121122 > 20121123. But it must be stored as int or cast to int when comparing.
Store the timestamp (System.currentTimeMillis() ) of the Last execution and compair it with the currient one. If the difference is more than 24 hours... You know it or?
Set up an Alarm with AlarmManager that executes every 24 hours, then do stuff
Check this question: Alarm Manager Example
It's a more complicated approach than the rest, but makes sure things are done, while with the other options the app must be executed in order to check if it has to update whatever.
Here is the method
public boolean runOnceADay() {
SharedPreferences shp= c.getSharedPreferences(Constants.GENERAL_SHP, MODE_PRIVATE);
SharedPreferences.Editor editor= shp.edit();
long lastCheckedMillis = shp.getLong(Constants.ONCE_A_DAY, 0); // "KEY" you may change yhe value
long now = System.currentTimeMillis();
long diffMillis = now - lastCheckedMillis;
if (diffMillis >= (3600000 * 24)) { // set up your time circulation
editor.putLong(Constants.ONCE_A_DAY, now);
editor.commit();
Util.showMessage(c, "Once a Day Test");
return false;
} else {
Util.showMessage(c, "Too Early");
return true;
}
}
im working on auto profile changer application for android...this is my 2nd application im developing on android, so dont know all the bells and whistles of android development...
any way...i am having some trouble calculating the next time when the timer code is suppose to execute...mainly the issue is around the time that spans over midnight into the next day...
for example, say that the user created a sleeping profile that starts at 10:30PM and goes until 8AM the next day...using this as a example, the execution is getting inside the proper condition that i have placed in the code, but the nextUpdateInterval is not being set correctly...im still trying to figure out how to account/calculate time that spans over to the next day, and at this point im starting to think that im might be making this task overly complicated? any suggestions?
here is the snippet of the code:
timer.scheduleAtFixedRate( new TimerTask() {
public void run() {
//..... some code to convert user stored times into proper time formats
//PM to PM
if(isFromTimePM == true && isToTimePM == true){
}//PM to AM
else if(isFromTimePM == true && isToTimePM == false){
if(rightNowDate.getTime() >= fromDate.getTime() && rightNowDate.getTime() >= toDate.getTime()){
foundProfileIndex = i;
i = profileArrayListSize;
nextUpdateInterval = rightNowDate.getTime() - toDate.getTime();
}
}//AM to AM
else if(isFromTimePM == false && isToTimePM == false){
}//AM to PM
else if(isFromTimePM == false && isToTimePM == true){
}}, 0, nextUpdateInterval);
Thanks,
P
Forget about PM and AM. Since you appear to be using dates, when you use the getTime() method you are getting the number of milliseconds elapsed since the Epoch. Simply subtract these two and you will have the time interval in milliseconds:
long nextUpdateInterval = secondDate.getTime() - firstDate.getTime();
The nextUpdateInterval is a long and is 'time in milliseconds between successive task executions'.
none of this secondDate - firstDate was ever necessary, what i ended up doing was the following:
converted all times to miliseconds
converted the milliseconds into the date objects
used the compareTo to compare the 'to' 'from' dates to current date/time
if i found a profile match, then i stored the 'to' date as the next run date
created a reScheduleTimer method that took date as a paramter...and i just used the .schdule(timertask, date) to resechule the timer...