TimeZone Conversion with SimpleDateFormat in Java - java

I have a SimpleDateFormat parser that parse in this way:
sdf = new java.text.SimpleDateFormat("yyyy-MM-DD HH:mm:ss z").parse("2013-10-25 17:35:14 EDT");
log.debug(sdf);
This give me Sat Jan 26 03:05:14 IST 2013
What am i missing here?

First of all, DD stands for day in year, You should use dd instead.
Also, if you want to print a date in a specific format, you need to use two SimpleDateFormats.
SimpleDateFormat.parse returns a Date object represents the date you specified at the given format.
The Date object itself is saved as a regular Date, no format attached to it.
If you want to print it in a specific format, you need to use another SimpleDateFormat and call format method.

you should use Format
SimpleDateFormat sdf1 = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:SS z");
String sdf = sdf1.format(sdf1.parse("2013-10-25 17:35:14 EDT"));

There are two things.
sdf is an object of Date, which represents a specific instant in time (milliseconds elapsed since another instant known as "the epoch"). There is no format which is known to this object. And how this object is printed is solely handled by its class' toString method, which prints the date in this format:
dow mon dd hh:mm:ss zzz yyyy
This is exactly what you see in your output. Note that the timezone of the machine running the program is printed in this case. If you wish to print this object in a format of your choice you should use a DateFormat. To get output for a specific timezone you have to explicitly tell it to the DateFormat object (see below).
Another thing is you should be using dd instead of DD in the pattern. D is for day in year and d is for day in month, which I believe is what you want. Now keeping in mind both the points, this is one of the solutions to your problem:
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("EDT")); // Time Zone for output
Date d = sdf.parse("2013-10-25 17:35:14 EDT");
System.out.println(sdf.format(d)); // You need format method
which outputs:
2013-10-25 17:35:14 EDT

What are the people answering not getting here is more the question:
2013-10-25 17:35:14 EDT != Sat Jan 26 03:05:14 IST 2013
I think it is because 'EDT' is the timezone and so, when it is 17:35 in EDT is is 3:05 in the UK, ignoring Daylight saving adjustments.

Related

Change GMT to EST time in Java 6

I am trying to convert a GMT time zone from other server to EST considering day light saving to display the correct date but not able to do.
The GMT time format is coming in json String as "yyyy-MM-dd 'T' HH:mm:ss 'Z'". To this format we are setting time zone as EST but not getting correct result.
Example - date coming as "2020-06-02T03:53:57Z" , while the correct date in EST when created was "2020-06-01T11:53:57Z".
To convert between two explicit time zones, specify those time zones on the SimpleDateFormat objects used to parse and re-format the date string.
String input = "2020-06-02T03:53:57Z";
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
inputFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = inputFormat.parse(input);
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
outputFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println(outputFormat.format(date));
Output
2020-06-01 23:53:57 EDT
As you can see, in June, the time zone is EDT, not EST, and it is certainly not Z, aka UTC.

Java SimpleDateFormat parsing irregularities

I'm doing some date parsing in Java and am encountering some weird behavior.
I have a date string such as follows:
String s = "Sun Aug 11 2013 11:00:00 -0700 (Pacific Daylight Time)"
I'm trying to parse it into a date object like so:
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss Z (zzzz)");
I then print out the resulting date object from sdf.parse(s) and get:
Sun Aug 11 12:00:00 CDT 2013
I am in the central time zone, so it makes sense that it prints it as such, however, CDT is -0500, so the parsed date should be 13:00, not 12:00.
The odd thing is, if I remove either of the redundant pieces of time zone information, the date parses correctly. Using the format "EEE MMM dd yyyy HH:mm:ss Z ('Pacific Daylight Time')" or the format "EEE MMM dd yyyy HH:mm:ss '-0700' (zzzz)" results in the correct date:
Sun Aug 11 13:00:00 CDT 2013
This behavior seems to only occur with dates that fall within daylight savings time. If I instead parse a date in, say, December, with my initial date format, I get the correct result.
I have somewhat limited control over the format of the dates I'm parsing, and they could be coming from a variety of time zones. Has anyone encountered this behavior before, and is there a way to get around it without changing the format of the date string? I realize the time zone designations are redundant, but they aren't incorrect as far as I can tell.
There have certainly been bugs in Java's handling of daylight saving time and time zones in the past, and this sure looks like one you've found. What version of Java is this?
You might want to try giving Joda-Time a try to see if it handles the given date correctly.
If Joda doesn't help, you might need to try pre-parsing some of that date string to remove the descriptive time zone in parenthesis since it works when only one is defined. Very strange indeed!

Date format return wrong date

I'm trying to format a Date object and convert that formatted one back to Date type object
This is my code
SimpleDateFormat inputDf = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss zzz");
System.out.println("before format "+invoiceDate);
invoiceDate=inputDf.parse(inputDf.format(invoiceDate));
System.out.println("after format "+inputDf.format(invoiceDate));
System.out.println("after parse "+invoiceDate);
Out put from above code is
before format : Mon Jan 14 10:55:40 IST 2013
after format : Mon Jan 14 2013 10:55:40 IST
after parse : Mon Jan 14 10:55:40 IST 2013
You can see here after i parse the date object it converting back to original format(format which shows before format) but i want Date object like it appear in second print line(after format) thing is .format method returns String not a Date object, how can i fix this ?
Thanks
The Date object doesn't define any format. Date is just a long number with time in it.
In order to modify its format you have to use a String object, as you did in your example.
If you analyze your example:
before format: Shows the DEFAULT format for a Date that System.out.println offers.
after format: Shows the format given after using the SimpleDateFormat.
after parse: We are again in the first case.
This behaviour is because the SimpleDateFomat does not impose itself upon the date. The SimpleDateFormat is merely a pattern to get a formated output out of any Date, but it does not change the date itself. Date does not have a format, so
System.out.println("before format "+invoiceDate);
defaults to the default pattern format.
Actually, the SimpleDateFormat is exactly the way to achieve what you want, ie use it to properly format your output everytime you need it. Formating a date object gives you a representation of it, a String.
System.out.println("after parse "+invoiceDate);
Here you just trying to print the Date object . The Date object , per se, doesn't have any format. The class Date represents a specific instant in time, with millisecond precision. Hence we use DateFormat to format the output string which is printed on printing the Date object . To display the same output as second statement , you need to format it again.
System.out.println("after parse"+inputDf.format(invoiceDate));
Look at the Javadoc for implementation of the toString() for Date :
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy

How to modify my code to only get the time portion of a date?

I've got the following code:
Date time = new SimpleDateFormat("HH:mm").parse("8:00");
When I call time.toString(), the following is produced:
Thu Jan 01 08:00:00 CET 1970
Is there any way I can extract just the 8:00 from it? I have searched far and wide and have not found any way to do it using the standard SimpleDateFormat.
When I call time.toString(), the following is produced
Yes, it would be - because you're calling Date.toString. A Date value has no concept of format.
Is there any way I can extract just the 8:00 from it?
Whenever you want to convert to a string, you should use a DateFormat. So use the same format that you parsed in.
Alternatively, use Joda-Time, which has a LocalTime type specifically for "time of day", and has a handy parse method. You should still use a formatter every time you want to convert to a string, but at least the value will be easier to work with and more descriptive before then.
LocalTime localTime = LocalTime.parse("8:00");
To format this, you can use something like ISODateTimeFormat.hourMinute() or if you might have more precision, perhaps ISODateTimeFormat.hourMinuteSecond() - see the docs for all of the many options available.
recycle your original SimpleDateFormat Object
SimpleDateFormat format = new SimpleDateFormat("HH:mm")
Date time = format.parse("8:00");
String outString = format.format(time);
in case you were wondering, Here's some more information on DateTime Masks
Use the same SimpleDateFormat instance to format date into string.
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
Date time = sdf.parse("8:00");
System.out.println(sdf.format(time));
This will print:
08:00
java.util.Date class represents a specific instant in time, with millisecond precision.
API says java.util.Date.toString()
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
In order to format date's use SimpleDateFormat class
System.out.println(new SimpleDateFormat("HH:mm").format(time));

How can I use Java's SimpleDateFormat to parse a timezone given as "GMT+0100 (BST)"?

I have a date that's in the form of:
Wed Aug 17 2011 09:57:09 GMT+0100 (BST)
and have a filter that takes a time in a certain format. The problem seems to be the time zone on the end, none of the format strings I'm putting in the filter seem to work for this type of date format.
For example,
Wed Aug 17 2011 09:57:09 GMT+0100 (BST)
EEE MMM dd yyyy HH:mm:ss zZ?
The time zone part of this, keeps throwing an error.
Can anyone tell me what the correct format to parse the time zones on these dates is?
"z" needs a colon between hours and minutes. "Z" is only +/-HHMM (i.e. no "GMT" prefix).
One way to parse it is: EEE MMM dd yyyy HH:mm:ss 'GMT'Z. The "BST" bit is ignored, and it's based on assumption that there's always "GMT" before offset.
I would parse out and interpret the time zone information separately, then use that to construct the Date/Calendar object in the proper time zone.
The following code seems to work well enough with your example:
String source = "Wed Aug 17 2011 09:57:09 GMT+0100 (BST)";
String tzid = "GMT" + source.substring(28, 31)
+ ":" + source.substring(31, 33);
TimeZone tz = TimeZone.getTimeZone(tzid);
// if (tz == null) ?
SimpleDateFormat f = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss");
f.setTimeZone(tz);
Date date = f.parse(source);
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(date);
Prints "Wed Aug 17 08:57:09 UTC 2011".
A more sophisticated approach would be to use regex to extract individual parts ("+/-", "hh" and "mm") of the time zone offset.
Alternatively, you can attempt to discern the 3-letter time zone id (the string in between ( and )), and use the corresponding Java TimeZone if it exists.
In your particular example, though, "BST" resolves to Bangladesh Time which is GMT+0600 so you're better off with the numeric offset. "BST" here should probably be taken as British Summer Time (GMT+0100). This can be important because numeric offsets do not indicate the use of daylight savings time, which can be in effect depending on the date.
A more heuristic routine could take this into account and attempt to resolve the name first, but verify that the GMT offsets match, and fallback on the simple "GMT+hh:mm" timezones otherwise.
If you can not find a pattern matching your use case, try:
try{
new Date("Wed Aug 17 2011 09:57:09 GMT+0100 (BST)")
}catch(Exception e)
{
// Parse exception
}

Categories

Resources