my joda time zone messup - java

guys.
im newbie in using joda time api. so here is my question. Ive app server deploy somewhere in the western region and the date fixed to the particular time , Fri Feb 6 08:50:54 UTC 2015.
however, i try to use joda time zone to change the timezone to my country. it didnt worked out. i have run out of ideas. below is my code :
java.util.Date dateIn = new java.util.Date();
DateTime dateTimeUtc = new DateTime( dateIn, DateTimeZone.UTC );
System.out.println("date time utc : " + dateTimeUtc);
DateTimeZone timeZoneLos_Angeles = DateTimeZone.forID( "America/Los_Angeles" ); // Adjust time zone to United States.
DateTime dateTimeLos_Angeles = dateTimeUtc.withZone( timeZoneLos_Angeles );
System.out.println("los angeles date time : " + dateTimeLos_Angeles.toDate());
DateTimeZone timeZoneMalaysia = DateTimeZone.forID( "Asia/Singapore" );
DateTime dateTimeKL = dateTimeLos_Angeles.withZone( timeZoneMalaysia );
System.out.println("KL date time : " + dateTimeKL.toDate());
java.util.Date newDate = dateTimeKL.toDate();
System.out.println("after convert to j.u.Date : " + newDate);
the output:
date time utc : 2015-02-06T08:58:29.127Z
los angeles date time : Fri Feb 06 16:58:29 SGT 2015
KL date time : Fri Feb 06 16:58:29 SGT 2015
after convert to j.u.Date : Fri Feb 06 16:58:29 SGT 2015
i dont know what's going on now. joda time is using my local machine time.
can u guys explain what is happening here? am i accessing joda time in wrong way. or is it my mistake?

A java.util.Date is basically the same thing as a joda-time Instant: an instant on the universal time scale. It doesn't have any time zone. It's just a number of milliseconds wrapped into an object. So when you call toString() on a java.util.Date instance, this object tries to make this number of millisecond readable to you, and transforms it to a readable date using the default timezone of the JVM: SGT in this case.
If you want to see a date in a given timezone, then print the DateTime instance itself (which contains an instant and a time zone) instead of transforming it to a Date (which loses the timezone information), or use a SimpleDateFormat configured with the timezone you want to display the java.util.Date to a string in the wanted time zone.

Joda Time provides a quality replacement for the Java date and time classes. The design allows for multiple calendar systems, while still providing a simple API. Converting a Joda DateTime object from one timezone to another is pretty easy and saves you quite a number of lines of code. See method below.
public static Date convertJodaTimezone(LocalDateTime date, String srcTz, String destTz) {
DateTime srcDateTime = date.toDateTime(DateTimeZone.forID(srcTz));
DateTime dstDateTime = srcDateTime.withZone(DateTimeZone.forID(destTz));
return dstDateTime.toLocalDateTime().toDateTime().toDate();
}
Since Joda Time has its own class for storing Date and Calendar objects, the DateTime class has its own toDate() method for converting it to a java.util.Date.
For further example check this link

I reused your code and did some changes. The commented lines were the previous implementation so that you can compare the difference with the new implementation.
Date dateIn = new Date();
DateTime dateTimeUtc = new DateTime( dateIn, DateTimeZone.UTC );
System.out.println("date time utc : " + dateTimeUtc);
DateTimeZone timeZoneLos_Angeles = DateTimeZone.forID( "America/Los_Angeles" ); // Adjust time zone to United States.
//DateTime dateTimeLos_Angeles = dateTimeUtc.withZone( timeZoneLos_Angeles );
DateTime dateTimeLos_Angeles = dateTimeUtc.withZone(timeZoneLos_Angeles);
//System.out.println("los angeles date time : " + dateTimeLos_Angeles.toDate());
System.out.println("los angeles date time : " + dateTimeLos_Angeles.toLocalDateTime().toDate());
DateTimeZone timeZoneMalaysia = DateTimeZone.forID( "Asia/Singapore" );
DateTime dateTimeKL = dateTimeUtc.withZone(timeZoneMalaysia);
//System.out.println("KL date time : " + dateTimeKL.toDate());
System.out.println("KL date time : " + dateTimeKL.toLocalDateTime().toDate());
//Date newDate = dateTimeKL.toDate();
Date newDate = dateTimeKL.toLocalDateTime().toDate();
System.out.println("after convert to j.u.Date : " + newDate);
I hope this one works for you. If you can optimize this code further then great. Cheers!

Related

JodaTime - how to get current time in UTC

I want to get the current time in UTC. What I do so far is following (just for testing purposes):
DateTime dt = new DateTime();
DateTimeZone tz = DateTimeZone.getDefault();
LocalDateTime nowLocal = new LocalDateTime();
DateTime nowUTC = nowLocal.toDateTime(DateTimeZone.UTC);
Date d1 = nowLocal.toDate();
Date d2 = nowUTC.toDate();
L.d("tz: " + tz.toString());
L.d("local: " + d1.toString());
L.d("utc: " + d2.toString());
d1 is my local time, that's fine
d2 is my local time + 1, but should be local time - 1...
My local time zone is UTC+1 (according to the debug output and the list here: https://www.joda.org/joda-time/timezones.html)...
How do I correctly convert from one time zone to another (inclusive the millisecond representation)?
EDIT
I need the date/milliseconds... It's NOT about displaying the time correctly....
EDIT 2
Now, with the help of a comment and an answer, I tried following:
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);
Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();
L.d(Temp.class, "------------------------");
L.d(Temp.class, "tz : " + tz.toString());
L.d(Temp.class, "local : " + nowLocal + " | " + dLocal.toString());
L.d(Temp.class, "utc : " + nowUTC + " | " + dUTC.toString()); // <= WORKING SOLUTION
L.d(Temp.class, "utc2 : " + nowUTC2 + " | " + dUTC2.toString());
OUTPUT
tz : Europe/Belgrade
local : 2015-01-02T15:31:38.241+01:00 | Fri Jan 02 15:31:38 MEZ 2015
utc : 2015-01-02T14:31:38.241 | Fri Jan 02 14:31:38 MEZ 2015
utc2 : 2015-01-02T14:31:38.241Z | Fri Jan 02 15:31:38 MEZ 2015
What I wanted was, that the local date displays 15 o'clock and utc date displays 14 o'clock...
For now, this seems to work...
----- EDIT3 - Final solution -----
Hopefully, this is a good solution... I think, i respects all tipps i got...
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowUTC = new DateTime(DateTimeZone.UTC);
DateTime nowLocal = nowUTC.withZone(tz);
// This will generate DIFFERENT Dates!!! As I want it!
Date dLocal = nowLocal.toLocalDateTime().toDate();
Date dUTC = nowUTC.toLocalDateTime().toDate();
L.d("tz : " + tz.toString());
L.d("local : " + nowLocal + " | " + dLocal.toString());
L.d("utc : " + nowUTC + " | " + dUTC.toString());
Output:
tz : Europe/Belgrade
local : 2015-01-03T21:15:35.170+01:00 | Sat Jan 03 21:15:35 MEZ 2015
utc : 2015-01-03T20:15:35.170Z | Sat Jan 03 20:15:35 MEZ 2015
You're making it far more complicated than you need to:
DateTime dt = new DateTime(DateTimeZone.UTC);
No conversion required at all. If you find you actually need to convert, you can use withZone. I'd suggest you avoid going via LocalDateTime, however, as that way you can lose information due to time zone transitions (two different instants can have the same local time in the same time zone, because clocks go back and repeat local time.
Having said all of this, for the sake of testability I personally like using a Clock interface which allows me to get the current time (e.g. as an Instant). You can then use dependency injection to inject a real system clock when running in production, and a fake clock with a preset time for tests. Java 8's java.time package has this idea built into it, btw.
You can also use the static method now which makes it even more readable
DateTime.now(DateTimeZone.UTC)
Use this
DateTime.now().withZone(DateTimeZone.UTC)
and if you want to format, you can use
DateTime.now().withZone(DateTimeZone.UTC).toString("yyyyMMddHHmmss")
Please try to listen to Jon Skeets good advise and comments. Here an additional explanation. Your edit-2 contains a mistake:
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);
Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();
If you call toDate() on an object nowUTC of type LocalDateTime then you can get surprises - see javadoc. Joda-Time claims to use the same fields in java.util.Date as in nowUTC. What does this mean? Let's analyze:
nowUTC.toString() produces 2015-01-02T14:31:38.241 That is without timezone (note the missing Z at the end), so it is just a plain local timestamp. By context, we know it was generated in UTC. In your next step however, you convert it to a java.util.Date using the mentioned method above. This method combines the local timestamp with the system timezone (Belgrade) PRESERVING the FIELDS, hence CHANGING the instant. So you have finally miscorrected your instant. And your second line is wrong.
If you just want
utc date displays 14 o'clock
then don't use the questionable and misleading conversion method Joda-Time offers. Use instead a dedicated formatter with the pattern "EEE MMM dd HH:mm:ss zzz yyyy" or similar (Joda-Time offers DateTimeFormatter). Set the UTC-offset on this formatter and print. Done. Abandon completely any call of java.util.Date.toString(). This way, you don't even need to do any dangerous conversion at all.
From here: http://www.joda.org/joda-time/userguide.html#Changing_TimeZone
// get current moment in default time zone
DateTime dt = new DateTime();
// translate to London local time
DateTime dtLondon = dt.withZone(DateTimeZone.forID("Europe/London"));
The resulting value dtLondon has the same absolute millisecond time, but a different set of field values.
You can substitute `Europe/London' for the timezone you want (UTC). See this list of proper time zone names.
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
// or SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yyyy KK:mm:ss a Z" );
sdf.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
System.out.println( sdf.format( new Date() )
);
Instead of System.out.println( sdf.format( new Date() ) put your local date
I fixed this with this converter
public class DateTimeConverter implements AttributeConverter<DateTime, Date> {
#Override
public Date convertToDatabaseColumn(DateTime attribute) {
return attribute == null ? null
: new Date(attribute
.withZone(DateTimeZone.UTC)
.withZoneRetainFields(DateTimeZone.getDefault())
.getMillis());
}
#Override
public DateTime convertToEntityAttribute(Date dbData) {
return dbData == null ? null
: new DateTime(dbData.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
}
}
Dates are stored as UTC and recovered with your current time zone

Converting to UTC considering daylight saving

I have a date, for example Thu April 17 09:03:01 GMT 2014 in the timezone:
sun.util.calendar.ZoneInfo[id="Europe/London",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=Europe/London,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]
and everytime a try to convert to UTC it returns Thu April 17 10:03:01 GMT 2014
This does not make sense because the corresponding UTC time is actually Thu April 17 08:03:01 GMT 2014 since that the in my timezone time is added 1hour due to daylight savings.
The code I use to convert is this:
//timeZone - id="Europe/London"
public static Date timeZoneConvertDate(Date date, TimeZone timeZone) {
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(timeZone);
sdf.applyPattern("dd-MM-yyyy HH:mm:ss");
String newDate = sdf.format(date);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date nd = sdf.parse(newDate);
return nd;
} catch (ParseException e) {
return null;
}
}
Could someone explain what I'm doing wrong?
tl;dr
A Date has no timezone associated with it, so you cannot create a method that adjusts the timezone of a date object. You need to work with Calendar objects if you want to retain TZ information or, preferably, take a look at Joda-Time.
Explanation of Your Output
A Date value has no timezone information; it's merely the number of milliseconds since the epoch. With that in mind, let's see what you're doing:
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(timeZone);
sdf.applyPattern("dd-MM-yyyy HH:mm:ss");
String newDate = sdf.format(date);
This part of your code creates a formatter that will print the date in the London timezone. So the result you'll get at the time of writing is approximately: 17-04-2014 11:38:15 (assuming you just created your date object).
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date nd = sdf.parse(newDate);
return nd;
} catch (ParseException e) {
return null;
}
Here you tell the date parser to read the date as though it were a UTC date. It uses that information to know how many milliseconds since the epoch have passed. The date object you get back still has no timezone associated with it.
UTC is an hour behind British Summer Time, so it will create a date object that appears an hour ahead when printed in the BST timezone. So when I print nd, I get: Thu Apr 17 12:38:15 BST 2014.
No Time Zone In java.util.Date
As the correct answer by Duncan said a java.util.Date has no time zone component. Confusingly its toString method applies the JVM's default time zone. To display in another time zone, use SimpleDateFormat to apply an adjustment.
Even better, avoid the notoriously troublesome java.util.Date, .Calendar, and SimpleDateFormat. Use either Joda-Time or the new java.time package in Java 8.
Joda-Time
In Joda-Time, a DateTime object truly does contain an assigned time zone. If you do not specify a time zone, the JVM's default time zone is assigned.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/London" );
DateTime dateTime = new DateTime( 2014, 4, 17, 9, 3, 1, timeZone );
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
DateTime dateTimeIndia = dateTime.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
When run…
dateTime: 2014-04-17T09:03:01.000+01:00
dateTimeUtc: 2014-04-17T08:03:01.000Z
dateTimeIndia: 2014-04-17T13:33:01.000+05:30 (note the half-hour difference, +05:30)
You can easily convert back and forth to java.util.Date.
DateTime dateTime = new DateTime( myJUDate, timeZone );
…and…
Java.util.Date date = dateTime.toDate();

issue with date/timezone in Java

I need to display time zone in CET in my java application.
And I am using following code to achieve this.
String OLD_FORMAT = "yyyyMMdd HH:mm:ss";
String NEW_FORMAT = "dd.MM.yyyy HH:mm:ss";
String date = "20140217 14:45:28";
SimpleDateFormat sdf = new SimpleDateFormat(OLD_FORMAT);
TimeZone zone = TimeZone.getTimeZone("GMT+1");
sdf.setTimeZone(zone);
Date d = null;
d = sdf.parse(date);
sdf.applyPattern(NEW_FORMAT);
date = sdf.format(d);
and I am using the date object to print the date on UI.
OR
TimeZone zone = TimeZone.getTimeZone("CET");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
sdf.setTimeZone(zone);
But using the either of above piece of code i am getting GMT time which is one hour behind CET.
FOr example if I execute the code now, I will get 1:32:50 PM where as its 2:32:50 PM as per http://wwp.greenwichmeantime.com/time-zone/europe/european-union/central-european-time/
Any one any idea what might be going wrong here ?
UPDATE : I have found the issue. I made a silly mistake as I had to set the time first to GMT (the datetime i was getting was in GMT) and then change it to CET. Its working now. Thanks much everyone for the reply.
Maybe you are passing the wrong date to the SimpleDateFormat instance. I've written a small to test your code and it seems to work:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
public class Test {
public static void main(String[] args) {
TimeZone zone = TimeZone.getTimeZone("GMT+1");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
sdf.setTimeZone(zone);
TimeZone zone2 = TimeZone.getTimeZone("CET");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
sdf2.setTimeZone(zone2);
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 15);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.setTimeZone(TimeZone.getTimeZone("GMT+3"));
System.out.println(sdf.format(c.getTime()));
System.out.println(sdf2.format(c.getTime()));
}
}
java.util.Date does not have a TimeZone, it's essentially a long (milliseconds since epoch). If you want to keep the timezone, you must use java.util.Calendar or even better, use joda-time
The second piece of code should do the trick.
Note that CET in java actually means CET in winter and CEST in summer which is what you want I assume. GMT+1 would not actually switch to summer time so you'd be stuck in winter time if you use that.
If the outputted value is still wrong you are giving it the wrong date to format.
Perhaps you made the same timezone error when parsing the date?
Avoid 3-Letter Codes
Those three-letter time zone codes are neither standardized nor unique. And they get confusing with regards to Daylight Saving Time (DST). Instead use proper time zone names.
There are a few dozen such names for +01:00. Choose the one that represents your applicable rules for DST and other anomalies. My example code arbitrarily chose Paris time zone.
Confusing Question
I could not understand if your input string represented a date-time at UTC or already in a +01:00 time zone. My example code below has two variations, covering both cases.
Also, you would have found your question already asked and answered many times on StackOverflow if you searched.
Joda-Time
The bundled java.util.Date and Calendar classes are notoriously troublesome. Avoid them. Use either:
Joda-Time
java.time.* package, new in Java 8(informed by Joda-Time, defined by JSR 310, and supplanting the old Date/Calendar classes)
Example Code
String input = "20140217 14:45:28";
// Formatters
DateTimeFormatter formatterInput = DateTimeFormat.forPattern( "yyyyMMdd HH:mm:ss" );
DateTimeFormatter formatterOutput = DateTimeFormat.forPattern( "dd.MM.yyyy HH:mm:ss" );
// Use a proper time zone name rather than 3-letter codes.
DateTimeZone timeZoneParis = DateTimeZone.forID( "Europe/Paris" );
// If that input was meant to be in UTC, and then adjusted to +01:00.
DateTime dateTimeAsUtc = formatterInput.withZone( DateTimeZone.UTC ).parseDateTime( input );
DateTime dateTimeAdjustedToParis = dateTimeAsUtc.withZone( timeZoneParis );
// Or, if that input was already in +01:00.
DateTime dateTimeAsParis = formatterInput.withZone( timeZoneParis ).parseDateTime( input );
Dump to console…
System.out.println( "input: " + input );
System.out.println( "dateTimeAsUtc: " + dateTimeAsUtc );
System.out.println( "dateTimeAdjustedToParis: " + dateTimeAdjustedToParis );
System.out.println( "dateTimeAdjustedToParis thru formatter: " + formatterOutput.print( dateTimeAdjustedToParis ) );
System.out.println( "dateTimeAsParis: " + dateTimeAsParis );
When run…
input: 20140217 14:45:28
dateTimeAsUtc: 2014-02-17T14:45:28.000Z
dateTimeAdjustedToParis: 2014-02-17T15:45:28.000+01:00
dateTimeAdjustedToParis thru formatter: 17.02.2014 15:45:28
dateTimeAsParis: 2014-02-17T14:45:28.000+01:00
I use the following code to get the date and time of my country;
String TIME_SERVER = "time-a.nist.gov";
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();
Date time = new Date(returnTime);
Maybe it helps you, if it doesn't, just put a comment and i will delete my answer.

Convert IST to US timezones considering the daylight saving time in java

I have a date-time in IST. I want to convert it to US timezones based on input considering the daylight saving time,
if there is daylight saving time for the given date-time in java.
This is what i tried
function convert(Date dt,int toTimeZoneId){
Calendar cal = Calendar.getInstance();
cal.setTime(dt); // Geting time in IST
//Converted to GMT and set in cal
switch(toTimeZoneId){
case 1: tzTarget = TimeZone.getTimeZone("America/Adak");
offset = -10;
break;
case 2: tzTarget = TimeZone.getTimeZone("America/Anchorage");
offset = -9;
break;
case 3: tzTarget = TimeZone.getTimeZone("America/Los_Angeles");
offset = -8;
break;
case 4: tzTarget = TimeZone.getTimeZone("America/Denver");
offset = -7;
break;
case 5: tzTarget = TimeZone.getTimeZone("America/Chicago");
offset = -6;
break;
case 6: tzTarget = TimeZone.getTimeZone("America/New_York");
offset = -5;
break;
}
//converting from GMT to US timezones based on offset and dst
cal.setTimeZone(tzTarget);
dst = tzTarget.getDSTSavings();
dst = dst/3600000;
offset = offset + dst;
cal.add(Calendar.HOUR, offset);
Date date = cal.getTime();
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
}
To just convert a given date to different time zones, you need to create the date formatter with appropriate time zone. A date instance is just a long value relative to epoch; it doesn't have time zone information. So we aren't converting it to a different time zone, we are just representing it in different time zones. That is why we need time zone information when we want to create a string representation of the date instance.
Here's some code to illustrate the above. I've just added the time zone to your date format string to make things clear.
/*
* Converts a specified time to different time zones
*/
public void convert(Date dt) {
// This prints: Date with default formatter: 2013-03-14 22:00:12 PDT
// As my machine is in PDT time zone
System.out.println("Date with default formatter: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(dt));
// This prints: Date with IST time zone formatter: 2013-03-15 10:30:12 GMT+05:30
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
TimeZone tz = TimeZone.getTimeZone("GMT+0530");
sdf.setTimeZone(tz);
String dateIST = sdf.format(dt);
System.out.println("Date with IST time zone formatter: " + dateIST);
// This prints: Date CST time zone formatter: 2013-03-15 00:00:12 CDT
tz = TimeZone.getTimeZone("CST");
sdf.setTimeZone(tz);
System.out.println("Date CST time zone formatter: " + sdf.format(dt));
}
I think this is what you are trying to do - convert a given time to different time zones. To do that I don't think you need to add/subtract any offset, as you just want the same time represented in a different time zone and the TimeZone instance should be able to take care of that during formatting.
As for daylight saving, the TimeZone should be able to take care of that as well. If you notice in my example code, I've used CST to create TimeZone instance and CST is "GMT -06 hours". But the output it gives is in CDT, which is "GMT -05 hours", because this time zone instance uses daylight saving. So by using the appropriate time zone you should be able to handle daylight saving as well.
java.util.GregorianCalendar allows you create dates with timezones. Unfortunately, addition and subtraction suck from there. (How do you subtract Dates in Java?)
Since you're converting between two timezones, you can also make use of java.util.TimeZone and use the difference of tz1.getOffset(date) - tz2.getOffset(date). Mind the ordering when doing subtraction.
Joda-Time
Using Joda-Time makes this much easier. Or try the new java.time package in Java 8.
Here is some example code using Joda-Time 2.3. Search StackOverflow for many more examples.
India time…
DateTimeZone timeZone_India = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( date, timeZone_India );
Adjusting the same moment for display as New York time…
DateTimeZone timeZone_NewYork = DateTimeZone.forID( "America/New_York" );
DateTime dateTimeNewYork = dateTimeIndia.withZone( timeZone_NewYork ); // Same moment, different wall-clock time.
Still the same moment, but in UTC (no time zone offset).
DateTime dateTimeUtc = dateTimeIndia.withZone( DateTimeZone.UTC );
Use Proper Time Zone Names
Avoid using 3-4 letter time zone codes. They are neither standardized nor unique. Your IST for example can mean either Irish Standard Time or India Standard Time. Use proper time zone names.

Formatting XmlGregorianCalendar timezone issue

I need to format java XmlGregorianCalendar to "yyMMdd" string.
My implementation:
XMLGregorianCalendar date = getDate(); //getting the date
if (date != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
LOG.debug("Parsing date...");
LOG.debug("XML Date: " + date);
LOG.debug("XML Date timezone: " + date.getTimezone());
GregorianCalendar gc = date.toGregorianCalendar();
LOG.debug("Gregorian calendar: " + gc.toString());
LOG.debug("Gregorian calendar timezone id: " + gc.getTimeZone().getID());
Date d = gc.getTime();
LOG.debug("Date: " + d.toString());
String formatted = sdf.format(d);
LOG.debug("Formatted: " + formatted);
}
What I see in log:
Parsing date...
XML Date: 1943-04-15T00:00:00.000Z
XML Date timezone: 0
Gregorian calendar: java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT+00:00",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=1943,MONTH=3,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=15,DAY_OF_YEAR=1,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=0,DST_OFFSET=0]
Gregorian calendar timezone id: GMT+00:00
Date: Wed Apr 14 20:00:00 EDT 1943
Formatted: 430414
April, 15 was parsed as April, 14. What I'm doing wrong? When I should set timezone?
It was parsed as midnight on April 15th UTC. It was then formatted as 8pm on April 14th EDT, which is correct as EDT is four hours behind UTC.
Note that Date.toString() always uses the local time zone - a Date object has no concept of which time zone it's in.
Your formatted value is also using the default time zone, as you haven't specified a time zone. The calendar value (gc) is in UTC, but when you format it, it will apply the time zone from the formatter (as you format the Date value, which doesn't have a time zone).
It's not clear what you were trying to achieve, but hopefully that will help. As an aside, I'd strongly recommend that you use Joda Time instead if you possibly can - it makes a lot of this much clearer.

Categories

Resources