SimpleDateFormat Problem while Parsing Date/time String on Japanese OS

S

shilpa

Hi there,

I am trying to parse Date/Time String : 2001/05/10 3:45:35 on Japanese
OS.

I know we can have exact Date Time formatting pattern to match this
string and can parse it easily.

But I am wondering why Date/Time Pattern yy/MM/dd hh:mm matches for
this string and return me date as : Thu May 10 03:45:00 PDT 2001 on
Japanese OS.

and because of this I am loosing seconds.

Does anybody knows why this is happening?

I have setLenient(false).

Best Regards,
Shilpa
 
R

Roedy Green

I am trying to parse Date/Time String : 2001/05/10 3:45:35 on Japanese
OS.

I know we can have exact Date Time formatting pattern to match this
string and can parse it easily.

It is not a bug, it's a feature!

quoting from
http://java.sun.com/j2se/1.5.0/docs/api/java/text/SimpleDateFormat.html

-------------------------------
Year: For formatting, if the number of pattern letters is 2, the year
is truncated to 2 digits; otherwise it is interpreted as a number.

For parsing, if the number of pattern letters is more than 2, the year
is interpreted literally, regardless of the number of digits. So using
the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.

For parsing with the abbreviated year pattern ("y" or "yy"),
SimpleDateFormat must interpret the abbreviated year relative to some
century. It does this by adjusting dates to be within 80 years before
and 20 years after the time the SimpleDateFormat instance is created.
For example, using a pattern of "MM/dd/yy" and a SimpleDateFormat
instance created on Jan 1, 1997, the string "01/11/12" would be
interpreted as Jan 11, 2012 while the string "05/04/64" would be
interpreted as May 4, 1964.

During parsing, only strings consisting of exactly two digits, as
defined by Character.isDigit(char), will be parsed into the default
century. Any other numeric string, such as a one digit string, a three
or more digit string, or a two digit string that isn't all digits (for
example, "-1"), is interpreted literally. So "01/02/3" or "01/02/003"
are parsed, using the same pattern, as Jan 2, 3 AD. Likewise,
"01/02/-3" is parsed as Jan 2, 4 BC.
---------------------------------

So if you want to be strict, you must do your own format check first
to make sure the fields are the correct length.

You could invent a simple mask checking class that allowed a mask to
be defined something like this:

"9999/99/99 Z9:99:99"

/-: must be literally that value.
9 must be digit 0-9
Z must be space or digit 0-9
space must be space
A - must be upper case letter
a - must be lower case letter


or if you wanted to permit variable width fields, write a regex
checker.
 
S

shilpa

Thank you ....
Actually pattern yy/MM/dd hh:mm is matching for string 2001/05/10
3:45:35.
So my date part is coming fine..but I am loosing seconds.
i.e: my date after parsing string is: Thu May 10 03:45:00 PDT 2001

So time is wrong, why it is matching "hh:mm" for string 03:45:00 ?
 
R

Roedy Green

Thank you ....
Actually pattern yy/MM/dd hh:mm is matching for string 2001/05/10
3:45:35.
So my date part is coming fine..but I am loosing seconds.
i.e: my date after parsing string is: Thu May 10 03:45:00 PDT 2001

So time is wrong, why it is matching "hh:mm" for string 03:45:00 ?

I am sorry I can't follow what you are saying. Please post the code
with your parse mask and a sample date you are parsing.

You seem to be saying your mask has no seconds part, and you are
puzzled why you are losing seconds. That makes no sense.
 
S

shilpa

My code is generic code which will loop thr' all date/time format and
will try to find match.
What I am saying is on Japanese System pattern : yy/MM/dd hh:mm is
getting matched for String " 2001/05/10 3:45:35"
and becos of this I am lossing seconds. My code part is:

int[] dStyle = {DateFormat.SHORT, DateFormat.MEDIUM, DateFormat.LONG,
DateFormat.FULL};

int dS, i ;

for (i=0; i < dateStyles.length && flag== false; i++)
{
dS = dStyle;
try
{
dateFormat = DateFormat.getDateTimeInstance(dS,
dStyle);
dateFormat.setLenient(false);
date = dateFormat.parse(stringDateTime);
flag= true;

}
catch(Exception e)
{

}
 
C

Chris Uppal

shilpa said:
What I am saying is on Japanese System pattern : yy/MM/dd hh:mm is
getting matched for String " 2001/05/10 3:45:35"
and becos of this I am lossing seconds.

The DateFormat.parse() method looks for a parseable date at the /begining/ of
the supplied string, it does not require that the parsed date is /all/ of the
supplied string (poor API design, but there you go...). In your case you need
to be able to tell how much of the String was actually a formatted date, so you
will have to use the alternate form of DateFormat.parse() that takes a
ParsePosition argument too.

-- chris
 
S

shilpa

Thanks Chris :)
Yeah, I guess this is the issue...will try and will let you know about
same.

Cheers :)
Shilpa
 
S

shilpa

Thanks Chris..Its working perfectly fine...:)

I have one more doubt here...On German OS pattern "dd.MM.yyyy H:mm"
matches for date/time "19.05.97 00:00"

and returns me wrong date : Fri May 19 00:00:00 GMT+05:30 0097 .

Any comments on this?

Thanks,
Shilpa
 
C

Chris Uppal

shilpa said:
I have one more doubt here...On German OS pattern "dd.MM.yyyy H:mm"
matches for date/time "19.05.97 00:00"

and returns me wrong date : Fri May 19 00:00:00 GMT+05:30 0097 .

Any comments on this?

Not really. I'm not sure whether this is a bug, but on the whole I suspect
not. In either case you have to work around it.

One thing I'd do is try all the options, rather than stopping at the first one
that "worked". That would have two benefits, one is that you could detect when
you had an ambiguous date and try to deal with that ambiguity somehow (throw an
excpetion, prompt the user for more data, select one option arbitrarily but
write a log entry to say that you have done so,.... whatever). The second is
that you could handle cases like this rather better.

I guess you need a layer of sanity checking anyway (to eliminate dates like
0097 AD for instance ;-), and you could use that together with the complete
list of possible interpretations to make the system more reliable. First work
out all the interpretations that the parse() method thinks are OK, and then
filter that by removing all the implausible values. If that leaves exactly one
candidate then accept it, otherwise go into some sort of error recovery mode.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top