Introduction
I'm trying to get the difference in seconds from two Epochs
i.e
2019-05-22 18:28:56 -> 1558542536 seconds
2019-07-22 19:00:00 -> 1563814800 seconds
The diff will be: 5,272,264 seconds
This date format comes from a binary file as a String
My code
public static void main(String[] args) throws ParseException
{
String regEpoch = "";
long result = 0;
//System.out.println((fecha = dateFormat.format(date)));
try(RandomAccessFile raf = new RandomAccessFile("binario2.txt", "rw")){
//user inputs a code (for now, doesn't matter if exists or not)
System.out.print("Input a code to look for: ");
String code = scan.next();
while(!code.matches("\\d+"))
{
System.out.println("[ERROR] Only digits accepted");
System.out.print("Input a code to look for: ");
code = scan.next();
}
//Gets the current date in seconds
long getSecs = (new Date().getTime())/1000;
System.out.println("Current tiem in secs: " + getSecs);
//We are "randomly accessing" a binary file. The is no problem here at all. It just works.
//Sets the pointer where I want it, again... this works fine.
raf.seek(27+(80*Integer.parseInt(code)));
//Read the String date correctly, which is 2019-05-22 18:28:56
System.out.println(raf.readUTF());
/*
//Attempt 2
System.out.println(java.time.Instant.ofEpochSecond(Long.parseLong(raf.readUTF())));
Long millis = new SimpleDateFormat("yyyy/MM/ss hh:mm:ss").parse(raf.readUTF()).getTime();
System.out.println(millis);
*/
//Let's try to convert it into seconds... No we can't due to -> Unparseable date: "2019-05-22 18:28:56"
Date dt = dateFormat.parse(raf.readUTF());
long epoch = dt.getTime();
System.out.println("Result is: " + (int)(epoch*1000));
}catch(IOException e){System.out.println("[ERROR] " + e);}
}
Problem
I have read many questions in how to turn seconds into Epoch, but what about the reverse?
Do I have to do it manually?
Is there any library I haven't heard of?
So far what I tried only gets the seconds from the Date with SimpleDateFormat but those are not what I expected...
What do I expect from this
I am currently doing homework and I have been task with calculating the price for a parking ticket and I thought, what if the car doesn't leave, let's say... in a week?
If I work only in the format of hh:mm:ss those cars who stay there a whole week will only pay for one day.
ChronoUnit
I always use ChronoUnit for calculations like this. Works fine.
package test;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class Test2 {
public static void main(String[] args) throws ParseException {
LocalDateTime date1 = LocalDateTime.parse("2019-05-22T18:58:56");
LocalDateTime date2 = LocalDateTime.parse("2019-05-23T19:00:00"); //LocalDateTime.now();
long seconds = ChronoUnit.SECONDS.between(date1, date2);
System.out.println(seconds);
}
}
Output
86464
For converting to date with SimpleDateFormat, you can see e.g. Java time since the epoch
Duration
Let java.time classes calculate a Duration.
Parse your input after adjusting to standard ISO 8601 format.
LocalDateTime ldtStart = LocalDateTime.parse( "2019-05-22 18:28:56".replace( " " , "T" ) ) ;
Time zone
Specify the time zone, to account for anomalies such as Daylight Saving a Time (DST). Days are not always 24 hours long.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtStart = ldtStart.atZone( z ) ;
Calculate a duration.
Duration d = Duration.between( zdtStart , zdtStop ) ;
long seconds = d.toSeconds() ; // Or `getSeconds` before Java 9.
For parking charges, you more likely want hours.
long hours = d.toHours() ;
This should work
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-05-22 18:28:56").getTime();
Related
i have data like this one
date what i got from timestamp utc are : 2020-06-29 05:31:58.153
LocalDateTime timestampasstring = message.getHeader().getUtcTimeStamp( SendingTime.FIELD);
Timestamp timestamp = Timestamp.from(timestampasstring.toInstant(ZoneOffset.UTC));
System.out.println(timestamp);
String timestampstrings = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timestamp);
String timestampstrings2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(timestamp);
i need to get timestamp number like 2020-06-29 05:31:58
and convert it become unix timestamp like this one 1593408718
how to convert it ?
If your getUtcTimeStamp method is helpful enough to return a LocalDateTime, you're most of the way there. Convert to an Instant using ldt.atOffset(ZoneOffset.UTC) (your getUtcTimeStamp really should be doing this for you if it already knows it's in UTC), then just call toEpochSecond() (or toEpochMilli() if you want the milliseconds part, but you just showed whole seconds).
Having read your question, I assume your method message.getHeader().getUtcTimeStamp(SendingTime.FIELD) returns a String (not a LocalDateTime) representing a timestamp in UTC while being formatted either like 2020-06-29 05:31:58.153 or 2020-06-29 05:31:58.
Since you have (shown) differently formatted datetimes (respectively, datetimes with a different accuracy), you will have to take care of that by defining a suitable DateTimeFormatter using a pattern able to deal with optional milliseconds (yyyy-MM-dd HH:mm:ss[.SSS]).
You can use it as follows:
public static void main(String[] args) {
// receive the result from your message, this is just an example
String utcTimestamp = "2020-06-29 05:31:58";
// create a ZonedDateTime by parsing the String to a LocalDateTime and adding a time zone
ZonedDateTime zdt = LocalDateTime.parse(utcTimestamp,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSS]"))
.atZone(ZoneId.of("UTC"));
// then get the epoch milliseconds / unix timestamp
long millis = zdt.toInstant().toEpochMilli();
// and print the result
System.out.println(zdt + " ==> " + millis + " epoch millis");
}
The output of this is, of course, different for datetimes that are only equal down to seconds:
2020-06-29T05:31:58Z[UTC] ==> 1593408718000 epoch millis
2020-06-29T05:31:58.153Z[UTC] ==> 1593408718153 epoch millis
If you call long seconds = zdt.toEpochSeconds() instead of converting toInstant().toEpochMillis (and adjust the output a little) you will get the same value for both examples:
public static void main(String[] args) {
// receive the result from your message, this is just an example
String utcTimestamp = "2020-06-29 05:31:58.153";
// create a ZonedDateTime by parsing the String to a LocalDateTime and adding a time zone
ZonedDateTime zdt = LocalDateTime.parse(utcTimestamp,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSS]"))
.atZone(ZoneId.of("UTC"));
// then get the epoch seconds
long seconds = zdt.toEpochSecond();
// and print the result
System.out.println(zdt + "\t==>\t" + seconds + " epoch seconds");
}
Output:
2020-06-29T05:31:58Z[UTC] ==> 1593408718 epoch seconds
2020-06-29T05:31:58.153Z[UTC] ==> 1593408718 epoch seconds
If your method really returns a LocalDateTime, you could simply skip conversions and write
public static void main(String[] args) {
LocalDateTime utcDateTime = message.getHeader().getUtcTimeStamp(SendingTime.FIELD);
// then get the epoch seconds
long seconds = utcDateTime.atZone(ZoneId.of("UTC")).toEpochSecond();
// and print the result
System.out.println(utcDateTime + "\t==>\t" + seconds + " epoch seconds");
}
The other answers are fine. Here’s my variant. First declare a formatter for parsing:
private DateTimeFormatter timestampFormatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
Consider declaring the formatter static and/or final. With this formatter I’d do:
String timestampAsString = "2020-06-29 05:31:58.153";
OffsetDateTime dateTime = LocalDateTime
.parse(timestampAsString, timestampFormatter)
.atOffset(ZoneOffset.UTC);
long unixTimestamp = dateTime.toEpochSecond();
System.out.println(unixTimestamp);
Output is what you asked for:
1593408718
The nice thing about the formatter is that it accepts both 2020-06-29 05:31:58.153 and 2020-06-29 05:31:58, that is, time both with and without fraction of second, and with any fraction of from 1 up to 9 decimals. Reusing ISO_LOCAL_TIME in the formatter buys us this.
In my application one of third party API returning timestamp in epoch.
Sometime it returns epoch time in seconds and sometime in miliseconds not confirmed. My application using below code to
convert it to java date and display to user but when I am receiving time in miliseconds it is failing on year.
String time = "1519377196185"; //Time in miliseconds
//String time = "1521575819"; //Time in seconds.
String timeZone = "US/Pacific";
long epochdate = Long.parseLong(time);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy hh:mm a");
LocalDateTime date34 =
Instant.ofEpochSecond(epochdate)
.atZone(ZoneId.of(timeZone))
.toLocalDateTime();
String date = date34.format(formatter).toString();
System.out.println("date : " + date);
if I use Instant.ofEpochMilli(epochdate) for miliseconds then it is working fine. So my question is how I can know that coming timestamp is in miliseconds or seconds so on that basis I will switch between ofEpochMilli and ofEpochSecond
Year Offset
I would try to parse first the date as seconds, given that if the date is in millis the year would be something extremely big (in this case 50000), then if the year is not greater than the year defined offset (e.g. 3000), that date is returned, otherwise the date is returned as millis.
public ZonedDateTime getZonedDateTime(String time) {
long longTime = Long.parseLong(time), yearOffset = 3000L;
String timeZone = "US/Pacific";
ZoneId zoneId = ZoneId.of(timeZone);
ZonedDateTime zdt = Instant.ofEpochSecond(longTime).atZone(zoneId);
if (zdt.getLong(ChronoField.YEAR_OF_ERA) >= yearOffset) {
return Instant.ofEpochMilli(longTime).atZone(zoneId);
} else {
return zdt;
}
}
Using the functions prints:
getZonedDateTime("1519377196185"); // 2018-02-23T01:13:16.185-08:00[US/Pacific]
getZonedDateTime("1521575819"); // 2018-03-20T12:56:59-07:00[US/Pacific]
Margin of Error
Any method that you decide to use, would have the possibility of an error and that the date is transformed incorrectly, specially when the date is in milliseconds and is too close of the epoch 1970-01-01T00:00:00Z.
The margin errors using the year offset of 3000 would be:
When the date is originally in milliseconds in the range from 1970-01-01T00:00:00Z until 1971-01-12T04:48:00Z
Would be considered as date in seconds
When the date is originally in seconds and the date is equal or after 3000-01-01T00:00:00Z (improbable date in normal apps)
Would be considered as date in milliseconds
Calculate the range of error in milliseconds dates
You can calculate the range of error for dates originally in milliseconds with:
Instant.ofEpochMilli(LocalDateTime.of(3000, 1, 1, 0, 0) // year = 3000
.toEpochSecond(ZoneOffset.UTC)); // 1971-01-12T04:48:00Z
One easy (temporary, sort of) solution would be to just check the length of your time String. If the length is equal to 13, then it represents milliseconds. This will be true until 1 ms after 2286-11-20T17:46:39.999Z, which is a long time from now. The time in seconds would take even more time to reach a length of 13.
Inspect length of String input
As stated by Jacob G. his Answer, check the length.
String input = "1519377196185"; // Milliseconds since epoch.
//String input = "1519377196" ; // Seconds since epoch.
Instant instant = null;
int length = input.length();
switch ( length )
{
case 13:
instant = Instant.ofEpochMilli( Long.parseLong( input ) );
break;
case 10:
instant = Instant.ofEpochSecond( Long.parseLong( input ) );
break;
default:
throw new IllegalStateException( "Unexpected length of input text for count-from-epoch number: " + input + ". Message # 2188d054-5720-4393-9b18-829913d7ba1c." );
}
System.out.println( input + " ➞ " + instant.toString() ); // Generate a String representing textually the value of the `Instant` object.
1519377196185 ➞ 2018-02-23T09:13:16.185Z
Or:
1519377196 ➞ 2018-02-23T09:13:16Z
ZonedDateTime
To move from UTC in an Instant to some particular time zone, provide the context of a time zone (ZoneId) to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString(): 2018-02-23T10:13:16.185+01:00[Africa/Tunis]
LocalDateTime - not appropriate here
The LocalDateTime class is the wrong class to use, as seen in the Question. This class purposely lacks any concept of time zone or offset-from-UTC. So it does not represent a moment, and is not a point on the timeline. This class represents potential moments along a range of about 26-27 hours.
Use LocalDateTime only when the zone/offset is unknown (a terrible situation) or when you need an indefinite value such as “Christmas starts on first moment of December 25, 2018”.
You can solve this other way by converting epoch in seconds to epoch in milliseconds and apply only Instant.ofEpochMilli() for both:
String time = "1519377196185"; //Time in miliseconds or seconds
if(time.length() == 10) { // length of epoch in seconds is 10
time = time + "000";
}
String timeZone = "US/Pacific";
long epochdate = Long.parseLong(time);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy hh:mm a");
LocalDateTime date34 = Instant.ofEpochMilli(time)
.atZone(ZoneId.of(timeZone))
.toLocalDateTime();
String date = date34.format(formatter).toString();
System.out.println("date: " + date);
I want to calculate the time difference (duration) between two hours (HH:mm:ss) in Java. Here, I've read several topics on this subject, but my problem is a little bit different.
I'm not able to use Joda-Time, as well.
Example:
input values: 12:03:00
00:00:00
expected output: 11:57:00
Сode:
public static void main(String[] args) throws ParseException {
Scanner sc = new Scanner(System.in);
String startTime = sc.next();
String endTime = sc.next();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Date d1 = sdf.parse(startTime);
Date d2 = sdf.parse(endTime);
long elapsed = d2.getTime() - d1.getTime();
String hms = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(elapsed),
TimeUnit.MILLISECONDS.toMinutes(elapsed) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(elapsed)),
TimeUnit.MILLISECONDS.toSeconds(elapsed) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsed)));
if (elapsed > 0) {
System.out.println(hms);
} else {
elapsed = elapsed * (-1); //otherwise, print hours with '-'
String hms1 = String.format("%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(elapsed),
TimeUnit.MILLISECONDS.toMinutes(elapsed) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(elapsed)),
TimeUnit.MILLISECONDS.toSeconds(elapsed) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsed)));
System.out.println(hms1);
}
}
Result:
expected output: 11:57:00
actual output: 12:03:00 //that's the problem
tl;dr
Duration.between(
LocalTime.parse( "12:03:00" ) ,
LocalTime.parse( "23:59:59.999999999" )
).plusNanos( 1 ).withNanos( 0 )
PT11H57M
Use a nanosecond
The modern approach uses the java.time classes.
The catch is that for time-of-day only, there is no midnight. So your 00:00 which you apparently intended for end-of-day is actually interpreted as start-of-day.
There is only the last nanosecond before the day ends. The LocalTime has a constant defined for that last nanosecond: LocalTime.MAX = 23:59:59.999999999
Since you care only about whole seconds, we can take advantage of that fractional second. If your ending time happens to be 00:00:00, substitute LocalTime.MAX. Then calculate a Duration object. You can add a single nanosecond and then truncate the resulting fractional second by setting the fractional second (the nanoseconds) to zero.
For ending times other than 00:00:00, the math still works. Adding a nanosecond gets you ….000000001 fraction of second, and Duration::withNanos will truncate that unwanted fraction.
// This code assumes the inputs are *always* in whole seconds, without any fraction-of-second.
LocalTime start = LocalTime.parse( "12:03:00" );
LocalTime stop = LocalTime.parse( "00:00:00" );
if( stop.equals( LocalTime.MIN ) ) {
stop = LocalTime.MAX ; // `23:59:59.999999999`
}
Duration d = Duration.between( start , stop );
d = d.plusNanos( 1 ).withNanos( 0 ) ;
System.out.println( "start/stop: " + start + "/" + stop );
System.out.println( "d: " + d );
See this code run live at IdeOne.com.
PT11H57M
Formatting
The output from toString is standard ISO 8601 format. The Duration class can parse such strings as well as generate them.
I strongly recommend not representing a span of time in time-of-day style, HH:MM:SS. This is ambiguous and often creates confusion when read by humans.
But if you insist on that format you must build the string yourself. The Duration class lacks a format method seen in other java.time class. Oddly, this class originally lacked methods to extract the parts, a number of days, of hours, of minutes, of seconds, and a fractional second. See this Question for discussion. Java 9 brings such methods, named to…Part.
While using Java 8, I suggest doing string manipulation of the ISO 8601 formatted output. Replace the PT with empty string. If there is an M, replace H with a colon. If there is an S, replace the M with a colon and replace the S with empty string. If no S, replace M with empty string. I believe you can find this code posted on Stack Overflow.
The basic flaw here is that you want the NEAREST distance between two times. When you are constructing your date objects, even though you only format for Hour:Minute:Second it still stores the day/month/year etc... For the dates 12:03:00 and 00:00:00 it defaults them to the same day, so the difference from (Midnight to Noon) is what your getting not (Noon to Midnight) of the next day. The solution for you would be to check if the times are less than 12 (military time) and if so add 1 to the day.
Here's How you do it:
String t1 = "12:03:00";
String t2 = "00:00:00";
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Date d1 = sdf.parse(t1);
Date d2 = sdf.parse(t2);
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(d1);
c2.setTime(d2);
if(c2.get(Calendar.HOUR_OF_DAY) < 12) {
c2.set(Calendar.DAY_OF_YEAR, c2.get(Calendar.DAY_OF_YEAR) + 1);
}
long elapsed = c2.getTimeInMillis() - c1.getTimeInMillis();
Is this what you want to do:
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class HourTest {
public static void main(String[] args) throws Exception {
LocalDateTime ldt1 = LocalDateTime.parse("2015-05-04T12:07:00");
LocalDateTime ldt2 = LocalDateTime.parse("2015-05-04T00:00:00");
long seconds = Math.abs(ChronoUnit.SECONDS.between(ldt1, ldt2));
String hms = String.format("%02d:%02d:%02d", seconds / 3600, (seconds / 60) % 60, seconds % 60);
// Prints 12:07:00. I tried it.
System.out.println(hms);
}
}
You can use java.time.Duration which is modelled on ISO-8601 standards and was introduced with Java-8 as part of JSR-310 implementation. With Java-9 some more convenient methods were introduced.
Demo:
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class Main {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalTime startTime = LocalTime.parse("12:03:00");
LocalTime endTime = LocalTime.parse("00:00:00");
LocalDateTime startDateTime = today.atTime(startTime);
LocalDateTime endDateTime = today.atTime(endTime);
if (startDateTime.isAfter(endDateTime)) {
endDateTime = endDateTime.with(LocalTime.MIN).plusDays(1).with(endTime);
}
Duration duration = Duration.between(startDateTime, endDateTime);
// Default format
System.out.println(duration);
// Custom format
// ####################################Java-8####################################
String formattedDuration = String.format("%02d:%02d:%02d", duration.toHours(), duration.toMinutes() % 60,
duration.toSeconds() % 60);
System.out.println(formattedDuration);
// ##############################################################################
// ####################################Java-9####################################
formattedDuration = String.format("%02d:%02d:%02d", duration.toHoursPart(), duration.toMinutesPart(),
duration.toSecondsPart());
System.out.println(formattedDuration);
// ##############################################################################
}
}
Output:
PT11H57M
11:57:00
11:57:00
Learn about the modern date-time API from Trail: Date Time.
For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I have this problem with calculating time difference in minutes.
Its working fine with exampples like calculating the difference between
2045 and 2300.
But when I want to calculate the difference between for example
2330 (today) and 0245 (tomorrow) I get a incorrect answer.
Code below:
// This example works
String dateStart = "2045";
String dateStop = "2300";
// This example doesnt work
//String dateStart = "2330";
//String dateStop = "0245";
// Custom date format
SimpleDateFormat format = new SimpleDateFormat("HHmm");
Date d1 = null;
Date d2 = null;
try {
d1 = format.parse(dateStart);
d2 = format.parse(dateStop);
} catch (Exception e) {
e.printStackTrace();
}
long diff = d2.getTime() - d1.getTime();
long minutes = TimeUnit.MILLISECONDS.toMinutes(diff);
System.out.println("Time in minutes: " + minutes + " minutes.");
Thanks in advance
Consider using LocalDate, LocalDateTime, LocalTime ZonedDateTime classes from java.time.* package introduced in Java 8. They are very handy in use as they can address various corner cases (e.g. measuring minutes across different time zones, or during autumn and spring time change).
The thing to you need to know when you calculate time difference is that:
LocalTime contains time only
LocalDate contains date only (no time)
LocalDateTime contains both (date + time.)
ZonedDateTime contains date + time + timezone
This implies that difference between times will be different when you compare with:
LocalTime you can diff only time so 20:45 and 23:30 gives 2:45 of difference
LocalDate you cannot calculate any time diffs (contains no time)
LocalDateTime you can specify date and time, e.g.: 20:45 on 1Jan and 23:30 on 3Jan . Time difference will be 2:45 and 2 days of difference, or 50:45.
ZonedDateTime - same as LocalDateTime plus you takes into account DayLightSavings, so if the clock is changed overnight - it will get reflected.
Here is a snippet for a LocalDateTime:
LocalDateTime today2045 = LocalDateTime.of(
LocalDate.now(),
LocalTime.parse("20:45"));
LocalDateTime tomorrow0230 = LocalDateTime.of(
LocalDate.now().plusDays(1),
LocalTime.parse("02:30"));
System.out.println("Difference [minutes]: " +
Duration.between(today2045, tomorrow0230).toMinutes());
For ZonedDateTime taking into account spring/autumn clock changes:
ZonedDateTime today2045 = ZonedDateTime.of(
LocalDate.now(),
LocalTime.parse("20:45"),
ZoneId.systemDefault());
ZonedDateTime tomorrow0230 = ZonedDateTime.of(
LocalDate.now().plusDays(1),
LocalTime.parse("02:30"),
ZoneId.systemDefault());
System.out.println("Difference [minutes]: " +
Duration.between(today2045, tomorrow0230).toMinutes());
Some info on constructors can be found in Oracle's tutorial here.
This is not working because when you create a new date with just a time in it, it's assuming the day is "today".
What you could do is:
// This example works
String dateStart = "2045";
String dateStop = "2300";
// This example doesnt work
//String dateStart = "2330";
//String dateStop = "0245";
// Custom date format
SimpleDateFormat format = new SimpleDateFormat("HHmm");
Date d1 = null;
Date d2 = null;
try {
d1 = format.parse(dateStart);
d2 = format.parse(dateStop);
} catch (Exception e) {
e.printStackTrace();
}
// MY ADDITION TO YOUR CODE STARTS HERE
if(d2.before(d1)){
Calendar c = Calendar.getInstance();
c.setTime(d2);
c.add(Calendar.DATE, 1);
d2 = c.getTime();
}
// ENDS HERE
long diff = d2.getTime() - d1.getTime();
long minutes = TimeUnit.MILLISECONDS.toMinutes(diff);
System.out.println("Time in minutes: " + minutes + " minutes.");
But you should consider using Java 8 new Date/Time features, or Joda Time.
You can add if statement to check if this is today, and if no you can add one day to this, since you are comparing time it wont be problem if you add full day
if(d2.before(d1)){
d2.setTime(d2.getTime()+86400000);
}
Try it out
This is a solved problem. If you look at the Joda Time library you'll find all the time and date manipulation functions you could possibly want:
In your case something along the lines of:
DateTime first = new DateTime(larger-time);
DateTime second = new DateTime(smaller-time);
DateTime difference = first.minusMillis(second.getMillis())
Joda will cope with all the odd edge conditions like rolling over between days/months/years, lengths of months, leap years, daylight savings, timezones...
I want to compare two different time stamp using System.currentTimeMillis().
Basically I want to check whether the time stamps are within 3 hours range on a particular day.
How to do this?
Considering you have time1 and time2, where time1 <= time2 you can do this:
if (time1 >= time2-(60*60*3*1000)) {
// interval is up to 3 hours
} else {
// interval is more than 3 hours
}
Use Instant to get the time in the epoch and convert it to LocalDateTime to get the information about the day and check, if the first time plus 3 hours is smaller than the second time:
long millis1 = System.currentTimeMillis();
...
long millis2 = System.currentTimeMillis();
Instant instant1 = Instant.EPOCH.plusMillis(millis1);
Instant instant2 = Instant.EPOCH.plusMillis(millis2);
LocalDateTime t1 = LocalDateTime.ofInstant(instant1, ZoneId.systemDefault());
LocalDateTime t2 = LocalDateTime.ofInstant(instant2, ZoneId.systemDefault());
System.out.println("same day: " + (t1.getDayOfYear() == t2.getDayOfYear()));
System.out.println("t1+3h >= t2: " + (t1.plusHours(3).compareTo(t2) >= 0));
Here is a sample program that might help you out. The crux here is the method "findIfDatesWithinThreeHours" which helps whether to find if two instances are three hours apart.
package com.inrvu.adapter;
import java.util.Calendar;
import java.util.Date;
public class Tester {
public static void main(String[] args) {
Date[] dates = getTwoDatesThreeHoursApart();
System.out.println(String.format("%b", findIfDatesWithinThreeHours(dates[0],dates[1])));
dates = getTwoDatesWithinThreeHours();
System.out.println(String.format("%b", findIfDatesWithinThreeHours(dates[0],dates[1])));
}
public static Date[] getTwoDatesThreeHoursApart()
{
Calendar calendar = Calendar.getInstance();
Date date1 = calendar.getTime();
calendar.add(Calendar.HOUR,4);
Date date2 = calendar.getTime();
return new Date[]{date1,date2};
}
public static Date[] getTwoDatesWithinThreeHours()
{
Calendar calendar = Calendar.getInstance();
Date date1 = calendar.getTime();
calendar.add(Calendar.HOUR,3);
Date date2 = calendar.getTime();
return new Date[]{date1,date2};
}
public static boolean findIfDatesWithinThreeHours(Date date1, Date date2) {
// here the time of a single hour is defined as 60*60*1000
System.out.println(date1);
System.out.println(date2);
return Math.abs(date1.getTime()-date2.getTime()) <= 3*60*60*1000;
}
}
Your Question is vague. This might get you pointed in the right direction.
If by "timestamp" you meant a count of milliseconds since the epoch of 1970 UTC, construct an Instant. This class represents a moment on the timeline in UTC with a resolution of nanoseconds (finer than milliseconds).
Instant instant = Instant.ofEpochMilli( millis );
Get current moment.
Instant now = Instant.now();
Calculate three hours.
Instant in3Hours = now.plus( 3 , ChronoUnit.HOURS );
See if your moment lies between now and three hours later.
Boolean contained = ( ( ! instant.isBefore( now ) ) && instant.isBefore( in3Hours ) );
If you meant you want to compare a pair of moments to see if the elapsed time is less than 3 hours, use a Duration. This class represents a span of time in terms of seconds and nanoseconds.
Instant earlierInstant = … ;
Instant laterInstant = … ;
Duration duration = Duration.between( earlierInstant , laterInstant );
if ( duration.isNegative() ) {
… handle error of unexpected data inputs where the second instant is *before* the first instant.
}
… else …
Boolean elapsedUnderThreeHours = ( duration.compareTo( Duration.ofHours( 3 ) ) == -1 );