How do I add time to a timestamp? - java

I need to add 14 minutes and 59 seconds to an unknown time in an array. How do I do this? This is what I have so far:
Date duration = df.parse("0000-00-00 00:14:59");
arrayOpportunity[2] = arrayOpportunity[2] + duration;
The time is not being changed. Thanks!
I have done my research. I cant paste the entire code I have. But mainly I didnt want to make you read it all. Just looking for a simple answer of how to add two timestamps.

If you are talking about a java.sql.Timestamp, it has a method called setTime. java.util.Date has a setTime method as well for that sort of thing.
You could something like this:
static final Long duration = ((14 * 60) + 59) * 1000;
oldTimestamp.setTime(oldTimestamp.getTime() + duration);

If you want to add time in millis then you can just add
(((14 * 60) + 59) * 1000) <-- Mili second value of 14 m and 59 sec

If you just want to add times, I suggest using Joda Time.
The class LocalTime lets you add durations like this:
LocalTime timeSum = time.plusMinutes(14).plusSeconds(59);

Just add the appropriate number of milliseconds using #getTime() and #setTime():
timeStamp.setTime(timeStamp.getTime() + (((14 * 60) + 59)* 1000));

arrayOpportunity[2] = arrayOpportunity[2] + 14*60*1000 + 59*1000;
The Date object you have may work, but it doesn't really represent 14 minutes and 59 seconds, it just represents a particular time in calendar (eg. 14 minutes 59 after the epoch start which is 1st January 1970 00:14:59).

Related

Effectively getting time unit with Joda

I am looking for a neat solution to get the time units in Java 7 ( or using Joda date time)
Like, to 65 minutes, it should say 1 hour 5 minutes
To 30 minutes, it should just say 30 minutes
Thanks.
You can use joda time's normalizedStandard to print your output too.
Per the doc,
Normalizes this period using standard rules, assuming a 12 month year,
7 day week, 24 hour day, 60 minute hour and 60 second minute.
An example for 65 minutes would be:
System.out.println(PeriodFormat.getDefault().print(Period.hours(0).plusMinutes(65).plusSeconds(0).normalizedStandard()));
Output:
1 hour and 5 minutes
Short answer, use org.joda.time.Period.
For example, a general purpose solution might be to have a method that takes the number of milliseconds and returns a String of the form:
X hours, X minutes, X seconds, X milliseconds
public class DateTimeUtils {
public static String toNicePeriodValue(Period period) {
return period.getHours() + "hours " +
period.getMinutes() + "minutes " +
period.getSeconds() + "seconds " +
period.getMillis() + "milliseconds";
}
}
An easy way to create a Period object is like this:
public String nicePeriodValueFromMillis(long timeInMillis) {
Period period = new Period(timeInMillis);
String ret = DateTimeUtils.toNicePeriodValue(period);
return ret;
}
And invoke it like this:
long timeInMillis = /* obtain somehow */
String nicePeriodValue = nicePeriodValue(timeInMillis);
System.out.println("Nice Period Value: " + nicePeriodValue);
This is not, of course, a complete solution, but it should get you started.
If your input is always minutes use the modulus operator % 60 to find remaining minutes and / 60 to find hours.

Compare Timestamp with another Timestamp object

I'm newer to Java. I'm using two Timestamp objects dateFrom and dateTo. I want to check whether the dateFrom is 45 days earlier than dateTo. I used this code fragment to compare this
if(dateFrom.compareTo(dateTo) < 45)
{
// do the action;
}
I'm confusing with the 45 given in the code. Can I expect the correct result. will it meets my result.
compareTo() returns a value of -1, 0 or 1, depending on the result.
What you want to do is
long result = dateTo.getTime() - (1000 * 60 * 60 * 24 * 45) - dateFrom.getTime();
if(result >= 0) {
System.out.println("dateFrom is 45 days or more before dateTo");
else {
System.out.println("dateFrom is less than 45 days before dateTo");
}
This is rather ugly though. Is there a specific reason you're not using a Calendar?
You have to think about it a bit logically. First of all you need to get to a timestamp which is 45 days before the dateTo date. Time has various units (seconds, minutes, hours, days) so just checking < 45 is meaningless in this case. The compareTo() method is just there for ordering to know if a timestamp is before or after the other.
You could first create a Calendar for the timestamps, and add() dateFrom by 45 days. Then you can use the before() method to check if dateFrom is before dateTo.
Use Joda Time or Calendar class(add 45 days to dateFrom, compare the result with dateTo).
Do like this
Date dateFrom ="your from date";
Calendar cal = GregorianCalendar.getInstance();
cal .setTime(dateFrom);
cal.add(Calendar.DAY_OF_MONTH, 45);
Date expireDate = cal.getTime();
Date dateTo = new Date();
if(dateTo.after(expireDate)){
}
Since Timestamp in Java is number of milliseconds from UNIX Epoch - change 45 days to number of milliseconds (45d=45*24h=45*24*3600s=45*24*3600*1000ms) so if:
(time_B + 45*24*3600*1000) >= time_A
it means that time_B is 45 days (or more) 'further' in time that time_A
Of course you can use JodaTime and other libs too.

Android Calendar is not giving expected results

I am passing values to calendar instance, but don't know why it is not performing as expected. I want to add one day to a specific date and then use that date.
Log.v("data going to calendar==",
"year="+Integer.parseInt(fy)+
"month="+Integer.parseInt(fm)-1)+
"day="+Integer.parseInt(fd)+
"hh="+Integer.parseInt(fh)+
"mm="+Integer.parseInt(fmn));
c.set(
Integer.parseInt(fd),
Integer.parseInt(fm)-1,
Integer.parseInt(fy),
Integer.parseInt(fh),
Integer.parseInt(fmn));
c.add(Calendar.DAY_OF_MONTH,1);
Log.v("data coming from calendar==",
"year = " + c.get(Calendar.YEAR)+
"month ="+ c.get(Calendar.MONTH)+
"day ="+c.get(Calendar.DATE)+
"hh="+c.get(Calendar.HOUR)+
"mm="+c.get(Calendar.MINUTE));
output is:
data gng to calendar==year = 2013month =7day =29hh=12mm=0
data cmng from calendar==year = 35month =1day =4hh=0mm=0
i run that code by putting comment on code to add one day, but the results are still same except for day, it means adding one day is working perfectly --->
year = 35month =1day =3hh=0mm=0
You call the set() method with the wrong parameters. According to the documentation the order must be year, month, date as first three parameters and you call it with date, month, year as the first parameters.
If you change your code to
c.set(Integer.parseInt(fy),
Integer.parseInt(fm)-1,
Integer.parseInt(fd),
Integer.parseInt(fh),
Integer.parseInt(fmn));
it should work as intended.
The strange values are because it treats 2013 as the day which is approx. 6 years that are added to the date.
If you want to add a day - 24 hours - to a date, add it as milliseconds: 1 day = 24 * 60 * 60 * 1000 milliseconds.
Calendar c = Calendar.getInstance();
//Set calendar's fields here
long time = c.getTimeInMilliseconds();
long nextDay = time + 24 * 60 * 60 * 1000;
c.setTimeInMillis(nextDay);

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);

Java Date problems, finding the date X days ago

Date nowdate = new Date();
long nowms = nowdate.getTime();
long differencems = numdaysback * 24 * 60 * 60 * 1000;
long thenms = nowms - differencems;
Date thendate = new Date(thenms);
If numdaysback is 365, then I would suppose that thendate would be one year ago. but it's not... it's about three weeks ago?!?
NUMDAYSBACK: 365
NOWDATE: Wed Jun 22 20:31:58 SGT 2011
NOWMS: 1308745918625
DIFFERENCEMS: 1471228928
THENMS: 1307274689697
THENDATE: Sun Jun 05 19:51:29 SGT 2011
How about:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
Date thendate = cal.getTime();
Returns the same time of day regardless of DST or leap years, is shorter and clearer...
Generally Calendar is the way to go in such cases (unless you use a 3rd party library like Joda Time). You can use it for all kinds of calculations: add N days/hours/months/seconds, truncate time to a whole hour etc. - stuff that would be too much pain with long only.
Regarding your original question, it seems to be a victim of integer overflow. It works if the multiplication explicitly uses long:
long differencems = 365 * 24 * 60 * 60 * 1000L;
If you are using Java 8 and up, you can use the newer java.time library to do this a bit more cleanly.
Date xDaysAgo = Date.from( Instant.now().minus( Duration.ofDays( x ) ) );
Just try this:
long differencems = numdaysback * 24L * 60 * 60 * 1000;
With the new code you will not loose the digits due to integer multiplication.
Since we have marked the literal 24 as long, the multiplication will be done by auto converting the first operand numdaysback into long. The rest of the multiplication will also be done on long operands.
This line:
long differencems = numdaysback * 24 * 60 * 60 * 1000;
the RHS should be: 31536000000. You have something much less, the reason being the RHS is being evaluated as an int (as all the quantities are ints), and you are exceeding MAX_INT. To correct to this:
long differencems = numdaysback * 24 * 60 * 60 * 1000l;
Note the "l" which makes 1000 be a long - now the RHS will be evaluated as a long.
The Date class is (informally) deprecated. The API has so many faults, that it is really difficult to get Dates/Times right with it. The easiest example is something like your code for differencems. It fails, if the time inbetween contains a daylight savings switch (if you don't use UT) and will always fail to take care of leap seconds.
If your application depends on correct dates, you might want to use Joda Time.

Categories