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.
    -Karen

    You 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
    Matthias

    Since 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
    Ashish

    Thanks 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.

  • SimpleDateFormat parse error

    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.

  • SimpleDateFormat Parse date

    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);
    }

  • SimpleDateFormat parses wrong date successfully (lenient = false). Why?

    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 AM

    Read 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 advance

    I 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