Time difference calculation issues - java

I have a table called by name Symbols in my Application which will be updated continously for every 8 minutes
Each record inside the Symbol table has got a attribute by name updated-at and whose value is in timestamp as shown
"updated_at" : NumberLong("1375715967249")
I have a task to show the updated data to the users from the symbols table
In case the symbol is not updated for 9 minutes , i need to executed a particular task and if updated a different task
I was following this logic , please let me know if this has got any loop holes ?? ( I mean like day like settings --- or any such )
package com;
public class UnixTimeConversion {
public static void main(String args[]) {
long timeStamp = 1375715967249l;
java.util.Date date = new java.util.Date();
long currtime = date.getTime();
if ((currtime - timeStamp) > 600000) {
System.out.println("Greater than 10 minutes since executed");
} else {
System.out.println("Lesser than 10 minutes since executed");
}
}
}

Better to try in this way
long timeStamp = 1375715967249l;
long currTime = System.currentTimeMillis();
if ((currTime - timeStamp) > 10*60*1000) {
System.out.println("Greater than 10 minutes since executed");
} else {
System.out.println("Lesser than 10 minutes since executed");
}
10min = 10*60*1000 ms

UNIX timestamps don't care about Timezones, UTC leap seconds or anything. It's just a number linearly measuring the passing of time. If you don't care about wallclock time either, there's no problem. You just have to take care that you convert your source material to UNIX timestamps in the right manner.

Related

how to count the seconds in java?

I'm trying to understand how I could go about keeping track of the seconds that an object has been created for.
The program I'm working on with simulates a grocery store.
Some of the foods posses the trait to spoil after a set amount of time and this is all done in a subclass of an item class called groceryItem. The seconds do not need to be printed but are kept track of using a currentTime field and I don't quite understand how to count the seconds exactly.
I was looking at using the Java.util.Timer or the Java.util.Date library maybe but I don't fully understand how to use them for my issue.
I don't really have a very good understanding of java but any help would be appreciated.
You can use either long values with milliseconds since epoch, or java.util.Date objects (which internally uses long values with milliseconds since epoch, but are easier to display/debug).
// Using millis
class MyObj {
private final long createdMillis = System.currentTimeMillis();
public int getAgeInSeconds() {
long nowMillis = System.currentTimeMillis();
return (int)((nowMillis - this.createdMillis) / 1000);
}
}
// Using Date
class MyObj {
private final Date createdDate = new java.util.Date();
public int getAgeInSeconds() {
java.util.Date now = new java.util.Date();
return (int)((now.getTime() - this.createdDate.getTime()) / 1000);
}
}
When you create your object call.
Date startDate = new Date();
After you are done call;
Date endDate = new Date();
The number of seconds elapsed is:
int numSeconds = (int)((endDate.getTime() - startDate.getTime()) / 1000);

Possible to make #currentTimeMillis a constant? when a value is added to it?

So I'm trying to make the System.currentTimeMillis(); a constant. It's difficult to explain this. What the code is supposed to do is add a value to the System.currentTimeMillis(); which it does and wait till the code returns true and then execute an action. So basically, I'm trying to make a "temp-ban" system. Because System.currentTimeMillis isn't a constant value, of course, this is going to return false. I'm wondering what would I exactly do to make this code become true
long timeleft = StaticMaps.muteMap.get(uuid).getTime() * 1000; //seconds to miliseconds
if (System.currentTimeMillis() >= timeleft + System.currentTimeMillis()) {
plugin.mutemanager.destructPlayerMute(uuid, "Expired", "Removed by Console, Expired!");
} else {
KTools.notify("debug");
e.setCancelled(true);
}
Solution I used
Store the value as a "Long" inside a map with the System.currentTimeMillis();
So what you would do is.
Map<UUID, Long> temp = new HashMap<>();
Long time = 3 * 1000; //3 * 1000 = 3 Seconds
temp.put(Identifier, System.currentTimeMillis() + timetoadd)
timetoadd needs to be a long.
Then check if System.currentTimeMillis() is >= the value in the hashmap.
long HOUR = 3600000;
long DAY = 86400000;
long dayformula = Long.parseLong(parts[0]) * DAY;
long hourformula = Long.parseLong(parts[1]) * HOUR;
long totalmiliseconds = dayformula + hourformula;
You don't want to make that into a constant. You want to store off its value for a given moment in time and use that to check against the current system time.
That's easily accomplished thus:
long timeleft = StaticMaps.muteMap.get(uuid).getTime() * 1000; //seconds to miliseconds
long lastCheckedTime = System.currentTimeMillis();
if (System.currentTimeMillis() >= timeleft + lastCheckedTime) {
plugin.mutemanager.destructPlayerMute(uuid, "Expired", "Removed by Console, Expired!");
} else {
KTools.notify("debug");
e.setCancelled(true);
}
...although to be fair, that statement is almost guaranteed to be false unless timeLeft is on the order of microseconds.
You can't make System.currentTimeMillis(); a constant (var/value) because that's not a var/value, but rather a function that returns one.
What you want to do is save timestamps of the current time (using that), plus ban/mute time, into a map, and then either schedule the lift of the ban/unmute, or manage it yourself by periodically checking System.currentTimeMillis(); and if it's past (above) any expected ban-lift/unmute time (the ones you saved), applying the necessary actions (lifting ban or unmuting).
I'm currently on my phone, and I can't give an example of the schedule method out of my (not very reliable) memory...
But, if it's the managed one, I can try:
//How to "schedule" the lift...
public /*static ?*/ void mutePlayer(??? uuid, long muteTime){
StaticMaps.muteMap.put(uuid, System.currentTimeMillis()+muteTime); //I'm assuming how the syntax is...Adapt as needed.
}
//Somewhere else, inside a loop that runs periodically...
for(Entry<uuid, long> scheduled : Staticamaps.muteMap.entrySet()){
if (System.currentTimeMillis() >= scheduled.value() /*lift timestamp*/)) {
plugin.mutemanager.destructPlayerMute(scheduled.key() /*uuid*/, "Expired", "Mute has expired!");
} else {
KTools.notify("debug");
e.setCancelled(true);
}
}
Note that, since I can't know the syntax or the functions available to muteMap, some of the ones I used should be considered pseudo-code.

Combining Human Time with Computer Time into Synthetic Time

I am trying to write a high data rate UDP streaming interface simulator/tester in Java 8 to a realtime machine that has a very accurate time processor card. Every message has a time field in it and this field is in microseconds resolution. The interface relies on the high resolution time processor for packet ordering. The interface relies on the high precision time card which I don't have and need to simulate out of the equation. I figured I could get away with using something like this:
TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
It does work but after running for extended periods of time I found UDP bites me because I send a couple hundred packets out of order with the same exact time stamp and the other side of the interface can't tell that the packets it received were out of order. The interface is tolerant of this to an extent but this isn't really an issue on the real system with the high precision clocks.
To mitigate this I have added a sense of synthetic microseconds to my currentTimeMillis() as follows:
class TimeFactory {
private long prev;
private long incr;
public long now() {
final long now = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
long synthNow = now;
if(now == prev) {
if(incr < 999) {
incr += 1;
}
synthNow += incr;
} else {
incr = 0;
}
prev = now;
return synthNow;
}
}
Has anyone ever dealt with synthetic time like this? Is there any other way to tighten this code up or even a better way to handle this (using nanoTime somehow)? If I ever did send more then 999 packets would it be safe to increment into the milliseconds range (ie: increment + 1000 or more)? It looks like I am getting around ~10-15ms difference between currentTimeMillis() calls but I'm sure this is very system dependent.
In case anyone is interested here is what I ended up with to work around the lack of a high resolution system clock. It will give me a synthetic microseconds counter that increments until either System.currentTimeMillis() returns an updated value or you have called this 999 times. In practice I have only seen a maximum of ~500 increments. It doesn't look like I will have worry about spilling into the millisecond range.
I'm still open to other more realistic result alternatives.
public class SyntheticMicrosClock extends Clock {
private final ZoneId zone;
private long prev;
private long incr;
SyntheticMicrosClock (ZoneId zone) {
this.zone = zone;
}
#Override
public ZoneId getZone() {
return zone;
}
#Override
public Clock withZone(ZoneId zone) {
if (zone.equals(this.zone)) { // intentional NPE
return this;
}
return new SyntheticMicrosClock(zone);
}
public long micros() {
final long now = TimeUnit.MILLISECONDS.toMicros(millis());
long synthNow = now;
if(now == prev) {
if(incr < 999) {
incr += 1;
}
synthNow += incr;
} else {
incr = 0;
}
prev = now;
return synthNow;
}
#Override
public long millis() {
return System.currentTimeMillis();
}
#Override
public Instant instant() {
return Instant.ofEpochSecond(0, micros());
}
}
To use it I inject my synthetic Clock where I need it. Ex:
Clock synthClock = Inject or new SynthClock(ZoneOffset.UTC);
Instant.now(synthClock);
Do you need a timestamp or just a high resolution increasing number that it time based? If so, you might be able to use System.nanoTime.
There were issues with this call in early JVM's/OS' but they seem to have been addressed (see first answer here).
Of course there's that odd chance that it might loop around on you. Don't know what kind of flexibility you have with your protocol, but there should be ways to deal with that.
Building on what #Bill suggested, you have 200+ years of resolution with nanoTime, so why not store nanoTime on init, currentTimeMillis on init, then add the difference of nanoTime and initNanoTime to initCurrentTimeMillis to get an augmented, high-precision timestamp? Once you detect clock skew between this augmented clock and the real one over 100ms, or so, you can reinit.

Wrong time is displayed after date math

I have an application that tracks the wait time of a customer in a restaurant. It simply subtracts the time the customer began waiting from the current time, then formats it with StandardDateFormat into hh:mm and displays it as a string.
The problem is that the timer always begins with 6 hours, such as 06:01.
ActionListener actListner = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
aTable.updateTime();
}
};
Timer timer = new Timer(1000, actListner);
timer.start();
}
This is in the main program
public void updateTime()
{
data.updateTime();
fireTableDataChanged();
fireTableRowsInserted(data.name.size() - 1, data.name.size() - 1);
}
This is in the table model
public void updateTime()
{
Date newTime = new Date();
for (int i = 0; i < startTime.size(); i++)
{
this.setTimeWaiting(i, hoursMin.format(new Date(newTime.getTime() - startTime.get(i).getTime())));
}
}
public void setTimeWaiting(int index, Object newVar)
{
timeWaiting.remove(index);
timeWaiting.add(index, newVar.toString());
}
This is in the data model.
Every time a new row is added it puts the time the row is added in one column then the time that person has been waiting in the other column, but the waiting column is 6 hours ahead. It otherwise works fine.
This sounds like a timezone issue. Maybe you should set the timezone for the date format to UTC.
As k_g says, this is almost certainly a time zone issue. You are getting funny results because the Date class is intended for absolute times, not intervals.
I would recommend you use a library like Joda Time. It has special classes for concepts such as Intervals and Durations.
Or if you are using JDK 8 you can use the new date/time classes that have just been introduced.

Android (Java) count down timer into text

Basically, I have a count down timer right? And I need to display the time left for the timer in text. I have done that, but the timer's time is a bit off, as it needs to convert the seconds left into hours and minutes, like on a regular digital watch where it says 00:05:00 and it counts down to 00:04:59. I've done a lot of things today and my head is hurting quite a bit at the moment, so I can't exactly think about it. So my guess is that I need to use multiples of 60. Help?
Code:
int timeinminutes=1;
new CountDownTimer(timeinminutes*100000, 1000) {
TextView mTextField = (TextView) findViewById(R.id.textView1);
public void onTick(long millisUntilFinished) {
long hrs=0;
long mnts=0;
long scnds=0;
scnds=(millisUntilFinished/1000);
if (scnds>59) {
mnts=(scnds/60);
if (mnts!=Math.floor(mnts)) {
mnts=0;
}
}
if (mnts>59) {
hrs=(mnts/60);
if (hrs!=Math.floor(hrs)) {
hrs=0;
}
}
mTextField.setText(hrs + ":" + mnts + ":" + scnds);
}
public void onFinish() {
mTextField.setText("00:00:00");
}
}.start();
A lot of this has already been done. If you read about SimpleDateFormat it should help you get on your way to solving this.
You can find more information here as well.
Check out java.util.Timer here.
These should solve any of your problems.
You should have a separate class that does the count-down and keeps the remaining time in milliseconds as a field. The class could have a method that launches a Thread which sleeps 1000 milliseconds, then subtracts 1000 from the original time in milliseconds until the remaining time is 0.
You then could use another Thread which updates the TextView every 1000 milliseconds and a SimpleDateFormat to get the remaining time from the countdowntimer object and format it.

Categories

Resources