Not able to get difference between two datetime? - java

Please check the below code. I am trying to get the difference but every time getting 0.
Can anybody please point me what is the problem with below code?
SimpleDateFormat sDateFormat = new SimpleDateFormat("hh:mm:ss dd/mm/yyyy");
try {
long d1 = sDateFormat.parse("10:04:00 04/04/2014").getTime();
long d2 = sDateFormat.parse("10:09:00 04/04/2014").getTime();
long difference = d2 - d1;
Log.i(TAG,">> Difference = "+difference);
} catch (ParseException e) {
e.printStackTrace();
}

your formatter does not fit the date format used.
Try:
new SimpleDateFormat("HH:mm:ss dd/MM/yyyy");

From Android Developer documentation of SimpleDateFormat, you can see M is for Month and m is for minute...
M month in year (Text) M:1 MM:01 MMM:Jan MMMM:January MMMMM:J
m minute in hour (Number) 30
So, you should change the date format from this...
hh:mm:ss dd/mm/yyyy
to this...
hh:mm:ss dd/MM/yyyy
I hope this format correction will solve your problem.

Your format, hh:mm:ss dd/mm/yyyy has two problems:
h is used for 12-Hour time format i.e. a time format with AM/PM marker which is not the case with your date-time strings. You need to use H which is used for a 24-Hour time format.
m is not used for a month. For a month, you need to use M.
Apart from this, the legacy date-time API (java.util date-time types and their formatting API, SimpleDateFormat) are outdated and error-prone. It is recommended to stop using them completely and switch to java.time, the modern date-time API*.
Demo using modern date-time API:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String args[]) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("H:m:s d/M/u");
LocalDateTime start = LocalDateTime.parse("10:04:00 04/04/2014", dtf);
LocalDateTime end = LocalDateTime.parse("10:09:00 04/04/2014", dtf);
long diff = ChronoUnit.MILLIS.between(start, end);
System.out.println(diff);
}
}
Output:
300000
Learn more about the 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.

Related

How to format the given time string and convert to date/time object

I am getting the time object in the form of a string from a rest service . I need to extract the time and then do some time operation.The given time string is "2015-06-16T14:58:48Z". I tried the below code , to convert the string to the time , however , getting incorrect values.
String time = "2015-06-16T14:58:48Z";
SimpleDateFormat formatter = new SimpleDateFormat("YYYY-MM-DD'T'hh:mm:ss'Z'", Locale.US);
String dateInString = "2015-06-16T14:58:48Z";
Date date = formatter.parse(dateInString);
System.out.println("Original String : " + time);
System.out.println("After converting to time : " + formatter.format(date));
The output that i am getting is as below:
Original String : 2015-06-16T14:58:48Z
After converting to time : 2015-12-362T02:58:48Z
The converted date somehow is getting wrong value.Please suggest where is the mistake.Thanks.
You format string has a couple of mistakes:
Y means the week year, not the year, which is y
D means the day of the year. You should have used d, which means the day of the month.
h means a 12-hour notation time of day. Since you have 14 you should use H, which handle a 24-hour notation.
To sum it all up:
SimpleDateFormat formatter =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.US);
change SimpleDateFormat to this..
SimpleDateFormat formatter = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssX", Locale.US);
java.time
The root cause of the problem is using wrong symbols
Y (which specifies week-based-year) instead of y (which specifies year-of-era)
D (which specifies day-of-year) instead of d (which specifies day-of-month).
h (which specifies clock-hour-of-am-pm) instead of H (which specifies hour-of-day).
Check the documentation page
to learn more about these symbols.
Also, note that the legacy date-time API (java.util date-time types and their formatting API, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.
Solution using the modern API:
The modern date-time API is based on ISO 8601 and does not require you to use a DateTimeFormatter object explicitly as long as the date-time string conforms to the ISO 8601 standards. Your date-time string conforms to ISO 8601 standards (or the default format used by OffsetDateTime#parse).
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2015-06-16T14:58:48Z";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt);
// ########################Extract time information########################
LocalTime time = odt.toLocalTime();
// You can also get it as time.getHour()
// Extract other units in a similar way
int hour = odt.getHour();
// Also using time.format(DateTimeFormatter.ofPattern("a", Locale.ENGLISH));
String amPm = odt.format(DateTimeFormatter.ofPattern("h a", Locale.ENGLISH));
System.out.println(time);
System.out.println(hour);
System.out.println(amPm);
}
}
Output:
2015-06-16T14:58:48Z
14:58:48
14
2 PM
Note:
The Z in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
For any reason, if you need to convert this object of OffsetDateTime to an object of java.util.Date, you can do so as follows:
Date date = Date.from(odt.toInstant());
Learn more about the 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.

Same milliseconds for two different times in java

I need to convert a 24 hour date format for a given string into milliseconds. But I get the same milliseconds for 00:10:00 and 12:10:00. This is my code sample; please assist me.
DateFormat formate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
formate.parse("2013-10-31 12:10:00").getTime(); // return 1383158400000
formate.parse("2013-10-31 00:10:00").getTime(); // return 1383158400000
I am using 24 hours format, but I get the same result for 2 different times. Where is the mistake? Please help me to find out the problem.
You are using the 12-hour hh format; use the 24-hour HH (capitalized) format.
DateFormat formate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat date symbols
H Hour in day (0-23) Number 0
h Hour in am/pm (1-12) Number 12
java.time
Without AM/PM marker, the date-time parser considers the hour in 24-Hour format for which the symbol is H instead of h.
Changing that will fix your problem but the legacy date-time API (java.util date-time types and their formatting API, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using them completely and switch to java.time, the modern date-time API*.
Demo using modern date-time API:
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String args[]) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH).withZone(ZoneOffset.UTC);
System.out.println(Instant.from(dtf.parse("2013-10-31 12:10:00")).toEpochMilli());
System.out.println(Instant.from(dtf.parse("2013-10-31 00:10:00")).toEpochMilli());
}
}
Output:
1383221400000
1383178200000
Learn more about the 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.

Convert Date string with Time to long date

I have a string with date "10:00 AM 03/29/2011", I need to convert this to a long using Java, I cant use Date because its deprecated and it was not giving me the time correctly.. so i looked online to see how to come about it but still no luck. First time using java.
The problem is you're parsing the data and then messing around with it for no obvious reason, ignoring the documented return value for Date.getYear() etc.
You probably just want something like this:
private static Date parseDate(String text)
throws ParseException
{
SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a MM/dd/yyyy",
Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.parse(text);
}
If you really want a long, just use:
private static long parseDate(String text)
throws ParseException
{
SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a MM/dd/yyyy",
Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.parse(text).getTime();
}
Note that I'm punting the decision of what to do if the value can't be parsed to the caller, which makes this code more reusable. (You could always write another method to call this one and swallow the exception, if you really want.)
As ever, I'd strongly recommend that you use Joda Time for date/time work in Java - it's a much cleaner API than java.util.Date/Calendar/etc.
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API:
Parse the Date-Time string into LocalDateTime.
Convert the LocalDateTime to Instant.
Convert Instant to the Epoch milliseconds.
Demo:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "10:00 AM 03/29/2011";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("h:m a M/d/u", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
long epochMillis = instant.toEpochMilli();
System.out.println(epochMillis);
}
}
Output in my timezone, Europe/London:
1301389200000
ONLINE DEMO
Some important notes about this code:
ZoneId.systemDefault() gives you to the JVM's ZoneId.
If 10:00 AM 03/29/2011 belongs to some other timezone, replace ZoneId.systemDefault() with the applicable ZoneId e.g. ZoneId.of("America/New_York").
If 10:00 AM 03/29/2011 is in UTC, you can do either of the following:
get the Instant directly as ldt.toInstant(ZoneOffset.UTC) or
replace ZoneId.systemDefault() with ZoneId.of("Etc/UTC") in this code.
The timezone of the Ideone server (the online IDE) is UTC whereas London was at an offset of +01:00 hours on 03/29/2011 and hence the difference in the output from my laptop and the one you see in the ONLINE DEMO. Arithmetic: 1301389200000 + 60 * 60 * 1000 = 1301392800000
Learn more 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.

Convert "Friday, February 1, 2013" to "2013-02-01"

How can I perform this conversion in Java?
Currently, I'm doing:
public static String formatDate(String strDateToFormat) {
try {
SimpleDateFormat sdfSource = new SimpleDateFormat("EEEE, MMMM DD, YYYY");
Date date = sdfSource.parse(strDateToFormat);
SimpleDateFormat sdfDestination = new SimpleDateFormat("yyyy-MM-dd");
return sdfDestination.format(date);
} catch (ParseException pe) {
System.err.println("Parse Exception : " + pe);
}
return null;
}
However, this results in an incorrect format. It gives me the following output:
Friday, February 1, 2013 > 2013-01-04
Thursday, January 31, 2013 > 2013-01-03
You're using DD in your parsing part, which is the day of year. You want dd instead. You also probably want yyyy (year) instead of YYYY (week year). (In most cases they're the same value, but not always.)
You're using DD in your parsing part, which is the day of year. You want dd instead.
Change also YYYY in yyyy.
You can find all patterns here.
http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Your code has got two major problems and the existing answers have already solved one of them. The second and even more dangerous problem is, not using Locale with SimpleDateFormat, which is a Locale-sensitive type. Since your Date-Time string is in English, make sure to use Locale.ENGLISH or some other English-Locale. So, a correct initialization would be:
SimpleDateFormat sdfSource = new SimpleDateFormat("EEEE, MMMM d, y", Locale.ENGLISH);
Check Never use SimpleDateFormat or DateTimeFormatter without a Locale to learn more about it. Also, notice a single d which, for parsing, can cater to both single-digit as well as double-digit representation of a day-of-month. Similarly, a single y can cater to both two-digit as well as four-digit representation of a year.
Switch to the modern Date-Time API
Note that the java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API* released with Java SE 8 in March 2014.
Solution using java.time, the modern Date-Time API
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String input = "Friday, February 1, 2013";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEEE, MMMM d, u", Locale.ENGLISH);
LocalDate date = LocalDate.parse(input, dtf);
System.out.println(date);
}
}
Output:
2013-02-01
ONLINE DEMO
Some notes:
Here, you can use y instead of u but I prefer u to y.
The LocalDate#toString gives you a String in [ISO-8601 format] which is the exact same format you are expecting. So, you do not need to format LocalDate explicitly to obtain a String in this format.
Learn more 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.

server time zone java conversion

Ok, so I've pretty much tried everything. I bet it's something really simple but I can't seem to get a hold of it.
The server sends me the time, which is epoch. However when I put this into a date object it seems to automatically pick up the time zone and it adds +3 to the server time. So if the gmt time is 00.00, it says its 03.00.
I also need to add a timezone of my own. Let's say the epoch time is 00.00 again, it should read 10.00 after I add the timezone.
any help would be much appreciated. Thank you
"It seems to add" - I suspect you're using Date.toString() which does indeed use the local time zone. The Date object itself is effectively in UTC though. Use DateFormat to perform the conversion to a string instead, and you can specify which time zone to use. You may also need to use Calendar - it depends what you're trying to do.
(Alternatively, use Joda Time in the first place, which is a better API. It may be a little bulky for your Android project though. I wouldn't be surprised if there were a "Joda Time lite" project around somewhere for precisely this sort of thing...)
EDIT: Quick sample, although it's not entirely clear what you need...
long millis = getMillisFromServer();
Date date = new Date(millis);
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
format.setTimeZone(customTimeZone);
String formatted = format.format(date);
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
long millis = 1316391494L;
Instant instant = Instant.ofEpochMilli(millis);
System.out.println(instant);
// The same instant at a specific timezone
ZonedDateTime zdt = instant.atZone(ZoneId.of("Australia/Brisbane"));
System.out.println(zdt);
}
}
Output:
1970-01-16T05:39:51.494Z
1970-01-16T15:39:51.494+10:00[Australia/Brisbane]
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
What went wrong with your code?
A java.util.Date object simply represents an instant on the timeline — a wrapper around the number of milliseconds since the UNIX epoch (January 1, 1970, 00:00:00 GMT). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
long millis = 1316391494L;
Date date = new Date(millis);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX[zzzz]", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDateUtc = sdf.format(date);
System.out.println(strDateUtc);
sdf.setTimeZone(TimeZone.getTimeZone("Australia/Brisbane"));
String strDateBrisbane = sdf.format(date);
System.out.println(strDateBrisbane);
}
}
Output:
1970-01-16T05:39:51.494Z[Coordinated Universal Time]
1970-01-16T15:39:51.494+10:00[Australian Eastern Standard Time]
ONLINE DEMO
* 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.

Categories