SimpleDateFormat parsing difficulty
Hello all,
Recently, I had to parse Strings into Dates using SimpleDateFormat. The difficulty I had was because the Strings had timezone offsets. The code below shows the 3 tests it took to create a Date object of specified TimeZone.
Test 1
Fails because I don't set the TimeZone for SimpleDateFormat.
Test 2
Works for the first String because the TimeZone matches the timezone in the String.
Test 3
Works for all Strings, but is cumbersome because I have to parse the end of the String myself.
My question is this: Shouldn't SimpleDateFormat parse a String directly into a Date without having you to specify the TimeZone of that Date? This problem was very annoying to solve and goes against logic (at least mine!).
I'm interested in any thoughts on this matter. Am I being unreasonable, or is this poorly explained in the API?
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
public class DateTests {
private static String DATE_FORMAT = "yyyyMMddHHmmss.SSSZ";
private static String[] TEST_DATA = {
"20020125120434.175+0800",
"20031101195801.942+0000",
"20041231000159.999-0536",
"20050220165427.531-1100"
private static int MINUTE = 60 * 1000; //in milliseconds
private static int HOUR = 60 * MINUTE;
public static void main(String[] args) {
test1();
test2();
test3();
private static void test1() {
System.out.println("**** TEST 1 ****\n");
DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
formatter.setLenient(false); //want to check that dates are valid
for (String dateString : TEST_DATA) {
try {
Date date = formatter.parse(dateString);
System.out.println("Success! The date is: "+date.toString());
} catch (ParseException e) {
System.out.println(dateString + " has error index of: " + e.getErrorOffset());
//out of curiousity, lets see the String representation of the current date & time
Date now = new Date();
String currentDate = formatter.format(now);
System.out.println("\nThe current date as a String: "+currentDate);
System.out.println("\n");
private static void test2() {
System.out.println("**** TEST 2 ****\n");
DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
formatter.setLenient(false); //want to check that dates are valid
//lets make the timezone +0800
formatter.setTimeZone(new SimpleTimeZone(8 * HOUR, "GMT")); //8 hour offset
for (String dateString : TEST_DATA) {
try {
Date date = formatter.parse(dateString);
System.out.println("Success! The date is: "+date.toString());
} catch (ParseException e) {
System.out.println(dateString + " has error index of: " + e.getErrorOffset());
System.out.println("\nSuccess for the first date. Why? The timezone of the formatter matches the date.");
System.out.println("\n");
private static void test3() {
System.out.println("**** TEST 3 ****\n");
DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
formatter.setLenient(false); //want to check that dates are valid
for (String dateString : TEST_DATA) {
try {
//lets set a timezone for each individual date
int length = dateString.length();
int gmtMinutes = Integer.parseInt(dateString.substring(length-2, length));
int gmtHours = Integer.parseInt(dateString.substring(length-4, length-2));
int timeZone = gmtMinutes * MINUTE + gmtHours * HOUR;
timeZone = dateString.charAt(length-5) == '+' ? timeZone : -timeZone;
formatter.setTimeZone(new SimpleTimeZone(timeZone, "GMT"));
Date date = formatter.parse(dateString);
System.out.println("Success! The date is: "+date.toString());
} catch (ParseException e) {
System.out.println(dateString + " has error index of: " + e.getErrorOffset());
}-Muel
Date objects don't have time zones.
This is true, my problem was that I needed to parse both the Date and the TimeZone from a String. I got misled by the SimpleDateFormat documentation (the symbol Z), and somehow got the impression that a Date should have an associated TimeZone!
In hindsight, it is clear that Z should be used for Date strings containing a timezone and that SimpleDateFormat uses the timezone to modify the Date so that it's correct for the timezone of the current machine. If that makes sense!
-Muel
Similar Messages
-
Strange result of SimpleDateFormat.parse()
Hi,
I'm having trouble with the parse data function as it does not return the correct hour.
Here is what I'm doing:
Date nullDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse("1900-01-01T00:00:00-0000");I would now expect nullDate to be Mon Jan 01 00:00:00 CET 1900
But instead, it is Mon Jan 01 00:09:21 CET 1900
Personally I cannot think of a reason why the time is not 0.
Any ideas?I don't see the problem you see. What version of Java on what OS and in what time zone?
P.S. I would certainly set the time zone for the parser i.e.
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
parser.setTimeZone(TimeZone.getTimeZone("UTC"));
Date nullDate = parser.parse("1900-01-01T00:00:00-0000");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
System.out.println(formatter.format(nullDate));On my Ubuntu 10.04 using JDK 1.6.0_20 in London (currently GMT) time zone I get
1900-01-01 00:00:00 GMT -
Strange problem with SimpleDateFormat.parse method
I got something strange with this method.
String pattern = "yyyy/MM/dd";
String mydate = "2007/00/10";
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
Date newdate = formatter.parse(mydate);
I get "2006/12/10"
is this correct.dongyisu wrote:
and there no exception get thrown outYes it does. I ran this:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateFormatTest
public static final String DEFAULT_DATE_FORMAT = "yyyy/MM/dd";
public static void main(String[] args)
DateFormat formatter = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
formatter.setLenient(false);
for (int i = 0; i < args.length; ++i)
try
Date date = formatter.parse(args);
System.out.println("input: " + args[i] + " date: " + date);
catch (ParseException e)
System.err.println(args[i] + " is not a valid date");
and got this when I input "2007/00/10":
com.intellij.rt.execution.application.AppMain DateFormatTest 2007/00/10
2007/00/10 is not a valid date
Process finished with exit code 0% -
SimpleDateFormat.parse() causes Unparsable date exception
I am using SimpleDateFormat to both format and parse date strings. The format is working properly, but parse results in the following exception:
java.text.ParseException: Unparseable date: "2007-08-31T12:05:05.651-0700"
at java.text.DateFormat.parse(Unknown Source)
Here is my code:
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.SZ");
String dateTime = dateFormatter.format(new Date());
Date test = dateFormatter.parse(dateTime);
For testing purposes, I am formatting a date string, and then passing it right back into parse() and I get the exception.
I am using jre1.5.0_10.
Thank you for your help.
-KarenYou have specified the milliseconds (S) to have a minimum of 1 letter.
From the API:
Number: For formatting, the number of pattern letters is the minimum number of digits, and shorter numbers are zero-padded to this amount. For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields.
If you specify it like this:SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.SSSZ");
// or like this
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.S Z");it will work.
Message was edited by:
dwg -
Java.util.text.SimpleDateFormat.parse strange behavior
Wow !
if I parse "10/14/2002" I get "0/2/2003", that is, the month 14 is considered 12 (december) + 2 additional months and therefore february in the next year!!
any idea ?
Paolo Denti
=============================
public class Test {
public static void main(String[] args) {
java.util.Date testDate = null;
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("dd-MM-yyyy");
try {
testDate = formatter.parse("10-14-2002");
catch (java.text.ParseException e) {
System.out.println("Data scassata: " + e.getMessage());
System.exit(1);
System.out.println(testDate.toString());
=================================
prints "Mon Feb 10 00:00:00 CET 2003"Tryformatter.setLenient(false);if you do not want this behaviour.
-
Java.text.SimpleDateFormat.parse()
This method does too much than I expected, say:
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date d = sdf.parser("00/00/0000");The d would be 1999, Nov. 30.
After hacked the source code and some testing, I found it will roll backward or forward to generate a date. So, 01/32/2000 would become Feb. 01 2000. But I don't think this is a good implementation, as I expect it could throw exceptions at runtime if the string is not a valid time sting. And it's very difficult to debug, since any digit could be parsed!
I think you guys here know what's behind the scene and why it's implemented like this. Any idea? Do you agree that the parse method should throw an exception when the fields of a date string're out of range? Or am I missing something?
Comments are welcomed, and duke dollars're ready for those good answers.change your code as follows at it will do what you expected in the first places:
<code>
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
sdf.setLenient(false);
Date d = sdf.parser("00/00/0000");
</code>
Spieler -
Problem with SimpleDateFormat.parse()
Hello
I have a problem with the parse-function in SimpleDateFormat.
When i try to parse the date Fri Jul 15 17:23:41 2005 with this pattern EEE MMM d HH:mm:ss yyyy i get the exception java.text.ParseException: Unparseable date: "Fri Jul 15 17:23:41 2005".
This is my code:
SimpleDateFormat df=new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy");
try {
df.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}Can someone explain me what i did wrong?
Thanks
MatthiasSince your name is "Matthias" it is possible that your locale is one that does not use the English language. If that is the case then your problem is that "Fri" or "Jul" are not correct abbreviations in your language.
Easiest way to test this idea is to format a date (such as now) using that SimpleDateFormat object and see what the output looks like. -
Possible SimpleDateFormat.parse(...) error.
Consider this code segment
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
String testDate[] = {
"2005-07-29 16:28:38.83",
"2005-07-29 16:28:38.003",
"2005-07-29 16:28:38.03",
"2005-07-29 16:28:38.3"
for (int i = 0; i < testDate.length; i++)
Timestamp date = Timestamp.valueOf(testDate);
Date utilDate = sdf.parse(testDate[i]);
System.out.println(testDate[i] + " : "+(date.getTime()+date.getNanos()/1000000)+" : "+utilDate.getTime());
Output is:
2005-07-29 16:28:38.83 : 1122668918830 : 1122668918083
2005-07-29 16:28:38.30 : 1122668918300 : 1122668918030
2005-07-29 16:28:38.003 : 1122668918003 : 1122668918003
2005-07-29 16:28:38.03 : 1122668918030 : 1122668918003
2005-07-29 16:28:38.3 : 1122668918300 : 1122668918003
Now if we look at msecs portion, sdf.parse is parsing .3 and .03 and .003 as 003
But Timestamp is parsing in right way. .3 = 300, .03 = 030 and .003 = 003
I tested this program with ibm jdk 1.3 and sun jdk 1.5 with same results.
Is it known bug of simpleDateFormat or some unknown feature?
Thanks
AshishThanks to reply!!
It makes sense for SimpleDateFormat to behave this way.
I was wondering, if i can retrieve millisecs portion with trailing zeros.. instead of padded zeros. Any setting in SimpleDateFormat?
One way, I am experimenting is Timestamp.valueOf()
Thanks
Ashish -
SimpleDateFormat Parse Exception
I am trying to convert a string "20070423"
to a Date and I am getting a parse exception. Can I not parse this format("20070423")?
This is my method
public static Date convertStringToDate(String strDate)
throws ParseException {
Date aDate = null;
try {
if (log.isDebugEnabled()) {
log.debug("converting date with pattern: " + datePattern);
aDate = convertStringToDate(datePattern, strDate);
} catch (ParseException pe) {
log.error("Could not convert '" + strDate
+ "' to a date, throwing exception");
pe.printStackTrace();
throw new ParseException(pe.getMessage(), pe.getErrorOffset());
return aDate;
}Like DrClap said, you pattern must be incorrect. For the string you gave try this
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
System.out.println(dateFormat.parse("20070423"));HTH
-t -
SimpleDateFormat.parse() Problem
My Code:
public class Sdf {
public Sdf() {
SimpleDateFormat s1 = new SimpleDateFormat("DD:MM:yyyy:HH:mm:ss:a:z");
try{
Date myDate = s1.parse("15:11:2006:21:12:13:PM:GMT");
System.out.println(myDate.toString());
catch(Exception ex){
System.out.println("EX");
public static void main(String s[]){
new Sdf();
}The output: Sun Jan 15 21:12:13 GMT 2006
My Problem
The month entered in the parse method is 11 (Nov) but parsing returns January.
I am doing something wrong obviously, so what do I need to do to fix this?
My goal is to get a long value from that string pattern.
Thanks so much, for any help you can give.Hmm, when you think about it, the whole operation is extremely complicated anyway. Accounting for leap years, leap seconds daylight saving times, locale specific stuff and of course 'bad' entry�s such as Jan 32nd.
I spent hours trying to fix that problem. Manually calculating values by multiplying 1000*60*60 for hours, 24 hour time V's 12 hour time was another source of compilcation etc. I pretty much opened a can of worms that I wanted to close quite quickly again.
Some values I'd imagine would have to take precedence over others to limit the many combinations and permutations. What takes precedence over what is another story but I guess reading the API more carefully would eliminate the need to know such things for most purposes.
I certainly won't be forgetting the difference between DD and dd again in a hurry.
Thanks Again. -
Hy,
I've an error when parsing a date with the parse function of the SimpleDateFormat class.
Date birthDate = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmZ");
try {
birthDate = sdf.parse("198012160810Z");
} catch (ParseException e) {
System.out.println(e.getMessage());
The exception Unparseable date: "198012160810Z" is raised.
I've no error if I remove the "Z" at the end of the date. I've checked in the RFC 822, the Z time zone is accepted.
Does somebody knows the problem ?thegillou wrote:
Thanks for your response everybody. I'ts OK.
warnerja : I can't respond to say thank you when I sleep.....you know the timezones..........Sure, but I also know you were answered within 6 minutes after you posted the question. So you really are of the type to post a question and immediately go nighty-night rather than see if there will be replies soon? Hard to believe.
Anyway, you're welcome. -
import java.text.SimpleDateFormat;
class Datum
public Datum()
java.util.Date datum = null;
SimpleDateFormat formatter = new SimpleDateFormat("dd-mm-yyyy");
try
datum = formatter.parse("15-08-2006");
System.out.println(datum.toString());
catch(Exception e)
e.printStackTrace();
public static void main( String args[] )
Datum d = new Datum();
}Parse Dosesn't working Correct.As a result I get DAte with JAnuary MOnth always, no metter what iactal date is.
I use jdk 1.5.0_06
Please help!!SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); // <-- note the uppercase portion...~
-
SimpleDateFormat.parse accepts invalid date string
SimpleDateFormat("dd/MM/yyyy").parse(...) accepts invalid input strings (e.g. "1.1.2gsd001") without raising an exception.
Where I do a mistake?
Example:
import java.text.*;
import java.util.*;
public class Test {
public static void main(String[] args) throws ParseException {
String s = "1.1.2gsd001";
SimpleDateFormat sdf = new SimpleDateFormat("d.M.yyyy");
sdf.setLenient(false);
Date d = sdf.parse(s);
System.out.println(d);
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(d);
The result is: Sun Jan 01 00:00:00 CET 2
Thanks for your help.Tahnks s lot.
Final code is (and it workes well):
import java.text.*;
import java.util.*;
public class Test {
public static void main(String[] args) throws ParseException {
ParsePosition pp = new ParsePosition(0);
String s = "1.1.2001";
SimpleDateFormat sdf = new SimpleDateFormat("d.M.yyyy");
sdf.setLenient(false);
Date d = sdf.parse(s, pp);
if (pp.getIndex() != s.length())
throw new ParseException(String.format("Unparseable date: %s", s), pp.getIndex());
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(d);
} -
Hi
I've got a problem validating date by SimpleDateFormat. Format "yyyy" successfully parses string like "2009-78" into date 01.01.2009. Can you please help me with it?
Here is my code:
SimpleDateFormat format = new SimpleDateFormat("yyyy");
format.setLenient(false);
String dateStr = "2009-78";
Date date;
try {
date = format.parse(dateStr);
} catch (ParseException e) {
date = null;
e.printStackTrace();
System.out.println(String.format("String '%s' parsed to date %s", dateStr, date));Output:
String '2009-78' parsed to date Thu Jan 01 00:00:00 MSK 2009I need an exception to be thrown in such situation. How can I check where the string represents a correct date?
Thanks for your help.
Evgeny
Edited by: su.eug on Apr 13, 2009 12:56 AMRead the comments in the API:
[http://java.sun.com/javase/6/docs/api/java/text/DateFormat.html#parse(java.lang.String)|http://java.sun.com/javase/6/docs/api/java/text/DateFormat.html#parse(java.lang.String)]
You could try the other overload of parse, if you want to test whether the whole String was used:
[http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html#parse(java.lang.String, java.text.ParsePosition)|http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html#parse(java.lang.String,%20java.text.ParsePosition)]
(Sorry--the second link doesn't go to the right place. There is a version of "parse" with two parameters, which you can use to determine if the whole String was used.) -
SimpleDateFormat parse fails !!!
Hi guys, has anyone have a solution to this problem:
SimpleDateFormat fr = new SimpleDateFormat("dd-MM-yyyy");
fr.setLenient(false);
System.out.println(fr.parse("10-10-00"));-SimpleDateFormat seems not capable to parse 00 year when year is in four digit format.
Is there any trick to parse this as a 2000 year as a simple way ???
Thanks in advanceI know if I use 2 digits the problem gets solved, I
need to solve it because there are customers that
need four digits in format, so I need to be able to
parse in 4 digits 2000 year in a faster way
It sounds like you're failing to distinguish between parsing and formatting. If you need to parse a four-digit year, then feed it a string with a four-digit year. You may need to use more than one DateFormat object; e.g., one for parsing, one for formatting.
Formatting a Date Using a Custom Format
Parsing a Date Using a Custom Format
Maybe you are looking for
-
Illustrator CS5: Random Crashes When Saving Or Previewing My Work
Hello Adobe Community, I tend to get errors when I save my work in Illustrator. A few read as follows: "Unknown Error" "Can't Save Illustration" "Not Enough Ram Available" The last error I got read: "Can't finish previewing. There is not enough memor
-
IMovie 11 can't find my projects
I've creaeted several, over 20, projects in iMovie saved to an external hard drive. I just installed iMovie 11, and they do not appear in the project window. I can see the external hard drive, but no projects are listed. How do I tell iMovie where th
-
Funny sort of keyboard problem.
For some reason unknown to myself, the forward slash and apostrophe keys are not working properly on my macbook. On any forum page, including this one, if I hit either of those keys then a little Quick Find Google window opens at the bottom left corn
-
I can watch Netflix fine from Apple tv but when I click onto the Movie Icon it acts as if it's about to show the movie rental selection then goes back to the home screen. Please help!
-
LiveCycle has unhandled win32 exception
Hi, Everybody. LiveCycle was running fine when I logged out last night. This morning opening last nights file produced a "unhandled win32 exception occurred in FormDesigner.exe[5864]. and asked if I wanted to debug. When I selected NO, LiveCycle shu