problems converting CountDownTimer to my SimpleDateFormat output - java

I have a timer that counts down. I want the displayed format to be 00.00 or "ss.SS". However I haven't made any progress in hours. Without the SimpleDateFormat it displays 01.91 then goes to 01.9. This makes it hard to watch as it flickers to keep the view centered. All I really want is a way to keep the format 01.90 and not allow the 0 to be dropped. Could I accomplish this with my original code without the SimpleDateFormat?
/*
* This is my original code before I tried the SimpleDateFormat
*
* This code is fully functional and works good, it just keeps dropping the 0 every
* 10 milliseconds and makes the view shake
*
* getTimeSecs() could return 5, 10, 15, 30, 90 seconds converted to milliseconds
* getCountDownInterval() returns 10
*
*/
public void createTimer() {
myCounter = new CountDownTimer(getTimeSecs(), getCountDownInterval()) {
public void onTick(long millisUntilFinished) {
timerIsRunning = true;
if(millisUntilFinished < 10000) {
TVcountDown.setText("0" + ((millisUntilFinished / 10) / 100.0));
} else {
TVcountDown.setText("" + ((millisUntilFinished / 10) / 100.0));
}
} //end onTick()
#Override
public void onFinish() {
timerIsRunning = false;
TVcountDown.setBackgroundColor(myRes.getColor(R.color.solid_red));
TVcountDown.setTextColor(myRes.getColor(R.color.white));
TVcountDown.setText("Expired");
// Make sure vibrate feature is enabled
if(wantsVib == true) {
vib.vibrate(300);
}
} //end onFinish()
}.start();
} //end createTimer()
Here is my code after trying the SimpleDateFormat
public void createTimer() {
myCounter = new CountDownTimer(getTimeSecs(), getCountDownInterval()) {
public void onTick(long millisUntilFinished) {
timerIsRunning = true;
long current = (long) ((millisUntilFinished / 10) / 100.0);
TVcountDown.setText("" + timerDisplay.format(current));
}
#Override
public void onFinish() {
timerIsRunning = false;
TVcountDown.setBackgroundColor(myRes.getColor(R.color.solid_red));
TVcountDown.setTextColor(myRes.getColor(R.color.white));
TVcountDown.setText("Expired");
// Make sure vibrate feature is enabled
if(wantsVib == true) {
vib.vibrate(300);
}
}
}.start();
} //end createTimer()
I know! I don't even think I'm close to getting it with the SimpleDateFormat and I'm getting frustrated. It runs, but counts down only seconds, on the milliseconds side. So 15 seconds shows 00.15 not 15.00.
I don't expect someone to code it all out for me just need pointed in the right direction. All the tutorials I can find involve years, days, and such and I can't grasp the concept from that.
I'd prefer not to use the SimpleDateFormat -- cuz it hasn't been to simple for me -- and just use my original code and add a zero to the end of the milliseconds side every 10 milliseconds.
Thanks in advance.

Try this:
TVcountDown.setText(convertToMyFormat(millisUntilFinished));
and convertToMyFormat() method:
public String convertToMyFormat(long ms) {
String secString, msecString;
//constructing the sec format:
int sec = (int) (ms / 1000);
if(sec < 10) secString = "0"+sec;
else if(sec == 0) secString = "00";
else secString = ""+sec;
//constructing the msec format:
int msec = (int) ((ms-(sec*1000))/10.0);
if(msec < 10) msecString = "0"+msec;
else if(msec == 0) msecString = "00";
else msecString = ""+msec;
return secString+":"+msecString;
}
I'm not sure if I did the msec part correctly but you can tweek it as you want.

convert the number to a string and it will keep formatting. additionally you can do something like this
public String NumToStr(long i){
if (i < 10 ) {
return ("0" + Long.toString(i));
}
return Long.toString(i);
}
to make sure "9" will always come back as "09". Now set the string to the text.
actually what might be easier is this
if(millisUntilFinished < 10000) {
TVcountDown.setText("0" + Long.toString((millisUntilFinished / 10) / 100.0));
} else {
TVcountDown.setText("" + Long.toString((millisUntilFinished / 10) / 100.0));
}
Use Float.toString() or Double.toString, or whatever you need. Dont be afraid to write a little function to edit the string to make it appear as you want if you need to.
public String KeepFirstTwoCharOfString(String string){
//code to store first two Char into string
// return the string containing only first 2 chars
}

Related

How to convert CRON string to ScheduleExpression in Java?

I got this problem:
I have a text field,
There should be a CRON expression written, and later on saved.
Now I need a method to convert the CRON string (here are some random examples: http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/crontrigger.html) to java ScheduleExpression (http://docs.oracle.com/javaee/6/api/javax/ejb/ScheduleExpression.html)
But, I have no idea how to do it...
I have a timer based execution system, that run only on days, weeks and months, but now I need to implement the CRON models, so that the executions can be run on a specific period of time...
here is a little code, just to back me up:
#Resource
private TimerService timerService;
#Timeout
public void execute(Timer timer) {
Script s = (Script) timer.getInfo();
execute(s, true);
System.out.println("Timer Service : " + s.getScriptId());
System.out.println("Current Time : " + new Date());
System.out.println("Next Timeout : " + timer.getNextTimeout());
System.out.println("Time Remaining : " + timer.getTimeRemaining());
System.out.println("____________________________________________");
Date today = new Date();
if (s.getTimerSetup().getEndDate() <= today.getTime()) {
stopTimer(s);
}
}
#Override
public void startTimer(Script s) {
if (s.getTimerSetup().getTimerRepeat().equals("0")) {
return;
}
s.setStatus(true);
em.merge(s);
em.flush();
if (s.getTimerSetup().getEndDate() > System.currentTimeMillis()) {
long timeOut = 1L;
String timerRepeat = s.getTimerSetup().getTimerRepeat();
if (timerRepeat.equals("1")) {// day
timeOut = 1000L * 60L * 60L * 24L;
} else if (timerRepeat.equals("2")) {// week
timeOut = 1000L * 60L * 60L * 24L * 7L;
} else if (timerRepeat.equals("3")) {// month
timeOut = 1000L * 60L * 60L * 24L * 30L;
} else {
return; //Here is the part where the cron string is detected
}
long initialTimeOut = s.getTimerSetup().getStartDate() - System.currentTimeMillis();
if (initialTimeOut < 0) {
long initCheck = initialTimeOut * -1;
while (initCheck > timeOut) {
initCheck -= timeOut;
}
initialTimeOut = timeOut - initCheck;
}
Boolean found = false;
if (timerService.getAllTimers().size() == 0) {
System.out.println("Started the timer for the script: " + s.getFileName());
timerService.createTimer(initialTimeOut, timeOut, s);
} else {
for (Timer timer : timerService.getAllTimers()) {
if (((Script) timer.getInfo()).getScriptId() == s.getScriptId()) {
System.out.println("This script's timer was already started!");
found = true;
}
}
if (!found) {
System.out.println("Started the timer for the script: " + s.getFileName());
timerService.createTimer(initialTimeOut, timeOut, s);
found = true;
}
}
} else {
System.out.println("The script's end date has expired");
}
}
I marked the place where the cron string is detected (in the if statement)
And I need now to transform the string to a ScheduleExpression.
And after that to run it with the normal timers. (but that comes later :))
Please help. Thanks in advance.
I found the answer, but forgot to answer it, here is the code that worked for me:
private ScheduleExpression parseCronExpressionToScheduleExpression(String cronExpression) {
if ("never".equals(cronExpression)) {
return null;
}
// parsing it more or less like cron does, at least supporting same fields (+ seconds)
final String[] parts = cronExpression.split(" ");
final ScheduleExpression scheduleExpression;
if (parts.length != 6 && parts.length != 5) {
scheduleExpression = scheduleAliases.get(cronExpression);
if (scheduleExpression == null) {
throw new IllegalArgumentException(cronExpression + " doesn't have 5 or 6 segments as excepted");
}
return scheduleExpression;
} else if (parts.length == 6) { // enriched cron with seconds
return new ScheduleExpression()
.second(parts[0])
.minute(parts[1])
.hour(parts[2])
.dayOfMonth(parts[3])
.month(parts[4])
.dayOfWeek(parts[5]);
}
// cron
return new ScheduleExpression()
.minute(parts[0])
.hour(parts[1])
.dayOfMonth(parts[2])
.month(parts[3])
.dayOfWeek(parts[4]);
}
So, if you send the cron expression to the function, it will make a shedule expression out of it, but it does not work 100% on all cron expressions but on most
Here is what worked for the individual positions in the cron expression
* works
- works
, works
/ works
last works (only in the part Day Of Month)
What does not work are the letters, such as L, and the others, at least not when I last checked.
Hope this will help the next guy :)

Java - Subtract 32 from a number in a specific amount of time

I was wondering... Is there a way that I could subtract 32 from a number in a specific amount of time? Such as 500 mils?
If you could help out, it would be great!
Thanks!
public void update() {
x += dx;
if(this.y % 32 == 0) {
this.tileY = this.y / 32;
}
if(this.x % 32 == 0) {
this.tileX = this.x / 32;
}
System.out.println(tileX);
}
public void moveLeft () {
// subtract 32 dx in 500 ms
}
Well, here is a lovely code I've developed for you. I've added the keyword static to be able to call it from main without creating any objects, but it does not use anything from a static context.
As my comments through the code try to explain, this isn't the perfect solution, it's just a start, you may face issues such as multi-threading errors (if you decide to use a separate Thread to update the position) or slight timing issues if the body of the method takes a while to execute.
If you feel the nanosecond precision is a bit too much for your purposes, remember there is also Thread.sleep(int milis).
Here is the code (try changing the values calling moveLeft(int, int) to see the results):
public class Slider {
public static void main(String[] args) {
Thread thread = new Thread() {
#Override
public void run() {
/*
* If you are going to use something like this, beware you are multi-threading
* Make sure what you do is thread-safe
*/
moveLeft(32, 500);
}
};
thread.start();
}
public static void moveLeft(int distance, int milis) {
//time_px is how many nanoseconds the Thread can sleep until it has to move 1 dx
double time_px = (100000*milis)/distance;
if (time_px >= 1) {
//Get the milis and nanos, rounding for Thread.sleep
long time_round = (long) Math.floor(time_px);
long milis_sleep = time_round/100000;
System.out.print("Waiting " + milis_sleep + "ms ");
int nano_sleep = (int) (time_round%100000);
System.out.println(nano_sleep + "ns per dx");
for (int i=0; i<distance; i++) {
try {
Thread.sleep(milis_sleep, nano_sleep);
/*
* Your code here
* A long code here might not get you the desired result since the sleeping does
* not account for the time spent processing the code. But this is a good start
*/
System.out.println("moving 1 dx");
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
else {
System.out.println("Cannot go that fast");
//If you are moving that fast (more than 1 dx per nanosecond) then you need to change this up a little.
}
}
}

GameLoop, What To Put For Delta?

I was just wondering for a quick question, what do you put in for delta exactly. The parameter double delta is (as the developer stated, in seconds of logic updates). If I wanted the loop to run 20 times a second, would I have it set to .2 or something like that? I am a bit confused on the logic updates (in seconds) part.
Anyways if you want to check any more of the game loops provided then check out the page here http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/
public abstract class GameLoop
{
private boolean runFlag = false;
/**
* Begin the game loop
* #param delta time between logic updates (in seconds)
*/
public void run(double delta)
{
runFlag = true;
startup();
// convert the time to seconds
double nextTime = (double)System.nanoTime() / 1000000000.0;
while(runFlag)
{
// convert the time to seconds
double currTime = (double)System.nanoTime() / 1000000000.0;
if(currTime >= nextTime)
{
// assign the time for the next update
nextTime += delta;
update();
draw();
}
else
{
// calculate the time to sleep
int sleepTime = (int)(1000.0 * (nextTime - currTime));
// sanity check
if(sleepTime > 0)
{
// sleep until the next update
try
{
Thread.sleep(sleepTime);
}
catch(InterruptedException e)
{
// do nothing
}
}
}
}
shutdown();
}
public void stop()
{
runFlag = false;
}
public abstract void startup();
public abstract void shutdown();
public abstract void update();
public abstract void draw();
}
You input the time in milliseconds that a single logic-loop should be based on.
If you want 20 times per second then 1/20 second is the number which is not 0.2 but 0.05.
You can write it more intuitively (IMO) by writing "1.0 / 20" then you don't have to convert back and forth and can just replace 20 with the frequency.

Parsing user time input in Java/GWT

What is the best way to parse time that a user typed in a text field in GWT? Default time formats require users to enter time exactly as the time format for locale specifies it.
I want to be more flexible as there are many different ways users can enter time. For example, entries like "8", "8p", "8pm", "8.15pm", "13:15", "1315", "13.15" should be valid.
I ended up with my own method that I want to share. This method returns time in milliseconds, which can be displayed using any data formats for the selected locale.
Any suggestions to improve it are highly appreciated.
EDIT: Improved following suggestions in comments.
public static Long parseTime(String value) {
// ";" is a common typo - we are not punishing users for it
value = value.trim().toLowerCase().replace(";", ":");
RegExp time12 = RegExp.compile("^(1[012]|[1-9])([:.][0-5][0-9])?(\\s)?(a|p|am|pm)?$");
RegExp time24 = RegExp.compile("^(([01]?[0-9]|2[0-3])[:.]?([0-5][0-9])?)$");
if (time12.test(value) || time24.test(value)) {
String hours = "0", minutes = "0";
if (value.contains(":") || value.contains(".")) {
String[] values = value.split("[:.]");
hours = values[0];
minutes = values[1].substring(0, 2);
} else {
// Process strings like "8", "8p", "8pm", "2300"
if (value.contains("a")) {
hours = value.substring(0, value.indexOf("a")).trim();
} else if (value.contains("p")) {
hours = value.substring(0, value.indexOf("p")).trim();
} else if (value.length() < 3) {
hours = value;
} else {
hours = value.substring(0, value.length() - 2);
minutes = value.substring(value.length() - 2);
}
}
if (value.contains("a") && hours.equals("12")) {
// 12am is actually zero hours
hours = "0";
}
Long time = (Long.valueOf(hours) * 60 + Long.valueOf(minutes)) * 60 * 1000;
if (value.contains("p") && !hours.equals("12")) {
// "pm" adds 12 hours to the total, except for 12pm
time += 12 * 60 * 60 * 1000;
}
return time;
}
return null;
}

Easy way to show Decimal of Long via CountDownTimer - Android

I have working code but it seems a bit strange that I have to gimmick my way around showing a decimal place on CountDownTimer but I haven't found anything that does it easier (obviously).
Here is the working Code I currently have:
final String tempTitle = TextView.getText().toString();
new CountDownTimer(10000, 100) {
public void onTick(long millisUntilFinished) {
String timeDown = String.valueOf(millisUntilFinished / 100);
String secTime="0";
String sec10th="0";
if (Long.valueOf(millisUntilFinished) < 1000) {
secTime ="0";
sec10th = timeDown.substring(0,1);
}else{
secTime=timeDown.substring(0,1);
sec10th = timeDown.substring(1,2);
}
TextView.setText("Start in: " + secTime + "." + sec10th);
}
public void onFinish() {
TextView.setText(tempTitle);
}
}.start();
}
divide by 100.0 so you dont do integer division.
Edit per your comment:
you could do
DecimalFormat df=new DecimalFormat("#.##"); //import java.text.DecimalFormat;
String timeDown=df.format(millisUntilFinished/100.0);
or #.### etc depending on how many decimals you want...

Categories

Resources