2

I have a scenario, that what ever my system Timezone is, i have to print in IST in Date Object and not in String. Here is my below code.

public static void main(String[] args) throws ParseException {
    Date now = new Date();
    DateFormat sdf = new SimpleDateFormat("yyyy:MM:dd-HH:mm:ss");
     sdf.setTimeZone(TimeZone.getTimeZone("IST"));
     String txnDateTime = sdf.format(now); 
      sdf.setTimeZone(TimeZone.getTimeZone("IST"));
     System.out.println("Date ::: "+txnDateTime);

     Date n = null;
     n = sdf.parse(txnDateTime);
     System.out.println("Date format ::: "+n);

}

My Output is as follows:

In String : I am getting as Expected : 2016:08:23-12:46:59 IST Timing
In Date : I am still getting BST Time : Tue Aug 23 08:16:59 BST 2016

I am expecting to come the Date as Tue Aug 23 12:46:59 IST 2016.

Any help would be appreciated.

Thanks in advance.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • The `java.util.Date` has the annoying and confusing behavior of applying the default time zone in the process of generating a String that represents its date-time value. This is one of *many* reasons to avoid this class and the other troublesome old legacy date-time classes. They have been supplanted by the java.time classes. – Basil Bourque Aug 23 '16 at 23:56

3 Answers3

5

Date.toString() uses your JVM's default timezone, because Date doesn't actually have an explicit timezone - it's really just a wrapper around a number of milliseconds.

You have to print using a DateFormat with an explicit timezone to print a Date in an specific timezone.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • I am going to deploy this code in both UK and US Servers, So I cant actually hard code any of the Input Timezone. When user from US logs in I have to print the Date in IST. Do you want me to use Calendar instead of Date? – sunil gogula Aug 23 '16 at 07:42
  • You can use what you like, provided it works. `SimpleDateFormat` suffices. And I don't exactly get why you can't hardcode something; or at least, make it a command-line parameter. – Andy Turner Aug 23 '16 at 07:43
  • When i use with SimpleDateFormat, that gives me the date with the Current Timezone rather than the Converted Timezone in IST. – sunil gogula Aug 23 '16 at 07:45
  • If only there were [a method on `SimpleDateFormat` to set the timezone...](http://docs.oracle.com/javase/8/docs/api/java/text/DateFormat.html#setTimeZone-java.util.TimeZone-) – Andy Turner Aug 23 '16 at 07:46
  • Even if i make as Command Line, I am able to get the time in String variable, but Still the date remains question as it still takes the System Time. – sunil gogula Aug 23 '16 at 07:46
  • I am already setting the IST Timezone from the below line sdf.setTimeZone(TimeZone.getTimeZone("IST")); – sunil gogula Aug 23 '16 at 07:48
  • You are setting the timezone when you *parse* the string, but you're printing the `Date` instance, which is independent of the `SimpleDateFormat` which parsed it. – Andy Turner Aug 23 '16 at 07:49
  • Yup there i Struck. So what would be the logic to Print the Date in IST in Date Format – sunil gogula Aug 23 '16 at 07:53
  • 1
    @sunilgogula You would use a SimpleDateFormat with TZ set to the desired TimeZone and `format` instead of `parse`. I suggest not to "hardcode" TZ, but make an Application-Wide Setting for it. You can use cmd-line param or a properties file, or the like. You could also try to fetch a hint for the desired TZ from the OS settings. – Fildor Aug 23 '16 at 08:19
  • Thanks @Fildor, But when i use format instead of parse, i am getting the converted Time in form of String Object, which i am not interested. I am interested in getting the time in Date Object only. – sunil gogula Aug 23 '16 at 08:21
  • @sunilgogula please read my answer: "Date.toString() uses your JVM's default timezone". You just can't do this with a `Date`: you need to format it with a `DateFormat`. – Andy Turner Aug 23 '16 at 08:22
  • 1
    @sunilgogula That's impossible. A Date (object) is just a number that is an offset to the java epoch. So if you parse a date in IST it will be converted to number x. If parse the same time instant in BST, it will be converted to the same x. While formatting it will be offset to the correct time zone again. So if you want to have the IST value in the Date object, you'll have to parse it as UTC. But that's kind of wrong. – Fildor Aug 23 '16 at 08:25
  • @Andy Turner, Could you please print out the line format using DateFormat. Actually i am running out of ideas. – sunil gogula Aug 23 '16 at 08:26
  • 1
    @sunilgogula which timezone do you think "IST" is? I bet your JVM thinks you mean *Irish* Standard Time (or maybe *Israel* Standard Time), rather than *India* Standard Time. Use [`"Asia/Kolkata"`](https://en.wikipedia.org/wiki/Time_in_India). – Andy Turner Aug 23 '16 at 08:31
1

tl;dr

ZonedDateTime.now( ZoneId.of( "India/Kolkata" ) )

Servers in UTC

Your servers should generally be set to UTC time. But you should never depend on that. Always specify the desired/expected time zone explicitly.

String != Date-Time

As others explain, do not conflate a date-time value with its String representation. A date-time object can parse Strings, and can generate Strings, but is distinct and separate from those Strings. A date-time object is not a String.

Avoid old date-time classes

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

Use java.time

From the comments it sounds like you are merely asking for the current moment to be captured in the India time zone. India time nowadays is five and a half hours ahead of UTC.

Specify a proper time zone name. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "India/Kolkata" );
ZonedDateTime zdt = ZonedDateTime.now( z );

If you want to see that moment adjusted into UTC, just extract a Instant which is a moment on the timeline always in UTC. Use Instant objects for your logging, data storage, and data exchange (generally speaking).

Instant instant = zdt.toInstant();

To generate a String representing the date-time value in standard ISO 8601 format, simply call toString.

You can generate strings in any format you desire. But usually best to let java.time localize automatically. Just specify the appropriate Locale to indicate (a) the human language to use in translation, and (b) the cultural norms to decide issues such as capitalization, abbreviation, and punctuation.

Locale l = Locale.CANADA_FRENCH ;  // Or Locale.US, Locale.ITALY, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l );
String output = zdt.format( f );

Note that Locale has nothing to do with time zone. Here we are taking the current wall-clock time of India and displaying in a format expected by a Québécois person.

Convert

While you should avoid the old legacy date-time classes because of their confusion, poor design, and flaws, sometimes you may need to interoperate with old code not yet updated to java.time types. For such cases you can convert to/from java.time by calling new methods added to the old classes.

java.util.Date utilDate = java.util.Date.from( zdt.toInstant() );

About java.time

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

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

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

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).

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.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Thanks @Basil Bourque. The above code that was provided again lans up in getting the Date in String Object. If there is no other way we can get the Date in Date Object, then i will change the Client implementation by changing the return type from Date to String. – sunil gogula Aug 25 '16 at 07:54
  • Hi Everyone, I think i found the Answer. Heres is the Below Code Date date1 = new Date(); System.out.println(date1); TimeZone.setDefault(TimeZone.getTimeZone("IST")); Date date2 = new Date(); System.out.println(date2); date1 prints the Server Time date 2 prints the time of your particular Time Zone Output Thu Aug 25 15:13:10 GMT 2016 Thu Aug 25 20:43:10 IST 2016 – sunil gogula Aug 25 '16 at 15:23
  • @sunilgogula You should almost *never* set the JVM’s default time zone. You immediately affect all code in all threads of all apps within that JVM. Also, those old date-time classes really are a mess; I urge you to stick with java.time types. They were invented and added to Java for a reason! – Basil Bourque Aug 25 '16 at 17:04
  • @sunilgogula By `IST`, did you mean `Irish Standard Time`? Or `Israel Standard Time`? I suggest you re-read my Answer. – Basil Bourque Aug 25 '16 at 17:14
1

I am expecting to come the Date as Tue Aug 23 12:46:59 IST 2016."

The sequence letters T-u-e... is a String. It is not a Date object. The Date class itself has no concept of a timezone. The timezone is stored in a Locale object instead. This timezone setting has no meaning until you convert a Date into a String with toString() or a SimpleDateFormat.

when i use format instead of parse, i am getting the converted Time in form of String Object, which i am not interested. I am interested in getting the time in Date Object only.

This is not possible. The time zone only has meaning when you parse the Date object into a String which you can display.

To solve your problem, you will need to use a SimpleDateFormat and add logic to determine which timezone to use when generating the String output.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • @BasilBourque Good catch. That's what I get for doing this off the cuff rather than verifying class names that I haven't used for a while. – Code-Apprentice Aug 24 '16 at 00:00