10

i have written this code to convert the current system date and time to some other timezone. I am not getting any error but i am not getting my output as expected. Like if i execute my program at a particular time.. My output is ::

The current time in India is :: Fri Feb 24 16:09:23 IST 2012

The date and time in :: Central Standard Time is :: Sat Feb 25 03:39:23 IST 2012

And the actual Time according to CST time zone is ::

Friday, 24 February 4:39:16 a.m(GMT - 6:00)

So there's some time gap. and i don't know why this is happening. Any help will be appreciated.. The code is ::

package MyPackage;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class Temp2 {


    public static void main(String[] args) {

        try {
            Calendar currentdate = Calendar.getInstance();
            String strdate = null;
            DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
            strdate = formatter.format(currentdate.getTime());
            TimeZone obj = TimeZone.getTimeZone("CST");

            formatter.setTimeZone(obj);
            //System.out.println(strdate);
            //System.out.println(formatter.parse(strdate));
            Date theResult = formatter.parse(strdate);

            System.out.println("The current time in India is  :: " +currentdate.getTime());

            System.out.println("The date and time in :: "+ obj.getDisplayName() + "is ::" + theResult);
        } catch (ParseException e) {
           e.printStackTrace();
        }
    }
}
Shantanu Tomar
  • 1,572
  • 7
  • 38
  • 64
  • 1
    Handling time using java.util quickly becomes a headache , if you have some time , check out the joda-time API – angryInsomniac Feb 24 '12 at 10:50
  • Take a look at this http://stackoverflow.com/questions/2356672/date-parsing-formating-with-timezone-and-simpledateformat-problem-around-dst-swi – Pavan Feb 24 '12 at 10:50
  • [`SimpleDateFormat`](http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html) – sam Oct 21 '15 at 14:22
  • though its old , I am getting same kind of problem with time zone.My problem is like: In my app I have to show GST time in and has to pass the UTC (of dubai time) to server. Not able to find solution please help. Example.. – mainu Dec 06 '18 at 06:03

11 Answers11

21

It's over the web. Could have googled. Anyways, here is a version for you (shamelessly picked and modified from here):

Calendar calendar = Calendar.getInstance();
TimeZone fromTimeZone = calendar.getTimeZone();
TimeZone toTimeZone = TimeZone.getTimeZone("CST");

calendar.setTimeZone(fromTimeZone);
calendar.add(Calendar.MILLISECOND, fromTimeZone.getRawOffset() * -1);
if (fromTimeZone.inDaylightTime(calendar.getTime())) {
    calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}

calendar.add(Calendar.MILLISECOND, toTimeZone.getRawOffset());
if (toTimeZone.inDaylightTime(calendar.getTime())) {
    calendar.add(Calendar.MILLISECOND, toTimeZone.getDSTSavings());
}

System.out.println(calendar.getTime());
naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Nishant
  • 54,584
  • 13
  • 112
  • 127
  • Thanx nishant .. for the answer..i am getting the time ryt..but date is still not correct.. its giving me.. 25th instead of 24th... Please if u can get that ryt.. ?? thanx – Shantanu Tomar Feb 24 '12 at 11:16
  • I am getting same kind of problem with time zone.My problem is like: In my app I have to show GST time in and has to pass the UTC (of dubai time) to server. Not able to find solution please help. Example.. if in india current time is 10:00AM, from TimeZone(Asia/Dubai)I am getting 8:30AM. Now I have to convert 8:30 to UTC which will be 4:30. But I am getting 15:00:00 GMT+05:30 2018. please help – mainu Dec 06 '18 at 06:53
8

Your mistake is to call parse instead of format.

You call parse to parse a Date from a String, but in your case you've got a Date and need to format it using the correct Timezone.

Replace your code with

Calendar currentdate = Calendar.getInstance();
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
TimeZone obj = TimeZone.getTimeZone("CST");
formatter.setTimeZone(obj);
System.out.println("Local:: " +currentdate.getTime());
System.out.println("CST:: "+ formatter.format(currentdate.getTime()));

and I hope you'll get the output you are expecting.

Nigam Patro
  • 2,760
  • 1
  • 18
  • 33
Oleg Mikheev
  • 17,186
  • 14
  • 73
  • 95
6

SimpleDateFormat#setTimezone() is the answer. One formatter with ETC timezone you use for parsing, another with UTC for producing output string:

DateFormat dfNy = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
dfNy.setTimeZone(TimeZone.getTimeZone("EST"));
DateFormat dfUtc = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
dfUtc.setTimeZone(TimeZone.getTimeZone("UTC"));

try {
    return dfUtc.format(dfNy.parse(input));
} catch (ParseException e) {
    return null;              // invalid input
}
Alex Salauyou
  • 14,185
  • 5
  • 45
  • 67
4

Handling dates in Java in my daily work is a non-trivial task. I suggest you to use Joda-Time that simplify our coding days and you don't have to "re-invent the wheel".

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Dario
  • 5,203
  • 1
  • 23
  • 26
3

You can use two SimpleDateFormat, one for parse the date string with EST timezone, one for print the date with UTC timezone

String format = "yyyy-MM-dd HH:mm:ss";
    SimpleDateFormat estFormatter = new SimpleDateFormat(format);
    estFormatter.setTimeZone(TimeZone.getTimeZone("EST"));
    Date date = estFormatter.parse("2015-11-01 01:00:00");

    SimpleDateFormat utcFormatter = new SimpleDateFormat(format);
    utcFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));

    System.out.println(utcFormatter.format(date));
Bon
  • 3,073
  • 5
  • 21
  • 40
2

You can just use "CST6CDT" because in some countries they follow CDT in summer and CST in winter

 public static String getDateInCST() {
             Calendar calendar = Calendar.getInstance();
             DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
             formatter.setTimeZone(TimeZone.getTimeZone( "CST6CDT"));
             String strdate = formatter.format(calendar.getTime());
             TimeZone.getAvailableIDs();
             return strdate;
     }
Pratik Sinha
  • 234
  • 1
  • 14
2

Problem is when you print date obj it call toString method and it will print in your machines default time zone. Try this code and see difference.

Calendar currentdate = Calendar.getInstance();
String strdate = null;
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ssz");
strdate = formatter.format(currentdate.getTime());
System.out.println("strdate=>" + strdate);
TimeZone obj = TimeZone.getTimeZone("CST");

formatter.setTimeZone(obj);
strdate = formatter.format(currentdate.getTime());
Date theResult = formatter.parse(strdate);

System.out.println("The current time in India is  :: " +currentdate.getTime());

System.out.println("The date and time in :: " + obj.getDisplayName() + "is ::" + theResult);
System.out.println("The date and time in :: " + obj.getDisplayName() + "is ::" + strdate);
naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Abhishek bhutra
  • 1,400
  • 1
  • 11
  • 29
  • do you get the mistake you were doing..? – Abhishek bhutra Feb 24 '12 at 11:54
  • Well not exactly... But what u r saying, it seems i am printing the date without converting to CST timezone.. It will be grateful, if u will explain where did i went wrong.. ?? – Shantanu Tomar Feb 24 '12 at 12:03
  • ok i ll but just do one thing in your code you are setting time zone after formatting the date in string...just set time zone before formatting date...this will change the output and i guess will give a clue that why difference of time is being inserted. – Abhishek bhutra Feb 24 '12 at 12:14
1

First message, don’t handle your date and time as strings in your code. Just as you don’t handle numbers and Boolean values as strings (I hope). Use proper date-time objects.

java.time

Sometimes we get date and time as string input. It may be from a text file, from the user or from data exchange with another system, for example. In those cases parse into a proper date-time object first thing. Second message, use java.time, the modern Java date and time API, for your date and time work.

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");

    String input = "2015-11-01 01:00:00";

    ZonedDateTime nyTime = LocalDateTime.parse(input, formatter)
            .atZone(ZoneId.of("America/New_York"));
    System.out.println("Time in New York: " + nyTime);

Output from this snippet is:

Time in New York: 2015-11-01T01:00-04:00[America/New_York]

To convert to GMT:

    OffsetDateTime gmtTime = nyTime.toOffsetDateTime()
            .withOffsetSameInstant(ZoneOffset.UTC);
    System.out.println("GMT Time: " + gmtTime);
GMT Time: 2015-11-01T05:00Z

If you need to give string output, format using a date-time formatter. Here’s an example of formatting for an American audience:

    DateTimeFormatter userFormatter
            = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
                    .withLocale(Locale.US);
    String formattedDateTime = gmtTime.format(userFormatter);
    System.out.println("GMT Time formatted for user: " + formattedDateTime);
GMT Time formatted for user: Nov 1, 2015, 5:00:00 AM

You additionally asked:

Between the two results below, which one should you take?

I understand that you ask because both are valid answers. On November 1, 2015 summer time (DST) ended at 2 AM. That is, after 01:59:59 came 01:00:00 a second time. So when we have got 2015-11-01 01:00:00 as input, it is ambiguous. It could be in Eastern Daylight Time, equal to 05:00 GMT, or it could be in Eastern Standard Time, one hour later, hence equal to 06:00 GMT. There is no way that I can tell you which of them is correct in your case. You may control which result you get using withEarlierOffsetAtOverlap() or withLaterOffsetAtOverlap(). Above we got the DST interpretation. So to get the standard time interpretation:

    nyTime = nyTime.withLaterOffsetAtOverlap();
    System.out.println("Alternate time in New York: " + nyTime);

Alternate time in New York: 2015-11-01T01:00-05:00[America/New_York]

We notice that the hour of day is still 01:00, but the offset is now -05:00 instead of -04:00. This also gives us a different GMT time:

GMT Time: 2015-11-01T06:00Z
GMT Time formatted for user: Nov 1, 2015, 6:00:00 AM

Avoid SimpleDateFormat and friends

While the other answers are generally correct, the classes DateFormat, SimpleDateFormat, Date and Calendar used there are poorly designed and long outdated. The first two are particularly troublesome. I recommend you avoid all of them. I frankly find the modern API so much nicer to work with.

Link

Oracle tutorial: Date Time explaining how to use java.time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

2020 Answer Here

If you want the new java.time.* feature but still want to mess with java.util.Date:

 public static Date convertBetweenTwoTimeZone(Date date, String fromTimeZone, String toTimeZone) {
        ZoneId fromTimeZoneId = ZoneId.of(fromTimeZone);
        ZoneId toTimeZoneId = ZoneId.of(toTimeZone);

        ZonedDateTime fromZonedDateTime =
                ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).withZoneSameLocal(fromTimeZoneId);

        ZonedDateTime toZonedDateTime = fromZonedDateTime
                .withZoneSameInstant(toTimeZoneId)
                .withZoneSameLocal(ZoneId.systemDefault())
                ;

        return Date.from(toZonedDateTime.toInstant());
    }

for java.sql.Timestamp

    public static Timestamp convertBetweenTwoTimeZone(Timestamp timestamp, String fromTimeZone, String toTimeZone) {

        ZoneId fromTimeZoneId = ZoneId.of(fromTimeZone);
        ZoneId toTimeZoneId = ZoneId.of(toTimeZone);

        LocalDateTime localDateTimeBeforeDST = timestamp.toLocalDateTime();

        ZonedDateTime fromZonedDateTime = ZonedDateTime.of(localDateTimeBeforeDST, fromTimeZoneId);

        ZonedDateTime toZonedDateTime = fromZonedDateTime.withZoneSameInstant(toTimeZoneId);

        return Timestamp.valueOf(toZonedDateTime.toLocalDateTime());
    }
thiennt
  • 51
  • 1
  • 2
  • 8
0

Please refer to below mentioned code.

     DateFormat utcConverter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     utcConverter.setTimeZone(TimeZone.getTimeZone("GMT"));
     String sampleDateTime = "2015-11-01 01:00:00";
     DateFormat nyConverter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     nyConverter.setTimeZone(TimeZone.getTimeZone("EST"));
     Calendar nyCal = Calendar.getInstance();

     nyCal.setTime(nyConverter.parse(sampleDateTime));

     System.out.println("NY TIME :" +nyConverter.format(nyCal.getTime()));

    System.out.println("GMT TIME  :" +utcConverter.format(nyCal.getTime()));
dossani
  • 1,892
  • 3
  • 14
  • 23
0

For google calendar API

private String getFormatedDate(Date date)
    {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+05:30");
        df.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
        return df.format(date);
    }
Toji
  • 1
  • 1
    Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. We have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. – Ole V.V. Jul 23 '21 at 18:04