Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert string to appropriate date with timezone java

I am Having Date with it's timezone, I want to convert it to another Timezone, E.g. I have Date '3/15/2013 3:01:53 PM' which is in TimeZone 'GMT-06:00'. I want to convert this in 'GMT-05:00' timezone. I have search lot, and I am confuse about How actually Date is working. How to Apply timezone to date. I have try with SimpleDateFormat, Calender and also with offset.

DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss aaa XXX");
df.setTimeZone(TimeZone.getTimeZone("GMT")); 
Date dt = null;
try {
    dt = df.parse("3/15/2013 3:01:53 PM -06:00");
} catch (ParseException e) {
    e.printStackTrace();
} 
String newDateString = df.format(dt);
System.out.println(newDateString);

It returns output 03/15/2013 09:01:53 AM Z. I guess it should be 03/15/2013 09:01:53 PM Z, because time in 'GMT-06:00' timezone, so it should be HH+6 to get time in GMT. I want Date in "yyyy-MM-dd HH:mm:ss" format where HH is in 24 hour.Please Help me with example. Thanks in advance.

EDIT :

I am converting the string into date using SimpleDateFormat

DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss aaa");
    Date dt = null;
    try {
        dt = df.parse("3/15/2013 3:01:53 PM");
    } catch (ParseException e) {
        e.printStackTrace();
    }

Now, as you say, I specify to Calendar that my date is in 'GMT-06:00' timezone and set my date,

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-6"));
cal.setTime(dt);

Now, I am telling calendar that I want date in 'GMT'

cal.setTimeZone (TimeZone.getTimeZone("GMT"));

System.out.println(cal.getTime());

OutPut:

Fri Mar 15 03:01:53 CDT 2013

Please know me if i am going wrong.

like image 230
minu Avatar asked May 15 '14 07:05

minu


2 Answers

You need TWO format objects, one for parsing and another one for printing because you use two different timezones, see here:

// h instead of H  because of AM/PM-format
DateFormat parseFormat = new SimpleDateFormat("M/dd/yyyy hh:mm:ss aaa XXX"); 
Date dt = null;
try {
  dt = parseFormat.parse("3/15/2013 3:01:53 PM -06:00");
}catch (ParseException e) {
  e.printStackTrace();
} 

DateFormat printFormat = new SimpleDateFormat("M/dd/yyyy hh:mm:ss aaa XXX"); 
printFormat.setTimeZone(TimeZone.getTimeZone("GMT-05")); 
String newDateString = printFormat.format(dt);
System.out.println(newDateString);

Output: 3/15/2013 04:01:53 PM -05:00

If you want HH:mm:ss (24-hour-format) then you just replace

hh:mm:ss aaa 

by

HH:mm:ss

in printFormat-pattern.


Comment on other aspects of question:

A java.util.Date has no internal timezone and always refers to UTC by spec. You cannot change it inside this object. A timezone conversion is possible for the formatted string, however as demonstrated in my code example (you wanted to convert to zone GMT-05).

The question then switches to the new requirement to print the Date-object in ISO-format using UTC timezone (symbol Z). This can be done in formatting by replacing the pattern with "yyyy-MM-dd'T'HH:mm:ssXXX" and explicitly setting the timezone of printFormat to GMT+00. You should clarify what you really want as formatted output.

About java.util.GregorianCalendar: Setting the timezone here is changing the calendar-object in a programmatical way, so it affects method calls like calendar.get(Calendar.HOUR_OF_DAY). This has nothing to do with formatting however!

like image 130
Meno Hochschild Avatar answered Oct 05 '22 02:10

Meno Hochschild


tl;dr

OffsetDateTime.parse( 
    "3/15/2013 3:01:53 PM -06:00" , 
    DateTimeFormatter.ofPattern( "M/d/yyyy H:mm:ss a XXX" )
).withOffsetSameInstant( 
    ZoneOffset.of( -5 , 0 ) 
)

2013-03-15T15:01:53-06:00

java.time

The Answer by Hochschild is correct but uses outdated classes. The troublesome old date-time classes bundled with the earliest versions of Java have been supplanted by the modern java.time classes.

Parse your input string as a OffsetDateTime as it contains an offset-from-UTC but not a time zone.

String input = "3/15/2013 3:01:53 PM -06:00";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/yyyy h:mm:ss a XXX" );
OffsetDateTime odt = OffsetDateTime.parse( input , f );

odt.toString(): 2013-03-15T15:01:53-06:00

Tip: Save yourself some hassle and use the ISO 8601 formats when exchanging date-time data as text. The java.time classes use these standard formats by default when parsing/generating strings.

Apparently you want to see the same moment as viewed by the people elsewhere using a different offset-from-UTC.

ZoneOffset offset = ZoneOffset.of( -5 , 0 ) ;
OffsetDateTime odt2 = odt.withOffsetSameInstant( offset ) ;

We see the offset changes from 6 to 5, and the hour-of-day changes accordingly from 15 to 16. Same simultaneous moment, different wall-clock time.

odt2.toString(): 2013-03-15T16:01:53-05:00

Generating strings

I want Date in "yyyy-MM-dd HH:mm:ss" format where HH is in 24 hour.

I suggest you always include some indication of the offset or zoneunless your are absolutely certain the user understands from the greater context.

Your format is nearly in standard ISO 8601 format. You could define your own formatting pattern, but I would just do string manipulation to replace the T in the middle with a SPACE.

String output = odt2.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ).replace( "T" , " " ) ;

2013-03-15 16:01:53


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

like image 35
Basil Bourque Avatar answered Oct 05 '22 01:10

Basil Bourque