different results for SimpleDateFormat in local and live environments - java

I have the following code
public String getDate(Date date) throws Exception{
String finalDate = "";
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
finalDate = formatter.format(date);
return finalDate;
}
I passed the input for this method as 9999-12-30 18:30:00.0.
In my live environment the result is :12/30/9999
In my local environment the result is :12/31/9999
What might be the reason for this strange behaviour. Thanks in advance..

Because there is a timezone difference between your live environment and local

To force your dateformat to use a specific time zone, for example UTC, you can use:
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));

Time zone format for sure. I would recommend you instead of using SimpleDateFormat use JodaTime.
Also if you want prevent time zone problem for all environments formatter.setTimeZone("UTC")

#psr as you mentioned that your local server is in India and production is in US.
The timezone is the issue so it is creating this problem.
Since your production server is in US, try this.
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));

One good thing to keep in mind is that java.util.Date does not have a notion of time zone in it. I'm always surprised how few people know that. So if you want unified results in your application, make sure you use timezone when you parse and when you print.
As #assylias said, you can set timezone of date formatter to achieve this.

Related

How do I convert timestamp string to local time string?

I have timestamp string: "1989-01-01 00:00:00" and i need convert it to local date format.
I execute:
SimpleDateFormat TIMESTAMPFORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DateFormat.getDateFormat(getContext()).format(TIMESTAMPFORMAT.parse("1989-01-01 00:00:00"));
And getDateFormat returns 31.12.1988
Why?
How can I receive 01.01.1989???
In order to skip time-zone when formatting, I would suggest you to set it to default as below:
SimpleDateFormat TIMESTAMPFORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TIMESTAMPFORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
This is probably to do with the time zones involved. I strongly suspect that you're formatting in a different time zone to the one you're using for parsing, and the value goes to before midnight, basically. If you can use the same time zone on both, it's likely to work.
If you possibly can, I'd encourage you to use Joda Time instead though - you really want a LocalDate.

Can I use one SimpleDateFormat pattern for dates with both 'Z' and '+1:00' suffixes?

I call a service which returns GMT dates. Its been working fine since November, but now with daylight savings time active, its failing. Here's a sample date from non-daylight savings time:
2011-12-07T15:50:01Z
And one from today (in daylight savings time):
2012-03-26T11:05:01+01:00
Previously I've been using this pattern:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.UK);
But its failing on the second date above with a ParseExcepton ("Unparsable date..."). So, can one pattern be used for both, and if so what is it? If I can't use one pattern for both, what is the correct pattern for the second date above?
It shouldn't make a difference, but if it does this is in use on the Android platform.
It definitely makes a difference that you're using Android, as it would make a difference in this case if you were using Java 5/6 or 7.
The pattern you're using specifies a literal 'Z' (also 'T') to be parsed. It is not parsing a timezone. You need to drop the single-quotes from around the 'Z' to start parsing an actual time-zone.
According to the Android JavaDoc, it is unclear whether a capital Z will even work in this case, as the format of the hours/minutes is pretty specific. I don't know enough about the Android SDK to confirm, but the colon definitly makes a difference in standard Java.
The new ISO8601 time zone pattern is covered by the X pattern specifier which is introduced in Java 7.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.UK);
If you're still on Java 6 or older, then yes it may make difference. You'll need either to parse it (partially) yourself or to grab Joda Time.
In case you use java6, you will have to identify the patterns and then apply the formater
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
String date2Str="2011-12-07T15:50:01Z";
Date date2 = df.parse(date2Str);
System.out.println(date2.toString());
SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz");
String date1Str="2012-03-26T11:05:01GMT+01:00";
Date date1 = df2.parse(date1Str);
System.out.println(date1.toString());

java Calender/formatter provides wrong date

Somehow I am being reported a issue, in which following code provides date in future.
The timezone used is GMT+01:00.
The numberOfDays is non negative integer.
The intention of this code is reduce the number of days from current date.
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yy",Locale.ENGLISH);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -numberOfDays);
Date date = calendar.getTime();
String dateStr= formatter.format(date);
System.out.println("Date : "+dateStr);
I am not able to reproduce this on my machine.
Does the Locale affect the TimeZone?
I tried to correlate to Why does a new SimpleDateFormat object contain calendar with the wrong year?, and Strange problem with timezone, calendar and SimpleDateFormat but in vain.
Please help me understand and rectify this issue.
Well, two possibilities I can think of off the top of my head:
The system date on the client machine is incorrect, so the calendar starts with a date in the future
If numberOfDays is negative, it will obviously push the date into the future
The Locale isn't directly related to the time zone - they're independent, although obviously a machine with a French locale is likely to be in a French time zone etc.
Personally I would avoid using Date/Calendar entirely and use Joda Time as a much nicer date and time API, but that wouldn't help with either of the ideas I gave above...

Java: Is this a correct way to get the current time as a Calendar object in a particular time zone?

I know there are other similar questions to this, but I came up with my own way of getting the current time in a specific time zone, so I just wanted to confirm if it is correct or not, or there are gotchas I didn't take care of.
Calendar cal = Calendar.getInstance();
// Assuming we want to get the current time in GMT.
TimeZone tz = TimeZone.getTimeZone("GMT");
cal.setTimeInMillis(calendar.getTimeInMillis()
+ tz.getOffset(calendar.getTimeInMillis())
- TimeZone.getDefault().getOffset(calendar.getTimeInMillis()));
// Calendar should now be in GMT.
Is the above correct at all? I did my own test and it seemed to be working as expected, but just wanted to confirm it again with the experts in Stack Overflow.
If you simply do a Calendar.getInstance with the TimeZone argument, the calendar's internal state for the get() methods will return you the field with the time for that timezone. For example:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
// if i run this at 9 EST this will print 2
System.out.println(cal.get(Calendar.HOUR));
If you just need the local time for display purposes, you can set the TimeZone on your format object. For example:
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(sdf.format(new Date()));
Like Macarse said though, Joda time is where it's at if you need to do anything more complex. The Java date APIs are a nightmare.
I'd prefer using joda-time instead of that.
Check this link.

format as GMT/UTC time when default timezone is something else

I have a program which needs to run under my local timezone for other reasons, but for one procedure i need to output dates using a SimpleDateFormat in GMT.
what is the tidiest way to do this?
Using the standard API:
Instant now = Instant.now();
String result = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withZone(ZoneId.of("GMT"))
.format(now);
System.out.println(result);
The new DateTimeFormatter instances are immutable and can be used as static variables.
Using the old standard API:
TimeZone gmt = TimeZone.getTimeZone("GMT");
DateFormat formatter = DateFormat.getTimeInstance(DateFormat.LONG);
formatter.setTimeZone(gmt);
System.out.println(formatter.format(new Date()));
Given that SimpleDateFormat isn't thread-safe, I'd say that the tidiest way is to use Joda Time instead. Then you can create a single formatter (calling withZone(DateTimeZones.UTC) to specify that you want UTC) and you're away:
private static DateTimeFormatter formatter = DateTimeFormat.forPattern(...)
.withZone(DateTimeZone.UTC);
...
String result = formatter.print(instant);
This has the other benefit that you can use Joda Time elsewhere in your code, which is always a good thing :)

Categories