Android countdown, is this the correct way? - java

I got this. But i can't seem to work out how to get the number of days/hours/minutes/seconds left. I ran it in debug mode and it produced: 2776799998. 2776799998 in milliseconds is way to much for 2 days, 1 hour and 15 minutes. (Was when posting this).
What is the correct way?
Calendar cal = Calendar.getInstance();
cal.set(2012, 6, 28, 16, 0);
long endTime = cal.getTimeInMillis();
long currentTime = System.currentTimeMillis();
long remaining = endTime - currentTime;
long seconds = remaining / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;

From Calendar's javadoc:
Month value is 0-based. e.g., 0 for January.

The month on the Calendar API starts in 0. So 6 corresponds to July. Maybe that's your problem.

Related

Current Time In Java(Logic Error) Time Zone: US Eastern Time

I seem to have a logic error in my code. The time now is: 14:38, but
my code says 18:38. I know there's a Calendar class I could use, but I want to
know why this code was wrong.
Code below:
public class welcome{
public static void main(String args[]){
//get total milliseconds since 1970
long total_millisec = System.currentTimeMillis();
// compute total seconds since 1970
long total_sec = total_millisec / 1000;
//compute current second
long current_sec = total_sec % 60;
//compute total minutes since epoch
long total_mins = total_sec / 60;
//compute current minute
long current_min = total_mins % 60;
//compute total hours
long total_hours = total_mins / 60;
//compute current hour
long current_hour = total_hours % 24;
System.out.println("Time is: "+current_hour+":"+current_min+":"
+current_sec);
}
}
When you perform your calculation, it's presumed that System.currentTimeMillis() returns difference in milliseconds between midnight of 1st January of 1970 (which is 1970-01-01 00:00) and current time. Try to evaluate the base date in your system and see what it'll be:
System.out.println("" + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm").format(new java.util.Date(0)));
it might return something like 1969-12-31 19:00 and this is not the midnight.
System.currentTimeMillis() returns the same as expression:
long currentTime = new java.util.Date().getTime() - new java.util.Date(0).getTime();

Java Time API - A better way to get total elapsed time

This is my first oportunity to play with the "new" java.time package from Java 8.
I need to get the total elapsed time, something like:
1 day, 2h:3m:4s 5ms
I know that have 2 TemporalAmount implementations for intervals:
- Period for years, months and days
- Duration for hours, minutes, seconds, milliseconds and nanoseconds
There's a way to mix these two or something more straightforward than "do math"?
That was the best I could do until now:
(Updated with a new improved version)
LocalDateTime start = LocalDateTime.now();
// Forcing a long time execution to measure
LocalDateTime end = start
.plusDays(1)
.plusHours(2)
.plusMinutes(3)
.plusSeconds(4)
.plusNanos(5000);
LocalDateTime elapsed = end
.minusDays(start.getDayOfYear())
.minusHours(start.getHour())
.minusMinutes(start.getMinute())
.minusSeconds(start.getSecond())
.minusNanos(start.getNano());
Period period = Period.between(start.toLocalDate(), end.toLocalDate());
long days = period.getDays();
long hours = elapsed.getHour();
long minutes = elapsed.getMinute();
long seconds = elapsed.getSecond();
long milliseconds = elapsed.getNano() / 1000;
StringBuilder msg = new StringBuilder();
msg.append(seconds);
msg.append("s ");
msg.append(milliseconds);
msg.append("ms");
if(minutes > 0) {
msg.insert(0, "m:");
msg.insert(0, minutes);
}
if(hours > 0) {
msg.insert(0, "h:");
msg.insert(0, hours);
}
if(days > 0) {
msg.insert(0, days == 1 ? " day, " : " days, ");
msg.insert(0, days);
}
System.out.println(msg.toString());
Thanks for your time =)
Seems like you need the PeriodFormatter from JodaTime. See below links:
How to format a duration in java? (e.g format H:MM:SS)
Formatting a Duration in Java 8 / jsr310
Given these two, I suggest using JodaTime for Duration.

Seconds between two dates, limited to variable working hours

I need to get the amount of seconds between two dates, and only during working hours (ex 0800-1600).
Any suggestions on how to do this in Java?
long seconds = ((datenow.getTime() - datethen.getTime()) / 1000);
You could use something like this:
public static void main(String[] args) {
Calendar cal1 = Calendar.getInstance();
cal1.set(2011, 10, 10, 12, 00, 00);
Date datenow = cal1.getTime();
Calendar cal2 = Calendar.getInstance();
cal2.set(2011, 10, 14, 15, 00, 00);
Date datethen = cal2.getTime();
// check for weekends
long daynow = TimeUnit.MILLISECONDS.toDays(datenow.getTime());
long daythen = TimeUnit.MILLISECONDS.toDays(datethen.getTime());
long daydiff = daythen - daynow;
long weekenddiff = daydiff / 7; // number of weekends
if (cal1.get(Calendar.DAY_OF_WEEK) > cal2.get(Calendar.DAY_OF_WEEK)) {
weekenddiff++;// we have a weekend but not another full week;
}
long secDiff = TimeUnit.SECONDS.convert(16, TimeUnit.HOURS);
long weekendAdditionalSecDiff = TimeUnit.SECONDS.convert(16, TimeUnit.HOURS); // 16 additional hours for the weekend
// 16 non-work hours between two shifts
daydiff *= secDiff;
daydiff += (weekenddiff * weekendAdditionalSecDiff);
long workDiffSeconds = TimeUnit.SECONDS.convert(
datethen.getTime() - datenow.getTime(),
TimeUnit.MILLISECONDS) - daydiff;
System.out.println("Difference in working hours is "
+ workDiffSeconds + " seconds");
System.out.println("Difference in working hours is "
+ TimeUnit.HOURS.convert(workDiffSeconds, TimeUnit.SECONDS) + " hours");
}
which first calculates the number of days between your days and subtracts the number of non-work-time-seconds from the real difference.
For the weekends, 8 additional non-work-hours per day are added.
When I did this, I found it easiest to take two dates, start and end.
Then express each in seconds.
Then find midnight of each date by taking the mod of each and 86400 (seconds per day).
And then it's easy figure from there. The key was to locate the end points of the interval at midnight.
Use something like Joda Time, (but it can be solved without).
Assuming day_now < date_then.
Figure the answer for day_now (datenow to midnight of datenow)
Figure the answer for day_then (midnight of day before then to datethen)
Figure out the number of days in between.
Combine 1, 2, and 3

How to convert getTime to seconds?

Can you please help in matter:
I have defined a variable which is:
Time from_time = rs.getTime("nfrm_time");
and it will read the values 7:15:00
How to convert this type to seconds?
Call getTime to get the number of milliseconds since January 1, 1970. Divide by 1000 to get it in seconds:
long unixTime = from_time.getTime() / 1000;
To get the number of seconds since 00:00 of the current day, use the
Calendar c = Calendar();
c.setTime(from_time);
long daySeconds = (c.get(Calendar.SECONDS) +
c.get(Calendar.MINUTES) * 60 +
c.get(Calendar.HOURS) * 3600);
long seconds = rs.getTime("nfrm_time").getTime() / 1000
Here's the explanation:
rs.getTime("nfrm_time") returns java.sql.Time which is actually a sub class of java.util.Date.
java.util.Date.getTime() returns time in milli seconds which we divide by 1000 to get seconds.
Note:
If you're looking for duration instead,
Calendar cal = Calendar.getInstance();
cal.setTime(rs.getTime("nfrm_time")); // set to the time returned by resultset
cal.set(0, 0, 0); // reset the year, month and date fields
Calendar cal2 = Calendar.getInstance();
cal2.set(0, 0, 0, 0, 0, 0); // reset all the fields, including time
long duration = ((cal.getTimeInMillis() - cal2.getTimeInMillis()) / 1000) + 1;
Try:
from_time.getTime() / 1000
This might work since:
The date components should be set to the "zero epoch" value of January 1, 1970 and should not be accessed.
This means that the date part is always the epoch day, which means the Time instance is represented by the number of milliseconds since the beginning of the day.
java.sql.Time inherits from java.util.Date which has a method getTime() which returns the number of milliseconds since January 1, 1970, 00:00:00 GMT.
So from_time.getTime()/1000 should do the trick.
Cleaner way is
Time from_time = Math.round(rs.getTime("nfrm_time")/1000);
To get the milliseconds:
long ms = from_time.getTime();

milliseconds until next 5th second

So I want to do some monitoring and I want it to be on every fifth minute, so for example if the application starts at 1:47 monitor everything until 1:50 and then reset. I currently have this working for hour but I need to cut it down to every fifth minute and I'm having a little trouble coming up with the math.
I get all of the current time information
Calendar currentCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
long currentTimeInMillis = currentCalendar.getTimeInMillis();
int hr = currentCalendar.get(Calendar.HOUR_OF_DAY);
int min = currentCalendar.get(Calendar.MINUTE);
int sec = currentCalendar.get(Calendar.SECOND);
int millis = currentCalendar.get(Calendar.MILLISECOND);
Now I need to find the next fifth minute, for hour I have this which works.
millisUntilNextHour = currentTimeInMillis + ((60L - min) * SECONDS_IN_MINUTE * 1000L) + ((60 - sec) * 1000L) + (1000L - millis);
Can anybody think of a way similar to above to get the milliseconds to the closest fifth minute?
Every fifth minute is 5 minutes * 60 seconds/minute * 1000 millisecond/second = 300,000 milliseconds.
Try this then:
millisUntilNextHour = (min*60*1000 + sec*1000 + millis + 299999)/300000*300000 - (min*60*1000 + sec*1000 + millis)
The +299999)/300000*300000 rounds up to the nearest 300,000. Then you get the difference between that and the current millisecond to find out how many milliseconds you are away from it.
Using the same approach as described in the question:
Calendar currentCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
int min = currentCalendar.get(Calendar.MINUTE);
currentCalendar.set(Calendar.MINUTE, 5 * (min / 5 + 1));
currentCalendar.set(Calendar.SECOND, 0);
currentCalendar.set(Calendar.MILLISECOND, 0);
millisUntilNextHour = currentCalendar.getTimeInMillis();
Update:
Reverted to my initial variant. It works as a charm. Lenient calendar (currentCalendar is lenient) works perfectly as expected when setting as minutes value greater than 60. From javadoc:
/**
* With lenient interpretation, a date such as "February 942, 1996" will be
* treated as being equivalent to the 941st day after February 1, 1996.
* With strict (non-lenient) interpretation, such dates will cause an exception to be
* thrown. The default is lenient.
*/
Why not use Quartz, which can handle this sort of thing easily. For the above you could specify a cron-type expression.
It may seem a bit heavyweight for your initial requirements but it's scaleable so it'll handle any future requirements.
Add five minutes to the current time, then set the seconds and millis to zero.
Note that the important thing is to use the .add(field, amount) method, as it will roll correctly into the next hour, etc. (including daylight savings, etc).
Calendar currentCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
// store off the milliseconds from the epoch
int startTime = currentCalendar.getTime().getTime();
currentCalendar.add(Calendar.MINUTE, 5);
currentCalendar.set(Calendar.SECOND, 0);
currentCalendar.set(Calendar.MILLISECOND, 0);
// calculate the milliseconds difference.
int difference = currentCalendar.getTime().getTime() - startTime;
System.out.println("The number of milliseconds till " + currentCalendar.getTime() + " is " + startTime);

Categories