My app contains listview that are time limited. In another activity, I have a PostActivity that let's user post something to mysql server using volley. User post are time-limited. After posting their content, they can post again after a certain hour or minutes. As I mentioned before that my listview is time-limited, they contain timeCreated & timeExpiry. Whenever the user logins and tries to post something, I get the value of timeExpiry and check if
timeExpiry - currentTime (timeExpiry, currentTime & timeCreated) are all in milliseconds
Long currentTime = System.currentTimeMillis()
Long remainingTime = userDate.getTimeExpiry - currentTime;
if (remainingTime > 0 || remainingTime == 0) {
//User is allowed to post
}
!Wait User can change their mobile time and post unlimitedly!!
Now for the sake of simplicity, is there anyway to get the time from my mysql server or from a NTP-Server. I tried alot of classes such as the SntpClient class**(link below)** `
but I get the date before 1970-1-1
https://gist.github.com/prasann/9003350
I used this function but the method DateUtils.getFormattedDateTime() was not implemened in any DateUtils class.
public String getUTCTime(){
long nowAsPerDeviceTimeZone = 0;
SntpClient sntpClient = new SntpClient();
if (sntpClient.requestTime("0.de.pool.ntp.org", 30000)) {
nowAsPerDeviceTimeZone = sntpClient.getNtpTime();
Calendar cal = Calendar.getInstance();
TimeZone timeZoneInDevice = cal.getTimeZone();
int differentialOfTimeZones = timeZoneInDevice.getOffset(System.currentTimeMillis());
nowAsPerDeviceTimeZone -= differentialOfTimeZones;
}
return DateUtils.getFormattedDateTime(new Date(nowAsPerDeviceTimeZone));
}
"0.de.pool.ntp.org" NTP-Server time for Germany
Related
I need to calculate if a certain time is between 30 minutes earlier and 20 minutes later than the current time.
Any idea how to do this?
The problem is when the time is 23:50h, for example. So I can't do a simple comparison since 23 is greater than 00. But I must consider it smaller since it's another day.
Example:
Now is 23:45. Testing 23:50.
23:45 - 30 minutes = 23:15.
23:45 + 20 minutes = 00:05.
Is 23:50 between 23:15 and 00:05?
Another example:
Now is 00:05. Testing 00:15.
00:05 - 30 minutes = 23:35.
00:05 + 20 minutes = 00:25.
Is 00:15 between 23:35 and 00:25?
--
minSdkVersion is 22, and this further limits the available solutions.
The easiest way to go is :
Compare Hours separately from minutes.
Or also you can take the Hours, multiply them for 60 and then add the returning value to the minutes amount, that will end up with a "only minute" calculation between the 2 times. You can make whatever operation you need.
The only case you should calculate is that one you are in a different day, but that dipends and what you are trying to accomplish!
CODE IN JAVA (OLD VERSION):
public class Main
{
public static void main(String[] args)
{
//Input TIME
String date = "23.45";
//Calculating the TIME in MINUTES ONLY
int date_m = normalizeTime(date);
//CALCULATE MAX AND MIN TIMES
int max = date_m+20;
int min = date_m-30;
/*
Working like that we don't
need to worry about the day Before or After
*/
//JUST DEBUG PRINTS TO SHOW YOU THAT
System.out.println("MAX TIME : "+max);
System.out.println("MIN TIME : "+min);
//The TIME that has to be tested
String testDate = "23.50";
//Calculating the TIME in MINUTES ONLY
int testDate_m = normalizeTime(testDate);
//JUST A DEBUG PRINT TO SHOW YOU THE TESTED TIME
System.out.println("TESTED TIME : "+testDate_m);
/*
If the testDate_m is Between the MAX and MIN values it's
TRUE else it's FALSE
If needed you can adjust with >= or <=
That doesn't matter for the logic.
*/
if(testDate_m<max && testDate_m>min)
System.out.println("IT IS BETWEEN!");
else
System.out.println("IT ISN'T BETWEEN!");
//DONE!
}
/*
Just a Method to clean up the code:
Basically it will Split the string in HOURS and MINUTES
and it will make a simple operation of : Hour*60(Transforming it to minutes) + minutes
The return is an INT that represent the inserted TIME as a MINUTE ONLY TIME.
If the returned number is more than 24*60 it's the Day Next (don't need to worry about that)
If the returned number is less than 0 it's the Previous Day (don't need to worry about that)
*/
private static int normalizeTime(String time)
{
int h = Integer.parseInt(time.substring(0,2));
int m = Integer.parseInt(time.substring(3,5));
return h*60+m;
}
}
CODE IN JAVA (NEW VERSION) :
public class Main
{
public static void main(String[] args)
{
boolean inTime = true;
//Input TIME
String date = "23.50";
//Calculating the TIME in MINUTES ONLY
int date_m = normalizeTime(date);
//CALCULATE MAX AND MIN TIMES
int max = date_m+20;
int min = date_m-30;
int prevMin = max;
int nextMax = min;
if(min<0)
{
prevMin = 24*60+min;
nextMax = 24*60+max;
}
else if(max>24*60)
{
prevMin = min-24*60;
nextMax = max-24*60;
}
/*
Working like that we don't
need to worry about the day Before or After
*/
//JUST DEBUG PRINTS TO SHOW YOU THAT
System.out.println("Between :"+min+" and "+max);
System.out.println("OR");
System.out.println("Between : "+prevMin+" and "+nextMax);
//The TIME that has to be tested
String testDate = "00.05";
//Calculating the TIME in MINUTES ONLY
int testDate_m = normalizeTime(testDate);
//JUST A DEBUG PRINT TO SHOW YOU THE TESTED TIME
System.out.println("TESTED TIME : "+testDate_m);
/*
If the testDate_m is Between the MAX and MIN values it's
TRUE else it's FALSE
If needed you can adjust with >= or <=
That doesn't matter for the logic.
*/
if((testDate_m<max && testDate_m>min) || (testDate_m<nextMax && testDate_m>prevMin))
System.out.println("IT IS BETWEEN!");
else
System.out.println("IT ISN'T BETWEEN!");
//DONE!
}
/*
Just a Method to clean up the code:
Basically it will Split the string in HOURS and MINUTES
and it will make a simple operation of : Hour*60(Transforming it to minutes) + minutes
The return is an INT that represent the inserted TIME as a MINUTE ONLY TIME.
If the returned number is more than 24*60 it's the Day Next (don't need to worry about that)
If the returned number is less than 0 it's the Previous Day (don't need to worry about that)
*/
private static int normalizeTime(String time)
{
int h = Integer.parseInt(time.substring(0,2));
int m = Integer.parseInt(time.substring(3,5));
return h*60+m;
}
}
The easiest way is just to work with timestamps.
long time = new Date().getTime();
long thiry_earlier = time - minutes_to_ms(30);
long twenty_later = time + minutes_to_ms(20);
if(compare < twenty_later && compare > thirty_earlier) {
//do whatever
}
long minutes_to_ms(long minutes) {
return minutes*60*1000;
}
There's some nicer conversion functions you can use nowdays I'm just too lazy to look them up. But working with raw timestamps makes everything easier for comparisons.
I have an app on the PlayStore and I am building a feature where the user will not see ads more than a specific number in one day.
I am thinking about comparing the current date and time to the previously saved one but haven't find a proper way to do that.
How can I compare date and time to know if 24 hours have passed or not?
Some posts that I found but not helpful:
medium.com
stackoverflow
stackoverflow
tl;dr
[This Answer uses Java syntax. You’ll have to translate to Kotlin syntax.]
if
(
Duration // Represents elapsed time on the scale of hours-minutes-seconds.
.between( // Calculates elapsed time between two points in time.
Instant.parse( "2021-03-23T15:30:57.013678Z" ) , // Last moment when an ad was show.
Instant.now() // Current moment.
) // Returns a `Duration` object.
.toHours() // Extract total number of whole hours from the `Duration` object.
>= 24L // Test if equals-to or greater-than 24 hours.
)
{ show ad }
java.time
You asked:
… know if 24 hours have passed or not?
Use the modern java.time classes defined in JSR 310. The java.time classes are built into Android 26 and later. Most of the functionality is available in earlier Android using the latest tooling’s “API desugaring“.
Instant adShown = Instant.parse( "2021-03-23T15:30:57.013678Z" ) ;
Instant now = Instant.now() ;
Duration d = Duration.between( adShown , now ) ;
long hoursSinceAdShown = d.toHours() ;
if( hoursSinceAdShown >= 24L ) { … show ad }
Record your next ad-showing as text in standard ISO 8601 format.
String output = Instant.now().toString() ;
2021-03-23T15:30:57.013678Z
Your Question asked for two different things:
Once per day
Every 24 hours
The first involves a calendar, dates, and a time zone. The second does not. I showed you code for the second.
You can use a scheduled executor service to trigger from a background thread the next showing of an ad at a specific moment. Search Stack Overflow to learn more as this has been covered many times already.
Use this code to check the current date, Yesterday or Particulardate. Pass Epoch time to this method
// input format (we get a value as Epoch)
private val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
private val outputFormat = SimpleDateFormat("MMM dd")
// have to pass the time value as Epoch time.
private fun calculateDateMonth(time: String): String {
var returnValue = ""
val dateTime = DateTime((time.toLong()) * 1000L)
val inputTime = inputFormat.parse(dateTime.toString())
val convertDateMonth = outputFormat.format(inputTime!!)
val timeInMilliseconds = outputFormat.parse(convertDateMonth)!!
val mTime: Calendar = Calendar.getInstance()
mTime.setTimeInMillis(timeInMilliseconds.time)
val now = Calendar.getInstance()
returnValue = when {
now[Calendar.DATE] == mTime[Calendar.DATE] // check isToday
now[Calendar.DATE] - mTime[Calendar.DATE] == 1 // check Yesterday
else -> convertDateMonth // Month and Date
}
return returnValue
}
i runing this code on android after load a cursor with the query i pass to the adapter, but my date is in long in milliseconds format so i need to format properly before load the adapter!
problem is this code is taking 14 seconds to pass a 50 items load, the problem get worst if i call it inside the adapter getView cause get slow when i scrool, if i take this function out the program runs smoothly
this is call inside my listfragment
private String dateFormatPatternEdited(long timeMS) {
android.text.format.DateFormat df = new android.text.format.DateFormat();
final Calendar eDate = Calendar.getInstance();
Calendar sDate = Calendar.getInstance();
sDate.setTimeInMillis(timeMS);
long daysBetween = 0;
while (sDate.before(eDate)) {
sDate.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
String mDateFormatPattern = FuelTrackerApplication.dateFormat.format(timeMS);
if (daysBetween < 2){
mDateFormatPattern = FuelTrackerApplication.timeFormat.format(timeMS);
} else if(daysBetween < 365){
mDateFormatPattern = df.format(FuelTrackerApplication.dateFormatPattern,timeMS).toString();
}
return mDateFormatPattern;
}
and this is were i initialize the date formats i gonna use its called inside onCreate in FuelTrackerApplication i dont think theres nothing wrong with this
public void initializeDateFormat() {
android.text.format.DateFormat df = new android.text.format.DateFormat();
dateFormatPattern = "MMM dd";
if (android.os.Build.VERSION.SDK_INT >= 18){
dateFormatPattern = df.getBestDateTimePattern(Locale.getDefault(), dateFormatPattern);
}
dateFormat = df.getMediumDateFormat(getApplicationContext());
timeFormat = df.getTimeFormat(getApplicationContext());
dateFormat2 = df.getLongDateFormat(getApplicationContext());
}
Ok just a few things. Depending on how long ago your dates are going back. You are only interested if the days between go more then 365. So if your dates are going back for years, you're doing extra work.
while (sDate.before(eDate) && daysBetween <= 365) {
sDate.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
Will let it break, it means if you have 20 entries going back 5 years, you don't do so much work.
It might be worth while to possibly just check the milliseconds difference. I'm not sure if this is precise enough, but it should work. It means you don't need to loop everything E.g
long millisecondsToday = getMilliseconds;
long timeMs = // you already have this
long millisecondsDifference = millisecondsToday - timeMs;
if (millisecondsDifference < MILLISECONDS_TWO_DAYS) // set a final variable out of this method
// etc
If might also be worth while initialising some of your variables once outside of the method. Like your df, that is being created 50 times, and then just having something set on it. Same with your eDate.
i got this incredible faster and practicaly remove the hole function
instead goes like this
lDateBetween = NOW - timeMS;
if (lDateBetween < DAY)
return FuelTrackerApplication.timeFormat.format(timeMS);
else if (lDateBetween < YEAR)
return df.format(FuelTrackerApplication.dateFormatPattern,timeMS).toString();
else return FuelTrackerApplication.dateFormat.format(timeMS);
all calculation is made using milliseconds i also put 2 final NOW and YEAR, also df and lDateBetween
i think is the fastest i can get!
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;
}
}
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.