1

Hi i am currently work on creating Desktop application using Swing.I was able to convert IST to EST time using Date class in java but not able to convert EST to IST time and it gives same EST time as IST time. Please find the below code .

ChangetoEST function is giving correct EST time from IST time. ChangetoIST function is not giving correct IST time from EST time and showing given EST time as IST time.

public String changetoEST(String date) throws ParseException
{
    SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
    String dateInString = date;
    Date d=formatter.parse(dateInString);
    TimeZone tzInAmerica = TimeZone.getTimeZone("America/New_York");
    formatter.setTimeZone(tzInAmerica);
    String sDateInAmerica = formatter.format(d);
    Date dateInAmerica = formatter.parse(sDateInAmerica);
    String a=formatter.format(dateInAmerica);
    return a;
}

public String changetoIST(String date) throws ParseException
{
    SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
    String dateInString = date;
    Date d=formatter.parse(dateInString);
    TimeZone tzInIndian = TimeZone.getTimeZone("Asia/Calcutta");
    formatter.setTimeZone(tzInIndian);
    String sDateInAmerica = formatter.format(d);
    Date dateInAmerica = formatter.parse(sDateInAmerica);
    String a=formatter.format(dateInAmerica);
    return a;
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350

3 Answers3

2

The parse calls are done without you explicitly setting a time zone, which means that parsing is done using your default time zone.

Set the source time zone before parsing, parse, set time zone to target time zone, and format result.

E.g.

public static String istToEst(String dateInput) throws ParseException {
    return changeTimeZone(dateInput, TimeZone.getTimeZone("Asia/Calcutta"),
                                     TimeZone.getTimeZone("America/New_York"));
}
public static String estToIst(String dateInput) throws ParseException {
    return changeTimeZone(dateInput, TimeZone.getTimeZone("America/New_York"),
                                     TimeZone.getTimeZone("Asia/Calcutta"));
}
private static String changeTimeZone(String dateInput, TimeZone sourceTimeZone,
                                     TimeZone targetTimeZone) throws ParseException {
    SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
    formatter.setTimeZone(sourceTimeZone);
    Date date = formatter.parse(dateInput);
    formatter.setTimeZone(targetTimeZone);
    return formatter.format(date);
}

Test

String dateInput = "08/22/2016 02:21 AM";
System.out.println(dateInput);
System.out.println(istToEst("08/22/2016 02:21 AM"));
System.out.println(estToIst("08/22/2016 02:21 AM"));

Output

08/22/2016 02:21 AM
08/21/2016 04:51 PM
08/22/2016 11:51 AM
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Hi Andreas...Thanks very much.. It is working perfectly . The solution is simple and understandable.. – Vetri Selvan Aug 22 '16 at 06:47
  • Hi Andreas. I have one more question.Why we need to set time zone before we parse the date? – Vetri Selvan Aug 22 '16 at 06:51
  • @Vetri Because otherwise how will the parser know what time zone the string is supposed to be in? unless the string includes the time zone and you also add the tz pattern to the format string it has no way of knowing that you mean anything but your default local timezone. So you have to tell it what time zone the input string is in, else it assumes the input is always IST in your case. Your original converttoest only appeared to work because your default timezone happened to be ist by coincidence. – Jason C Aug 22 '16 at 07:37
  • Thanks much for your explanation @JasonC – Vetri Selvan Aug 23 '16 at 02:25
1

Set formatter to the source timezone before parsing (this is the step you are missing), then set it to the destination timezone before formatting, otherwise it parses it using the local timezone, which is IST for you.

Also you should just be able to return sDateInAmerica directly, you don't need to re-parse then re-format it a second time.

Jason C
  • 38,729
  • 14
  • 126
  • 182
1

java.time

You are using troublesome old legacy date-time classes, now supplanted by the java.time classes.

We parse the input string as a LocalDateTime as it lacks any info about offset-from-UTC or time zone (offset plus rules for anomalies such as DST).

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/yyyy hh:mm a" );
LocalDateTime ldt = LocalDateTime.parse( input , f );

Apply a time zone to get an actual moment on the timeline, a ZonedDateTime object.

ZoneId zNewYork = ZoneId.of( "America/New_York" );
ZonedDateTime zdtNewYork = ldt.atZone( zNewYork );

To see the same moment through the lens of another time zone, another wall-clock time, adjust into another ZoneId. Notice that we are not going through another LocalDateTime as the purpose of that class is to forget any information about offset or time zone. We want the opposite, to use the info about time zone to adjust wisely between zones. So while New York is behind UTC by four hours, India is ahead of UTC by five and a half hours. So we need a total of nine and a half hour adjustment, which may include a change in date.

ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtKolkata = zdtNewYork.withZoneSameInstant( zKolkata );  // Same simultaneous moments on the timeline.

Generate String

You can generate a String in any format you desire to represent the date-time value.

String output = zdtKolkata.format( f );

Generally better to let java.time automatically localize for you.

Locale l = Locale.CANADA_FRENCH;  // Or Locale.US, Locale.ITALY, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l );
String output = zdtKolkata.format( f );
Andreas
  • 154,647
  • 11
  • 152
  • 247
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154