0

I need to format a string date with given time zone and return the date object back. I am currently in IST time zone.

So IST is 5 hours and 30 minutes ahead of UTC.

public void getDate(){
  String dateStr = "11/25/2016T13:30:00.000";
  String dateFormat = "MM/dd/yyyy'T'HH:mm:ss.SSS";
  Date date = formatedStringToDate(dateStr, dateFormat);
  System.out.println(date);
}

public static Date formatedStringToDate(final String date, final String dateFormat) throws ParseException {
        final SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date parsedDate = null;
        if (date != null) {
            try {
                parsedDate = sdf.parse(date);
            } catch (ParseException e) {
                throw e;
            }
        }
        return parsedDate;
}

I get the below out put.

Fri Nov 25 19:00:00 **IST** 2016

The time seems to be change from 5.30 hours but then if its a IST to UCT time converstion, it should be 5.30 hours before 13:30:00 which is 08:00:00?

Also how could I change the highlighted IST part of out put string to show the currect time zone in this case UTC?

Harshana
  • 7,297
  • 25
  • 99
  • 173
  • 1
    No. India Standard Time (IST) is 5:30 hours ahead of Coordinated Universal Time (UTC). So, since your date represents 13:30 UTC, and IST is 5:30 ahead, 13:30 UTC = 19:00 IST. A Date doesn't have any time zone. It's just a universal moment in time, stored as a number of milliseconds since another precise moment. To format it in UTC, then use a SimpleDateFormat, whose timezone is set to UTC, just like the one you used to parse the string (but you'll get the original string, then, of course). – JB Nizet Nov 25 '16 at 08:33
  • @JBNizet Thank you. So this is my understanding now. dateStr is just a string value with out any time zone. So I want to get the Date object by convert the time to given time zone. So in this example I set sdf.setTimeZone(TimeZone.getTimeZone("UTC")); Then I should not be have any time conversion know because my dateStr is in UTC and I set UTC also in my SimpleDateFormat – Harshana Nov 25 '16 at 09:44

2 Answers2

2

When you call toString on a Date (by printing it) you get the default format (because a Date is an object that stores a number of milliseconds, or nanoseconds in Java 9+, since an epoch). To see the result in UTC you need something like,

final DateFormat sdf = DateFormat.getDateTimeInstance(DateFormat.FULL,
        DateFormat.FULL);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = formatedStringToDate(dateStr, dateFormat);
System.out.println(sdf.format(date)); // <-- format the Date
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • For my curiosity, are they really changing the precision of java.util.Date in Java 9, although it's already basically deprecated in favor of the java.time API? – JB Nizet Nov 25 '16 at 08:35
  • 1
    @JBNizet I had heard they were, but now I cannot find a primary source. I believe it's to do with the `Date` implementation, the public api doesn't change (regardless of how Java is internally defining the epoch). – Elliott Frisch Nov 25 '16 at 08:43
  • @ElliottFrisch Thanks for point it out. Actually I print it just for my view purpose and I understand what is more important is the millisecond value which get assign in the Date constructor. So in that case, suppose I have a String date with time as in my example dateStr = "11/25/2016T13:30:00.000" in UTC (No time zone information is provided in the string so by default its UTC right) and I want to convert it to time for given time zone. eg: PST,UTC,IST etc. What could I do additionally in my example code post in the question? – Harshana Nov 25 '16 at 09:53
  • @ElliottFrisch Also with my current code posted, why I am getting a time converstion because my dateStr also in UTC and SimpleDateFormat I set timezone as UTC? – Harshana Nov 25 '16 at 09:53
0

tl;dr

LocalDateTime.parse( "2017-11-25T13:30:00.000" )
    .atZone( ZoneId.of( "Asia/Kolkata" ) )

2017-11-25T13:30+05:30[Asia/Kolkata]

java.time

The modern approach uses the java.time classes that replaced the troublesome old legacy date-time classes.

Parse your input string as a LocalDateTime given the lack of any indicator of zone or offset-from-UTC.

Using standard ISO 8601 format for such strings is preferred. The java.time classes use the standard formats by default when parsing/generating strings.

LocalDateTime ldt = LocalDateTime.parse( "2017-11-25T13:30:00.000" ) ;

ldt.toString(): 2017-11-25T13:30

If you are certain this date-time was intended to represent a moment by the wall-clock time of India, then assign a time zone to produce a ZonedDateTime object.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. 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( "Asia/Kolkata" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

zdt.toString(): 2017-11-25T13:30+05:30[Asia/Kolkata]

You can adjust into another zone for comparison.

ZonedDateTime zdtMontreal = zdt.withZoneSameInstant( ZoneId.of( "America/Montreal") );

zdtMontreal.toString(): 2017-11-25T03:00-05:00[America/Montreal]

To parse/generate strings in other formats such as the one in your Question, use the DateTimeFormatter or DateTimeFormatterBuilder classes. Search Stack Overflow for more info, as these have been covered extensively.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu'T'HH:mm:ss.SSS" , Locale.US ) ;

Use that formatter for parsing.

LocalDateTime ldt = LocalDateTime.parse( "11/25/2016T13:30:00.000" , f ) ;

And for generating.

String output = ldt.format( f ) ;  // Generate string.

Consider using ISO 8601 formats instead.


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?

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154