Parsing custom time format with SimpleDateFormat - java

I'm having trouble parsing a date format that I'm getting back from an API and that I have never seen (I believe is a custom format). An example of a date:
/Date(1353447000000+0000)/
When I first encountered this format it didn't take me long to see that it was the time in milliseconds with a time zone offset. I'm having trouble extracting this date using SimpleDateFormat though. Here was my first attempt:
String weirdDate = "/Date(1353447000000+0000)/";
SimpleDateFormat sdf = new SimpleDateFormat("'/Date('SSSSSSSSSSSSSZ')/'");
Date d1 = sdf.parse(weirdDate);
System.out.println(d1.toString());
System.out.println(d1.getTime());
System.out.println();
Date d2 = new Date(Long.parseLong("1353447000000"));
System.out.println(d2.toString());
System.out.println(d2.getTime());
And output:
Tue Jan 06 22:51:41 EST 1970
532301760
Tue Nov 20 16:30:00 EST 2012
1353447000000
The date (and number of milliseconds parsed) is not even close and I haven't been able to figure out why. After some troubleshooting, I discovered that the way I'm trying to use SDF is clearly flawed. Example:
String weirdDate = "1353447000000";
SimpleDateFormat sdf = new SimpleDateFormat("S");
Date d1 = sdf.parse(weirdDate);
System.out.println(d1.toString());
System.out.println(d1.getTime());
And output:
Wed Jan 07 03:51:41 EST 1970
550301760
I can't say I've ever tried to use SDF in this way to just parse a time in milliseconds because I would normally use Long.parseLong() and just pass it straight into new Date(long) (and in fact the solution I have in place right now is just a regular expression and parsing a long). I'm looking for a cleaner solution that I can easily extract this time in milliseconds with the timezone and quickly parse out into a date without the messy manual handling. Anyone have any ideas or that can spot the errors in my logic above? Help is much appreciated.

Take the milliseconds value in the string:
/Date(1353447000000+0000)/
and pass that value as a long into the Date constructor:
Date date = new Date(1353447000000);
and format the date object using SimpleDateFormat.

Even though it's pretty much what you're doing now, I don't think there's much wrong with the manual method - other than it's a shame you have to go there!
I don't believe you can do it solely with SDF.
This will give you a date reasonably 'elegantly':
Date date = new Date(Long.parseLong(weirdDate.split("[^\\d]")[6]));
I'm sure you've already considered it, but have you spoken to the producer of the API to see why they are outputting this value in such an odd format? If the interface is not public and/or not widespread they may consider changing it to something a bit more conventional.

Related

how to convert string date to java.util.Date in java and oracle [duplicate]

I've been searching all over and just can't find a explanation or reason why this is happening but the parse(String) method of DateFormat just isn't parsing my String correctly.
I'm trying to parse a String into the date format that is used for HTTP headers and got as far as getting the String on its own such as:
Thu, 11 Nov 2010 18:34:22 GMT
Which is in the format:
E, d MMM yyyy HH:mm:ss z
But when I use df.parse(dateStr); this is what I get out of it:
Thu Nov 11 18:34:22 GMT 2010
Which is nothing like what I wanted, why is the year now after the GMT? Why is there no comma anymore? And why is the date after the month?
I'm completely confused about this now and can't find a solution but I really need the date to be in that format. Is the comma messing things up? or the colons?
Thanks for your time,
Infinitifizz
P.S.
Forgot to mention this but I've tried dateformat.setLenient(false) and it makes no difference.
P.P.S
I'm trying to do this to compare the dates with date1.before(date2) and after() etc to see if one is newer than the other but I can't do this because the parsing isn't working.
Even though they look the same but just the format is different, they are not the same because after calling getTime() on both of them (When I have provided 2 identical dates) the longs are not the same. As in the date is:
Thu, 11 Nov 2010 19:38:52 GMT for a lastModified() on a File
If I input the String "Thu, 11 Nov 2010 19:38:52 GMT" and then compare their longs once converting the string to a date using parse() and then calling getTime() on that date I get:
lastModified = 1289504332671
fromString = 1289504332000
It is only the last 3 digits that are different, does this have any significance?
Thanks again for your time and sorry I didn't put this bit in first,
Infinitifizz
The result format is the default format of Date#toString() (click link to see the javadoc). You're apparently doing a System.out.println(date). You would like to use SimpleDateFormat#format() instead with another pattern to format it in the desired format. E.g.
String newDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
Update: You shouldn't care about the format when using Date. You should only care about the format at that point when Date is to be converted (displayed) as String. As to the difference in timestamps, the Date uses millisecond precision for the timestamp while HTTP header uses second precision. You'd like to divide the timestamps by 1000 before comparing.

How to format the output of the date-object (not as string)?

I'm trying to pass a Date-Object to a SOAP-API and need the output of the date-object itself to be yyyy-MM-dd
I'm already converting my string into a date-object like this:
// String __startDatum = "2013-02-05";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date convertedDate = dateFormat.parse(__startDatum);
For now the output of convertedDate will be Tue Feb 05 00:00:00 MEZ 2013.
How could I change the output of convertedDate to be 2013-02-05?
Please keep in mind I still need it to be a date-object not a string!
For now the output of convertedDate will be Tue Feb 05 00:00:00 MEZ 2013.
There's no "output of convertedDate" - it's just a Date variable. The only way to get "Tue Feb 05 00:00:00 MEZ 2013" would be to call toString() on it, either implicitly or explicitly - and you can't change the format used by Date.toString().
It's important to understand that a Date is just a number of milliseconds since the Unix epoch. It doesn't have a time zone; it doesn't have a calendar system; it doesn't have a particular format.
If you want a better API which allows you to create an object which just represents a date (rather than a date/time) you should look at Joda Time which is a far nicer date and time API than the built-in one. It's reasonably large - primarily due to the time zone data, I believe - so you may want to look for a cut down version tailored to Android. It's mostly a pleasure to work with though - at least compared with Date and Calendar.

Convert a dateString from a browser to java.util.Date?

I am facing an issue with parsing/converting a dateString from browser to Date format in Java.
The following are some of the values that I got from the browser.
dateStr = "01-01-2010 05:06:22";
dateStr = "Mon Oct 11 07:00:00 EDT 2010";
dateStr = "Fri May 25 2012 08:00:00 GMT-0400 (Eastern Daylight Time)";
Each dateStr is in different format and at the back-end I was using a SimpleDateFormat with a particular format to convert dateStr. Since the input dateStr format is not consistent, any idea about how this can be handled in the backend?
There is little access to the frontend code/folks.
PS: I did google about this and read the related topics here on StackOverflow.
Any sort of help is greatly appreciated. Thank you.
You have all the pieces you need. First define patterns for every possible date format you can get from the client. Then simply iterate over these formats and try parsing input using each of them and SimpleDateFormat.
Continue looping if SimpleDateFormat returns null (parse error) until you get valid Date. You might ask: what to do if input matches more then one pattern (is 02-01-2012 2nd of January or February the 1st?) Well, then you have bigger issues...

SimpleDateFormat change date while converting it to String

In my app, I am using SimpleDateFormat to convert the Date object to a string. But sometime when I change the time zone one by one to test whether the date I enter is the same as the date converted to a string, I found that it shows a different date. For example, suppose I have Thu Mar 15 00:00:00 GMT+08:00 2012 in my Date object, Now when I convert it to a string using SimpleDateFormat it works fine, but when I change the time zone one by one and check whether the date converted to string is same as it stored in Date object then in some cases it shows as 14-Mar-2012 instead of showing 15-Mar-2012. Why this happen? Can anyone please suggest me how to solve this out?
Code I have used:
SimpleDateFormat m_sdFormatter = new SimpleDateFormat("dd-MMM-yyyy");
String selected_date = m_sdFormatter.format(btnSelectedDt.getTime());
try this ,hope it may help you..
private String getDate(long timeStamp) {
DateFormat objFormatter = new SimpleDateFormat("dd-MM-yyyy");
objFormatter.setTimeZone(TimeZone.getDefault());
Calendar objCalendar = Calendar.getInstance(TimeZone.getDefault());
objCalendar.setTimeInMillis(timeStamp * 1000);
String result = objFormatter.format(objCalendar.getTime());
objCalendar.clear();
return result;
}
For example suppose i have Thu Mar 15 00:00:00 GMT+08:00 2012 in my Date object,
You haven't got that (even though that's no doubt what toString displays). A Date object doesn't contain a time zone. It contains an instant in time, which can be interpreted as different dates and times based on the calendar and time zone you use to interpret it. So that's midnight in once specific time zone - but the Date object itself is just a number of milliseconds since the unix epoch.
It's not clear exactly what you're doing, but you shouldn't be surprised that changing the time zone used in SimpleDateFormat will change the date written out. If you can describe in more detail what the larger goal is, we may be able to help you more. Note that if you can use Joda Time instead, that's a much better date/time API - but I know that it's quite large for use in an Android app.
In your SimpleDateFormat, mention the locale,
DateFormat objFormatter = new SimpleDateFormat("dd-MM-yyyy", locale);
where locale is of your choice. For eg, I use Locale.ENGLISH as it contains the date format that I require. Otherwise when you change ure locale in the device, the simpledateformat changes to current locale and you end up getting the wrong date.

Parsing a String into Date with DateFormat not parsing correctly

I've been searching all over and just can't find a explanation or reason why this is happening but the parse(String) method of DateFormat just isn't parsing my String correctly.
I'm trying to parse a String into the date format that is used for HTTP headers and got as far as getting the String on its own such as:
Thu, 11 Nov 2010 18:34:22 GMT
Which is in the format:
E, d MMM yyyy HH:mm:ss z
But when I use df.parse(dateStr); this is what I get out of it:
Thu Nov 11 18:34:22 GMT 2010
Which is nothing like what I wanted, why is the year now after the GMT? Why is there no comma anymore? And why is the date after the month?
I'm completely confused about this now and can't find a solution but I really need the date to be in that format. Is the comma messing things up? or the colons?
Thanks for your time,
Infinitifizz
P.S.
Forgot to mention this but I've tried dateformat.setLenient(false) and it makes no difference.
P.P.S
I'm trying to do this to compare the dates with date1.before(date2) and after() etc to see if one is newer than the other but I can't do this because the parsing isn't working.
Even though they look the same but just the format is different, they are not the same because after calling getTime() on both of them (When I have provided 2 identical dates) the longs are not the same. As in the date is:
Thu, 11 Nov 2010 19:38:52 GMT for a lastModified() on a File
If I input the String "Thu, 11 Nov 2010 19:38:52 GMT" and then compare their longs once converting the string to a date using parse() and then calling getTime() on that date I get:
lastModified = 1289504332671
fromString = 1289504332000
It is only the last 3 digits that are different, does this have any significance?
Thanks again for your time and sorry I didn't put this bit in first,
Infinitifizz
The result format is the default format of Date#toString() (click link to see the javadoc). You're apparently doing a System.out.println(date). You would like to use SimpleDateFormat#format() instead with another pattern to format it in the desired format. E.g.
String newDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
Update: You shouldn't care about the format when using Date. You should only care about the format at that point when Date is to be converted (displayed) as String. As to the difference in timestamps, the Date uses millisecond precision for the timestamp while HTTP header uses second precision. You'd like to divide the timestamps by 1000 before comparing.

Categories