I am getting following time from service
'Nov 11 2019 7:30 PM'
I know this is US Central Time, I need to get hours between current time and this event time, but i am unable to understand how to convert this date to UTC.
I am using following approach, but this does not seem to be working fine.
public Date ticketJSONDateFormatter(String dateTime){
SimpleDateFormat simpleDateFormatter
= new SimpleDateFormat("MMM d yyyy HH:mm a");
Date parsedDate = null;
try {
simpleDateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
parsedDate = simpleDateFormatter.parse(dateTime);
} catch (ParseException e) {
e.printStackTrace();
}
return parsedDate;
}
This method returns following date
Fri Oct 11 12:30:00 GMT+05:00 2019
Although the expected output may be something like this. My device is at (+5:00 UTC)
Fri Oct 12 12:30:00 GMT+05:00 2019
You can use `LocalDateTime' to parse the string to date,
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy hh:mm a");
String date = "Nov 11 2019 07:30 PM";
LocalDateTime ldt = LocalDateTime.parse(date, formatter);
Then convert it to your preferred zone,
Instant cdt = ldt.atZone(ZoneId.of("America/Chicago")).toInstant();
return cdt.atOffset(ZoneOffset.UTC)
This will return an Instant.
And as Ole V.V suggested in the comment, I wouldn't recommend using old Date and Calendar API. I would suggest reading this answer to understand the issues associated with the old Date API.
You can get this in following steps:
Use ZonedDateTime.parse to parse the time you are receiving.
Convert the America Central time to your local time.
Get your current time.
Find the difference between your current time and the event time converted to your local.
Example:
// Parsing the time you are receiving in Central Time Zone. Using Chicago as a representative Zone.
String dateWithZone = "Nov 11 2019 7:30 PM".concat("America/Chicago") ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd uuuu h:m aVV");
ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateWithZone, formatter);
System.out.println(zonedDateTime); // This is the time you received in Central time zone.
// Now convert the event time in your local time zone
ZonedDateTime eventTimeInLocal = zonedDateTime.withZoneSameInstant(ZoneId.systemDefault());
// Then find the duration between your current time and event time
System.out.println(Duration.between(ZonedDateTime.now(), eventTimeInLocal).toHours());
The duration class provides many other utilities methods to get more precise duration.
Related
I am trying to convert a UTC date String of the format 2020-06-09T06:30:00Z to a Timezone like Asia/Calcutta.
The time offset between UTC and Asia/Calcutta is +5:30, so the expected result on converting 2020-06-09T06:30:00Z to Asia/Calcutta is 2020-06-09T12:00:00Z but I am getting 2020-06-09T01:00:00Z
String utcDate = "2020-06-09T06:30:00Z";
String timezone = "Asia/Calcutta";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
LocalDateTime date = LocalDateTime.parse(utcDate, formatter); //2020-06-09T06:30
ZonedDateTime zonedDate = ZonedDateTime.of(date, ZoneId.of(timezone)); //2020-06-09T06:30+05:30[Asia/Calcutta]
Date dateConverted = Date.from( zonedDate.toInstant()); //Tue Jun 09 01:00:00 UTC 2020
I think zonedDate.toInstant() is converting subtracting 5:30 instead of adding 5:30 to 2020-06-09T06:30. My machine is in UTC timezone. may be its converting to local time don't know what is the issue. Also tried below method, still same issue.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone(timezone));
sdf.parse(dateString);
java.time
I agree with you, you should strongly prefer to use java.time, the modern Java date and time API. It’s not complicated when you know how.
String utcDate = "2020-06-09T06:30:00Z";
String timezone = "Asia/Calcutta";
ZoneId zone = ZoneId.of(timezone);
ZonedDateTime zdt = Instant.parse(utcDate).atZone(zone);
System.out.println("zdt: " + zdt);
Output is:
zdt: 2020-06-09T12:00+05:30[Asia/Calcutta]
You notice that the time of day in the ZonedDateTime is 12:00 as you had expected. The trailing Z that you also said you expected is wrong, though. Z means an offset of 0 from UTC, so since the offset is +05:30, we are very happy not to have the Z there.
If what you needed was an old-fashioned Date object, presumably for a legacy API that you don’t want to upgrade just now, there’s no reason to convert to your time zone first. This works:
Date oldfashionedDate = Date.from(Instant.parse(utcDate));
System.out.println("oldfashionedDate: " + oldfashionedDate);
Output in my time zone is:
oldfashionedDate: Tue Jun 09 08:30:00 CEST 2020
You may be in doubt whether the Date is right. It is. Since I am in Europe/Copenhagen time zone, currently at offset +02:00, the Date prints in this time zone, so the time of day is 8:30 (the Date doesn’t hold a time zone or offset). If instead I run in Asia/Calcutta time zone:
oldfashionedDate: Tue Jun 09 12:00:00 IST 2020
You notice IST for India Standard Time instead of CEST for Central European Summer Time. And the time is 12:00 as expected.
Points for you to take with you
Never hardcode Z as a literal in a format pattern string. As I said, it’s an offset, so it needs to be parsed as an offset.
For the same reason don’t parse into a LocalDateTime. A LocalDateTime. hasn’t got any offset, so you are losing information.
In this case use no formatter at all. Your format is ISO 8601, and Instant parses it as its default, that is, without any explicit formatter (OffsetDateTime and ZonedDateTime do too).
Make the conversion from UTC to Asia/Calcutta. It seems to me that you were doing the opposite conversion.
Link
Wikipedia article: ISO 8601
Got it work using SimpleDateFormat as shown below. But anyone coming across this issue should probably use ZonedDateTime.
String utcDate = "2020-06-09T06:30:00Z";
String timezone = "Asia/Calcutta";
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf1.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf1.parse(utcDate); // Tue Jun 09 06:30:00 UTC 2020
SimpleDateFormat sdf2 = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
sdf2.setTimeZone(TimeZone.getTimeZone(timezone));
String sDateInZone = sdf2.format(date); // 09-6-2020 12:00:00 PM
SimpleDateFormat formatter = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
Date dateInZone = formatter.parse(sDateInZone); // Tue Jun 09 12:00:00 UTC 2020
EDIT: Got it to work using ZonedDateTime also as shown below:
String utcDate = "2020-06-09T06:30:00Z";
String timezone = "Asia/Calcutta";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
LocalDateTime dateUtc = LocalDateTime.parse(utcDate, formatter);
ZonedDateTime utcZonedDateTime = dateUtc.atZone(ZoneId.systemDefault());
ZoneId zoneId = ZoneId.of(timezone);
ZonedDateTime zonedDateTime = utcZonedDateTime.withZoneSameInstant(zoneId);
String zoneDateString = formatter.format(zonedDateTime);
Date date = Date.from(LocalDateTime.parse(zoneDateString, formatter).atZone(ZoneId.systemDefault()).toInstant());
I want to convert a date to GMT.
I get a date in BST, I want to convert it to GMT without time zone conversion.
Example:
**If the BST date is: Wed June 26 13:30:13 BST 2019
I want to convert it to Wed 26 Jun 2019 13:30:13 GMT**
I want to ignore the timezone info and return the same date as GMT.
For this I am trying
private SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private SimpleDateFormat dateFormatGmtText = new SimpleDateFormat("EEE dd MMM yyyy HH:mm:ss 'GMT'");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String textDate = dateFormatLocal.format(date);
//Date is Wed June 26 13:30:13 BST 2019
private Date toGMTDate(final Date date) {
String textDate = dateFormatLocal.format(date);
try {
String[] dateParts = textDate.split("\\+");
textDate = dateParts[0] + "+0000";
return dateFormatGmt.parse(textDate);
} catch (ParseException e) {
return null;
}
}
private String toGMT(final Date date) {
return dateFormatGmtText.format(toGMTDate(date));
}
When I call toGMT it returns Wed 26 Jun 2019 14:30:13 GMT
I am not sure why it is so?
What is wrong here?
java.time
You said you can’t use the modern date and time API, but for other readers I should like to present that option first. SimpleDateFormat and Date are poorly designed and long outdated, the former in particular notoriously troublesome, so I recommend avoiding them.
I am assuming that BST is for British Summer Time (other interpretations exist). And I am assuming that you cannot avoid getting an old-fashioned Date object.
private static DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("EEE dd MMM yyyy HH:mm:ss z", Locale.UK);
private static ZoneId britain = ZoneId.of("Europe/London");
private static ZoneId gmt = ZoneId.of("Etc/GMT");
private static String toGMT(final Date date) {
ZonedDateTime britishTime = date.toInstant().atZone(britain);
ZonedDateTime gmtTime = britishTime.withZoneSameLocal(gmt);
return gmtTime.format(formatter);
}
Try it out with your Date of Wed Jun 26 13:30:13 BST 2019:
String textDate = dateFormatLocal.format(date);
System.out.println(textDate);
System.out.println(toGMT(date));
Output is:
2019-06-26T13:30:13+0100
Wed 26 Jun 2019 13:30:13 GMT
Whenever you get an old-fashioned Date, the first thing to do is to convert it to Instant. Then do any further conversions from there. The key to changing time zone and keeping the date and time of day (hour-minute-second of day) is the withZoneSameLocal method of the ZonedDateTime class.
I recommend specifying locale for the formatter.
I am not sure why it is so? What is wrong here?
A Date hasn’t got, as in cannot have a time zone. It’s a point in time, nothing more. YourtoGMTDate method returns a point in time that is an hour later: The time you gave it was 13:30:13+0100, and it returned 13:30:13+0000, which is the same point in time as 14:30:13+0100. Next you formatted this point in time using a formatter that used your default time zone, Europe/London, and therefore produced 14:30:13, but at the same time printed GMT in the string — the result you reported.
…the new time library, but for some reasons I can't use them.
If you really have got an evil boss that either forces you to use Java 1.4 or 1.5 and/or forbids the use external dependencies, the pretty simple hack is:
private String toGMT(final Date date) {
return dateFormatGmtText.format(date);
}
The cheating is: Your dateFormatGmtText uses your default time zone, Europe/London, but lies and prints GMT in the formatted string. This gives the same output as above — the output you asked for. Compared to your code I am just leaving out the date conversion.
Link: Oracle tutorial: Date Time explaining how to use java.time.
I have a function where I need to grab the current date, set to another time zone, and return that converted/formatted date as a Date object. I have code that works, however, the Date object does not set to the newly converted date, it returns the current date.
Here is the code:
public static Date getCurrentLocalDateTime() {
Calendar currentdate = Calendar.getInstance();
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TimeZone obj = TimeZone.getTimeZone("America/Denver");
formatter.setTimeZone(obj);
Logger.info("Local:: " + currentdate.getTime());
String formattedDate = formatter.format(currentdate.getTime());
Logger.info("America/Denver:: "+ formattedDate);
Date finalDate = null;
try {
finalDate = formatter.parse(formattedDate);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Logger.info("finalDate:: " + finalDate);
return finalDate;
}
From the examples I have reviewed and tried, this should work correctly. One of the issues is that I need to return the Date object so it works with the current code.
The output looks like:
2017-07-03 17:08:24,499 [INFO] from application in application-akka.actor.default-dispatcher-3 -
Local:: Mon Jul 03 17:08:24 UTC 2017
2017-07-03 17:08:24,501 [INFO] from application in application-akka.actor.default-dispatcher-3 -
America/Denver:: 2017-07-03 11:08:24
2017-07-03 17:08:24,502 [INFO] from application in application-akka.actor.default-dispatcher-3 -
finalDate:: Mon Jul 03 17:08:24 UTC 2017
As you can see, it formats the date correctly to the Mountain Time Zone, but then sets it back to the Calendar time.
EDIT --- Code solution:
public static Date getCurrentLocalDateTime() {
Calendar currentdate = Calendar.getInstance();
ZonedDateTime converted = currentdate.toInstant().atZone(ZoneId.of("America/Denver"))
.withZoneSameLocal(ZoneOffset.UTC);
Date finalDate = Date.from(converted.toInstant());
return finalDate;
}
A java.util.Date object has no timezone information. It has only a long value, which is the number of milliseconds from 1970-01-01T00:00:00Z (also known as "unix epoch" or just "epoch"). This value is absolutely independent of timezone (you can say "it's in UTC" as well).
When you call Logger.info("finalDate:: " + finalDate);, it calls the toString() method of java.util.Date, and this method uses the system's default timezone behind the scenes, giving the impression that the date object itself has a timezone - but it doesn't.
Check the values of finalDate.getTime() and currentdate.getTimeInMillis(), you'll see they are almost the same - "almost" because the SimpleDateFormat doesn't have the fraction of seconds, so you're losing the milliseconds precision (format method creates a String without the milliseconds, and the parse method sets it to zero when the field is not present). If I change the formatter to this, though:
// using ".SSS" to don't lose milliseconds when formatting
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
The output is:
Local:: Mon Jul 03 17:34:34 UTC 2017
America/Denver:: 2017-07-03 11:34:34.508
finalDate:: Mon Jul 03 17:34:34 UTC 2017
And both finalDate.getTime() and currentdate.getTimeInMillis() will have exactly the same values (Note that Date.toString() doesn't print the milliseconds, so you can't know what's their value - only by comparing getTime() values you know if they are the same).
Conclusion: just change your formatter to use the milliseconds (.SSS) and parsing/formatting will work. The fact that it shows the dates in another timezone is an implementation detail (toString() method uses system's default timezone), but the milliseconds value is correct.
If you want to get 11h at UTC, you must create another formatter and set its timezone to UTC:
DateFormat parser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
parser.setTimeZone(TimeZone.getTimeZone("UTC"));
finalDate = parser.parse(formattedDate);
Then, finalDate's time will have the value of 11h at UTC:
finalDate:: Mon Jul 03 11:34:34 UTC 2017
New Java Date/Time API
The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.
If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.
If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).
The code below works for both.
The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.
To do what you need, you can use a ZonedDateTime (a date and time + a timezone) and convert to another timezone keeping the same date/time values:
// current date/time in Denver
ZonedDateTime denverNow = ZonedDateTime.now(ZoneId.of("America/Denver"));
// convert to UTC, but keeping the same date/time values (like 11:34)
ZonedDateTime converted = denverNow.withZoneSameLocal(ZoneOffset.UTC);
System.out.println(converted); // 2017-07-03T11:34:34.508Z
The output will be:
2017-07-03T11:34:34.508Z
If you want a different format, use a DateTimeFormatter:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// pattern for day/hour
.appendPattern("EEE MMM dd HH:mm:ss ")
// UTC offset
.appendOffset("+HHMM", "UTC")
// year
.appendPattern(" yyyy")
// create formatter
.toFormatter(Locale.ENGLISH);
System.out.println(fmt.format(converted));
The output will be:
Mon Jul 03 11:34:34 UTC 2017
If you still need to use java.util.Date, you can easily convert from/to the new API.
In Java >= 8:
// convert your Calendar object to ZonedDateTime
converted = currentdate.toInstant()
.atZone(ZoneId.of("America/Denver"))
.withZoneSameLocal(ZoneOffset.UTC);
// converted is equals to 2017-07-03T11:34:34.508Z
// from ZonedDateTime to Date and Calendar (date will be 11:34 UTC)
Date d = Date.from(converted.toInstant());
Calendar cal = Calendar.getInstance();
cal.setTime(d);
// to get a Date that corresponds to 11:34 in Denver
Date d = Date.from(converted.withZoneSameLocal(ZoneId.of("America/Denver")).toInstant());
Calendar cal = Calendar.getInstance();
cal.setTime(d);
In Java <= 7 (ThreeTen Backport), you can use the org.threeten.bp.DateTimeUtils class:
// convert Calendar to ZonedDateTime
converted = DateTimeUtils.toInstant(currentdate)
.atZone(ZoneId.of("America/Denver"))
.withZoneSameLocal(ZoneOffset.UTC);
// converted is equals to 2017-07-03T11:34:34.508Z
// convert ZonedDateTime to Date (date will be 11:34 UTC)
Date d = DateTimeUtils.toDate(converted.toInstant());
Calendar c = DateTimeUtils.toGregorianCalendar(converted);
// to get a Date that corresponds to 11:34 in Denver
Date d = DateTimeUtils.toDate(converted.withZoneSameLocal(ZoneId.of("America/Denver")).toInstant());
Calendar c = DateTimeUtils.toGregorianCalendar(converted.withZoneSameLocal(ZoneId.of("America/Denver")));
I am converting time from GMT to different USA time-zones. For that, I have written a method which is returning the 1-hour prior time. if the time is 2:00 clock it's returning 1:00 clock
private static Date timeFormat(String timeZone) throws ParseException {
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DateFormat gmtFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
gmtFormat.setTimeZone(TimeZone.getTimeZone(TimeZone.getDefault().getID()));
Date date = null;
try {
date = gmtFormat.parse(sdfDate.format(new Date()));
LOG.info("GMT format time and date ==>> "+date);
} catch (ParseException e) {
e.printStackTrace();
}
DateFormat pstFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
pstFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
String timedd = pstFormat.format(date);
LOG.info("Return the new time based on timezone : "+pstFormat.format(date));
return gmtFormat.parse(timedd);
}
Can anybody help me out what exactly is the issue, because a few months back the same method was working fine? Is it happening because of daylight saving time?
This can be done in a much simpler way using java.time APIs. Use Instant to represent the time in UTC. It can be converted to time at any zone, and formatted to a particular pattern.
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
Instant now = Instant.now();
ZonedDateTime dt = now.atZone(ZoneId.of("UTC-05:00"));
System.out.println(dt.format(format)); //2017-05-24 04:51:03
ZonedDateTime pstDate = now.atZone(ZoneId.of("UTC-07:00"));
System.out.println(pstDate.format(format)); //2017-05-24 02:51:03
After so much of digging i have found that TimeZone won't give correct result on basis of time-zone
(EST, CST, MST, PST)
so in my method the param which i have passed as timeZone was coming as a
(EST, CST, MST, PST)
Instead of EST, CST, MST, PST i have passed US/Eastern US/Pacific US/Mountain US/Central, and it worked fine for me
I tried the below approach and searched in Web to find the solution for this but no luck : looking for the solution for converting a String in IST to PST:
String string = new Date().toString();
System.out.println(string);
SimpleDateFormat dt = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
dt.setTimeZone(TimeZone.getTimeZone("PST"));
Date D = dt.parse(string);
System.out.println(""+ D);
Even when I set time zone as PST, I am seeing out put in IST
here is the out put:
Tue Apr 18 18:58:09 IST 2017
Tue Apr 18 18:58:09 IST 2017
I tried another Option here I am seeing even it is showing the time in PST but I see below output it is a bit confusing:
public static Date convertFromOneTimeZoneToOhter(Date dt,String from,String to ) {
TimeZone fromTimezone =TimeZone.getTimeZone(from);//get Timezone object
TimeZone toTimezone=TimeZone.getTimeZone(to);
long fromOffset = fromTimezone.getOffset(dt.getTime());//get offset
long toOffset = toTimezone.getOffset(dt.getTime());
//calculate offset difference and calculate the actual time
long convertedTime = dt.getTime() - (fromOffset - toOffset);
Date d2 = new Date(convertedTime);
return d2;
}
OUT PUT:
Converted Date : Tue Apr 18 06:28:09 IST 2017
Can someone please help on this: I found lot of solutions on converting IST Date time to PST String but not IST/EST Date to PST Date.
As I mentioned above we can format to a String, but I am looking for an example of converting back to Date
You should look into Java 8's new Date API that handles timezones directly
// Get the current date and time
ZonedDateTime date1 = ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Karachi]");
System.out.println("date1: " + date1);
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println("Zoned Date Time: " + zonedDateTime);
ZoneId id = ZoneId.of("Europe/Paris");
System.out.println("ZoneId: " + id);
ZoneId currentZone = ZoneId.systemDefault();
System.out.println("CurrentZone: " + currentZone);
Prints :
date1: 2007-12-03T10:15:30+05:00[Asia/Karachi]
Zoned Date Time: 2017-04-18T09:52:09.045-04:00[America/New_York]
ZoneId: Europe/Paris
CurrentZone: America/New_York
Since some readers here will use Java 8 or later and some Java 7 or earlier, I will treat both.
I recommend you use the java.time classes introduced in Java 8 if you can:
ZoneId targetTz = ZoneId.of("America/Los_Angeles");
String string = "Tue Apr 18 18:58:09 +0300 2017";
DateTimeFormatter format = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss ZZZ uuuu",
Locale.ENGLISH);
ZonedDateTime sourceTime = ZonedDateTime.parse(string, format);
ZonedDateTime targetTime = sourceTime.withZoneSameInstant(targetTz);
String result = targetTime.format(format);
System.out.println(result);
This prints:
Tue Apr 18 08:58:09 -0700 2017
You said you wanted a PST date, and this is exactly what the ZonedDateTime gives you: date and time with time zone information.
In the example I am giving a zone offset, +0300 (corresponding to Israel Daylight Time) in the string. I understood that it wasn’t important to you how the time zone was given. I want to avoid the three and four letter time zone abbreviations like IST. Not only may IST mean either Irish Standard Time, Israel Standard Time or India Standard Time. I furthermore noticed that the java.time classes pick up 18:58:09 IST as 18:58:09 IDT (UTC+3) because it knows Israel is on DST on April 18; the SimpleDateFormat that I return to below takes IST more literally and interprets 18:58:09 IST as 18:58:09 +0200, which is 1 hour later in UTC.
You can use the java.time classes with Java 1.7 if you want. You can get them in the ThreeTen Backport.
If you don’t want to use java.time, the way to do it with the outdated classes from Java 1.0 and 1.1 is not that different in this case, only I cannot give you the PST date you asked for:
TimeZone targetTz = TimeZone.getTimeZone("America/Los_Angeles");
String string = "Tue Apr 18 18:58:09 +0300 2017";
SimpleDateFormat dt = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZ yyyy", Locale.ENGLISH);
Date d = dt.parse(string);
dt.setTimeZone(targetTz);
String result = dt.format(d);
System.out.println(result);
It prints the same result as above. However, you notice there is only one Date object. A Date object cannot hold any time zone information, so if you need this, you will have to bring the targetTz object along with d. It’s a common misunderstanding that there’s supposed to be a time zone in the Date object, probably greatly helped by the fact that its toString() prints a time zone. This is always the JVM’s default time zone and doesn’t come from the Date object, though.