Difference of two dates in minutes - java

I have 2 dates in String with format (MMM dd, yyyy hh:mm:ss a).
How to convert two Strings into date and find the difference in minutes ?
DateFormat df = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a", Locale.ENGLISH);
Date start = df.parse(startstring);
Date end = df.parse(endstring);
After I want to take the difference in minutes and I am using this code:
long result = ((end.getTime()/60000) - (start.getTime()/60000));
But the result is 0. How can I solve this problem ?
My Strings are :
start: Fri Mar 07 23:45:43 GMT+04:00 2014
end: Fri Mar 07 23:46:01 GMT+04:00 2014

You could use this approach (first calculate the minutes since epoch, then subtract them) -
private static long getTimeInMinutesFromEpoch(Date d) {
if (d == null) {
return 0;
}
return d.getTime() / (60 * 1000);
}
public static long getMinuteDifference(Date a, Date b) {
return Math.abs(getTimeInMinutesFromEpoch(b)
- getTimeInMinutesFromEpoch(a));
}
public static void main(String[] args) throws ParseException {
String startstring = "Mar 07, 2014 23:45:43 PM";
String endstring = "Mar 07, 2014 23:46:01 PM";
DateFormat df = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a",
Locale.ENGLISH);
Date start = df.parse(endstring);
Date end = df.parse(startstring);
System.out.println(getMinuteDifference(start, end));
}
Output is
1

From the looks of it you're creating the start date immediately before the end date (unless there is non-included relevant information).
Date start = df.parse(startstring);
Date end = df.parse(endstring);
These are going to be created in exactly the same minute and therefore give you 0 when you try to find the difference in minutes.
EDIT
Your times:
start: Fri Mar 07 23:45:43 GMT+04:00 2014
end: Fri Mar 07 23:46:01 GMT+04:00 2014
are 18 seconds apart. You're going to get 0 for the difference in minutes.

You can make Calendar object instead of Date and then you can get the minutes using Calendar.get(Calendar.MINUTE). Note that by using this logic, the difference between 22:45:43 GMT+04:00 2014 and 23:45:43 GMT+04:00 2014 will be zero minutes.

Related

Comparing dates with months as strings

I am trying to compare these two dates :
17 Oct. 2019 (08:23)
19 déc. 2019 (21:15)
The months are in French and the main problem is the months. Do I need to put an if statement for every type of month so I can switch it with the appropriate month? For example:
if (MonthValue.equals("oct."){
DateValue.replace("oct.","10");
}
Or is there an easier solution, because I need to check in a table if the first value is bigger than the second one.
Edit :
My new Code :
String target1 = "17 oct. 2019 (08:23)";
String target2 = "19 déc. 2019 (21:15)";
DateFormat df = new SimpleDateFormat("dd MMM. YYYY (kk:mm)", Locale.FRENCH);
Date result = df.parse(target1);
Date result2 = df.parse(target2);
System.out.println(result);
System.out.println(result2);
if(result.compareTo(result2) < 0) {
System.out.println("true");
}
else {
System.out.println("false");
}
Doesn't work gives this error:
java.text.ParseException: Unparseable date: "17 oct. 2019 (08:23)"
java.time and optional parts in the format pattern string
Like the others I recommend that you use java.time, the modern Java date and time API, for your date and time work. I understand that if your month names are five letters or shorter (for example avril), they are written out in full, whereas if they are seven letters or longer (for example juillet), they are abbreviated. The following formatter can parse in both situations:
private static final DateTimeFormatter DATE_FORMATTER
= new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("dd [MMMM][MMM] uuuu (HH:mm)")
.toFormatter(Locale.FRENCH);
Square brackets [] in the format pattern string surround optional parts. MMMM is for full month name. MMM is for the abbreviation. So the point in [MMMM][MMM] is that it will successfully parse either full month name or abbreviations and just skip the one that doesn’t work. Since you gave an example of Oct. being written with an upper case O, I have also specified that the parsing should not be sensitive to case. If this is not necessary, you may use this simpler formatter:
private static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofPattern("dd [MMMM][MMM] uuuu (HH:mm)", Locale.FRENCH);
In order to check that all months work, I have set up these test data:
String[] dateStrings = {
"17 Oct. 2019 (08:23)",
"19 déc. 2019 (21:15)",
"01 avril 2021 (09:40)",
"08 janv. 2020 (01:18)",
"28 févr. 2021 (21:41)",
"03 mars 2020 (22:54)",
"06 mai 2020 (03:14)",
"21 juin 2020 (07:15)",
"18 juil. 2020 (23:06)",
"06 août 2020 (22:28)",
"29 sept. 2020 (06:04)",
"18 nov. 2019 (01:35)"
};
To parse and compare two of them use LocalDateTime.parse() and .isBefore():
LocalDateTime dateTime1 = LocalDateTime.parse(dateStrings[1], DATE_FORMATTER);
LocalDateTime dateTime2 = LocalDateTime.parse(dateStrings[2], DATE_FORMATTER);
if (dateTime1.isBefore(dateTime2)) {
System.out.format(Locale.FRENCH, "%s is before %s%n", dateTime1, dateTime2);
}
Output:
2019-12-19T21:15 is before 2021-04-01T09:40
For comparison you may also exploit the fact that LocalDateTime implements Comparable. This is practical when sorting the dates and times, for example. As a brief example let’s sort all the LocalDateTime objects that come out of parsing the above strings:
Arrays.stream(dateStrings)
.map(ds -> LocalDateTime.parse(ds, DATE_FORMATTER))
.sorted()
.forEach(System.out::println);
2019-10-17T08:23
2019-11-18T01:35
2019-12-19T21:15
2020-01-08T01:18
2020-03-03T22:54
2020-05-06T03:14
2020-06-21T07:15
2020-07-18T23:06
2020-08-06T22:28
2020-09-29T06:04
2021-02-28T21:41
2021-04-01T09:40
Link: Trail: Date Time (The Java™ Tutorials) explaining how to use java.time.
Using DateTimeFormatter with pattern dd MMM yyyy (HH:mm) to parse the date string like this
String target1 = "17 oct. 2019 (08:23)";
String target2 = "19 déc. 2019 (21:15)";
Locale locale = Locale.FRANCE;
DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder().appendPattern("dd MMM yyyy (HH:mm)")
.toFormatter(locale);
LocalDateTime dateTime1 = LocalDateTime.parse(target1, dateTimeFormatter);
LocalDateTime dateTime2 = LocalDateTime.parse(target2, dateTimeFormatter);
System.out.println(dateTime1);
System.out.println(dateTime2);
if (dateTime1.compareTo(dateTime2) < 0) {
System.out.println("true");
} else {
System.out.println("false");
}
My recommendation:
parse the dates e.g. with a DateTimeFormatter to e.g. a LocalDateTime
compare the parsed dates (most date and time objects implement https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Comparable.html)
What I've got from your question is that you want to convert Month's names to their respective numbers. If this is the case, then you should try switch
Example:
switch (MonthValue){
case jan:
MonthValue = 1; // Set Month variable to it Numbered Position (type casting might be required)
break;
case feb:
MonthValue = 2;
break;
default:
System.out.println("Somthing...");
}
Try encoding to UTF8, which will avoid DateTimeParseException
Exception in thread "main" java.time.format.DateTimeParseException: Text '19 d??c. 2019 (21:15)' could not be parsed at index 3
public static void main(String args[]) throws Exception {
String date1 = "17 oct. 2019 (08:23)";
String date2 = "19 déc. 2019 (21:15)";
DateTimeFormatter longDateTimeFormatter = DateTimeFormatter.ofPattern("dd MMM yyyy (HH:mm)").withLocale(Locale.FRENCH);
LocalDateTime lclDate1 = LocalDateTime.parse(encodeUTF8(date1), longDateTimeFormatter);
LocalDateTime lclDate2 = LocalDateTime.parse(encodeUTF8(date2), longDateTimeFormatter);
if (lclDate1.compareTo(lclDate2) < 0) {
System.out.println("true");
}
else {
System.out.println("false");
}
}
public static String encodeUTF8(String dateStr) {
byte[] bytes = dateStr.getBytes();
String utf8EncodStr = new String(bytes, StandardCharsets.UTF_8);
return utf8EncodStr;
}

Difference in hours of two Calendar objects

I have two Calendar objects, and I want to check what is the difference between them, in hours.
Here is the first Calendar
Calendar c1 = Calendar.getInstance();
And the second Calendar
Calendar c2 = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
c2.setTime(sdf.parse("Sun Feb 22 20:00:00 CET 2015"));
Now lets say that c1.getTime() is: Fri Feb 20 20:00:00 CET 2015 and c2.getTime() is Sun Feb 22 20:00:00 CET 2015.
So is there any code that would return the difference between first and second Calendar in hours? In my case it should return 48.
You can try the following:
long seconds = (c2.getTimeInMillis() - c1.getTimeInMillis()) / 1000;
int hours = (int) (seconds / 3600);
Or using the Joda-Time API's Period class, you can use the constructor public Period(long startInstant, long endInstant) and retrieve the hours field:
Period period = new Period(c1.getTimeInMillis(), c2.getTimeInMillis());
int hours = period.getHours();
In Java 8 you could do
long hours = ChronoUnit.HOURS.between(c1.toInstant(), c2.toInstant());

Simple Date Format parsed then formatted date didn't match

I've run into a strange behavior of SimpleDateFormat, i don't know how to deal with.
I need to parse a date in a specific format (Day of Week, then day, then Month, then Year, Then time).
However, I've run into a behaviour, when parsing a date gives me a very strnge result (other date). Here is a small, self-contained example, and it's output on my machine.
public static void main(String[] args) throws Exception {
test("E YYYY kk:mm:ss");
test("E d YYYY kk:mm:ss");
test("E d MMMM YYYY kk:mm:ss");
}
public static void test(String format) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date now = new Date();
System.out.println(now);
String formattedNow = sdf.format(now);
System.out.println(formattedNow);
Date parsedFormattedNow = sdf.parse(formattedNow);
String formattedParsedNow = sdf.format(parsedFormattedNow);
System.out.println(formattedParsedNow);
System.out.println(formattedNow.equals(formattedParsedNow));
}
Output:
Sat Apr 27 13:48:07 MSK 2013
Sat 2013 13:48:07
Sat 2013 13:48:07
true
Sat Apr 27 13:48:07 MSK 2013
Sat 27 2013 13:48:07
Sat 5 2013 13:48:07
false
Sat Apr 27 13:48:07 MSK 2013
Sat 27 April 2013 13:48:07
Sat 5 January 2013 13:48:07
false
Why do then 27 transforms into 5, and April to January?
Well, there are two aspects here:
The pattern E d YYYY kk:mm:ss doesn't contain a month indicator at all. So after formatting to "Sat 27 2013 13:48:07" how are you expecting the parsing part to work out the month?
All your patterns use YYYY which is the week-year, not calendar year. This should usually be used with "day of week, week of week-year" patterns. If you use yyyy instead, the final pattern will work.
The only reason the first pattern appears to work is that you're not actually setting anything other than the "day of week" and the year (and time, of course). If you print out parsedFormattedNow (with no other formatting) you'll see that the parse result is actually January 5th. It's just you don't notice it, because it's still a Saturday.

timezone conversion and date is not displaying properly

Calendar cal= Calendar.getInstance();
System.out.println(cal.getTimeZone().getID());
cal.set(2012, 8, 21);
java.util.Date d = new java.util.Date();
System.out.println(d.toString());
//System.setProperty("user.timezone", "America/Chicago");
// System.out.println(TimeZone.getDefault().getID());
TimeZone tz1 = TimeZone.getTimeZone("Africa/Algiers");
//tz1.setDefault(tz1);
cal.setTimeZone(tz1);
System.out.println(cal.getTimeZone().getID());
//cal.set(2012, 8, 21);
System.out.println(d.toString());
Output is --
Asia/Calcutta
Tue Aug 21 11:35:06 IST 2012
Africa/Algiers
Tue Aug 21 11:35:06 IST 2012
I want the time in the currrent timezone format but it is giving in IST. How to do this.
EDIT: I've only just noticed that the code you're given doesn't even call cal.getTime(). You're completely ignoring the value in the calendar. It wouldn't do what you wanted anyway, but the value you're printing is just new Date()... how do you expect the calendar to get involved?
I want the time in the currrent timezone format but it is giving in IST. How to do this.
Avoid using Date.toString, to start with. A Date value has no concept of a time zone, so toStringjust uses the system time zone, always. Changing the time zone of a calendar without calling set again doesn't change the underlying value, either.
Now there are two options:
Use SimpleDateFormat, specifying the time zone there before formatting
Use Joda Time instead, which is a much richer date and time API in the first place
Personally I'd strongly advise you to use the latter option, particularly if you're doing quite a bit of date/time manipulation. Date, Calendar and SimpleDateFormat just don't let you write code which clearly expresses what data you have at any point in time.
Use TimeZone.setDefault(tz1); instead of //tz1.setDefault(tz1);
Calendar cal = Calendar.getInstance();
System.out.println(cal.getTimeZone().getID());
cal.set(2012, 8, 21);
java.util.Date d = new java.util.Date();
System.out.println(d.toString());
TimeZone tz1 = TimeZone.getTimeZone("Africa/Algiers");
TimeZone.setDefault(tz1);
cal.setTimeZone(tz1);
System.out.println(cal.getTimeZone().getID());
System.out.println(d.toString());
I run your program, see output :
Asia/Calcutta
Tue Aug 21 11:47:13 IST 2012
Africa/Algiers
Tue Aug 21 07:17:13 CET 2012
Calender doesnot work that way...i have SimpleDateFormat code..it may help..try this
public class TimeZoneTest {
public static void main(String[] args) {
new TimeZoneTest().setTimeZones();
}
private void setTimeZones(){
String etStart = "";
String ctStart = "";
String mtStart = "";
String ptStart = "";
DateFormat fullDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
String dateString = "Mon Mar 14 09:30:51 GMT 2011";
//this input date doesn't convert
//String dateString = "Mon Mar 14 09:30:51 PDT 2011";
System.out.println("Input Date: " + dateString);
System.out.println("Default TimeZone: " + TimeZone.getDefault());
try {
etStart = getDateInTimeZone(dateString, fullDateFormat, TimeZone.getTimeZone("America/New_York"));
ctStart = getDateInTimeZone(dateString, fullDateFormat, TimeZone.getTimeZone("America/Chicago"));
mtStart = getDateInTimeZone(dateString, fullDateFormat, TimeZone.getTimeZone("America/Denver"));
ptStart = getDateInTimeZone(dateString, fullDateFormat, TimeZone.getTimeZone("America/Los_Angeles"));
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("Eastern Date: " + etStart);
System.out.println("Central Date: " + ctStart);
System.out.println("Mountain Date: " + mtStart);
System.out.println("Pacific Date: " + ptStart);
}
private String getDateInTimeZone(Date inputDt, TimeZone targetTimeZone) throws ParseException{
DateFormat fullDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
fullDateFormat.setTimeZone(targetTimeZone);
return fullDateFormat.format(inputDt);
}
}

Time difference while taking into a/c

If we have 2 dates
Previous Date : Wed Jun 02 17:30:00 CDT 2010
Next Date : Sun Feb 13 22:00:00 CST 2011
and need to find difference in mins. between these 2 dates
Is there a way to accurately get it?
Yes, you can get an accurate difference of those times:
Parse each one with SimpleDateFormat to get a Date.
Get the time in milliseconds since the Epoch from each.
Subtract the two times and divide by 60000 for minutes.
Here's the code:
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
Date prevDate = sdf.parse("Wed Jun 02 17:30:00 CDT 2010");
Date nextDate = sdf.parse("Sun Feb 13 22:00:00 CST 2011");
long diffTime = nextDate.getTime() - prevDate.getTime();
System.out.println(diffTime / 60000 + " minutes");
date1.getTime() - date2.getTime() will give you the difference in milliseconds. You can then divide it by 60000 to get the difference in minutes.
Use TimeUnit class for convertion.
// specify the input format
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
String s1 = "Wed Jun 02 17:30:00 CDT 2010";
String s2 = "Sun Feb 13 22:00:00 CST 2011";
// parse to Date object
Date d1 = dateFormat.parse(s1);
Date d2 = dateFormat.parse(s2);
// get time in milliseconds
long l1 = d1.getTime();
long l2 = d2.getTime();
// absolute difference
long diff = Math.abs(l1 - l2);
// convert milliseconds to minute
long min = TimeUnit.MILLISECONDS.toMinutes(diff);
System.out.println(min);
With Joda Time
DurationFormatUtils.formatDuration(date2.getTime() - date1.getTime(), "m");

Categories