I need to convert a Date which is in CST to required time zone. I will get Date as String like "11/5/2018 12:54:20" which is in CST time zone. I have to convert this to a time zone which is passed as a parameter. suppose lets take it as "GMT+0530".
The result for the above date ideally "Nov 06 2018 00:24:20"
I have tried the below code which returned the passed date(11/05/2018 12:54:20) as same instead of(Nov 06 2018 00:24:20) . I have executed this on a system which has IST time zone.
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT-0600"));
SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+0530"));
System.out.println(sdf2.format(sdf.parse("11/5/2018 12:54:20").getTime()));
Edit:
Answer:
DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( "11/5/2018 12:54:20" , f ) ;
ZoneId z = ZoneId.of( "GMT-0600" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
System.out.println(zdt);
ZoneId zKolkata = ZoneId.of( "GMT+0530" ) ;
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;
System.out.println(zdtKolkata);
tl;dr
LocalDateTime // Represent a date and a time-of-day, without offset nor zone. So *not* a moment, *not* a point on the timeline.
.parse(
"11/5/2018 12:54:20" ,
DateTimeFormatter.ofPattern( "d/M/uuuu HH:mm:ss" ) // Define a formatting pattern to match your input string.
) // Returns a `LocalDateTime`.
.atZone( // Assign a time zone, to give meaning to the `LocalDateTime` object, making it a `ZonedDateTime` object.
ZoneId.of( "America/New_York" ) // Define a time zone properly with `Continent/Region` naming, never 2-4 letter pseudo-zones such as CST or IST.
) // Returns a `ZonedDateTime` object.
.withZoneSameInstant( // Adjust from New York time to Kolkata time. Some moment, different wall-clock time.
ZoneId.of( "Asia/Kolkata" )
) // Returns another `ZonedDateTime` object rather than altering (“mutating”) the original, per Immutable Objects pattern.
.toString() // Generate text in standard ISO 8601 format, wisely extended to append the name of the time zone in square brackets.
2018-05-11T22:24:20+05:30[Asia/Kolkata]
java.time
You are using terrible old classes, now supplanted by java.time classes.
Parse your input string as a LocalDateTime because it lacks any indication of offset-from-UTC or time zone.
Define a formatting pattern to match your input.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "d/M/uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( "11/5/2018 12:54:20" , f ) ;
ldt.toString(): 2018-05-11T12:54:20
You say this was intended for CST. Did you mean China Standard Time? Or Central Standard Time in North America?
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as CST or EST or IST as they are not true time zones, not standardized, and not even unique(!).
I will assume you meant something like New York time.
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
zdt.toString(): 2018-05-11T12:54:20-04:00[America/New_York]
And apparently you want to see this same moment through the lens of the wall-clock time used by the people of a different region, a different time zone. By IST did you mean Irish Standard Time? Or India Standard Time? Again, use real time zones not these 2-4 character pseudo-zones.
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;
zdtKolkata.toString(): 2018-05-11T22:24:20+05:30[Asia/Kolkata]
To see the same moment in UTC, extract a Instant.
Instant instant = zdtKolkata.toInstant() ;
instant.toString(): 2018-05-11T16:54:20Z
All three of these ( zdt, zdtKolkata, instant ) all represent the same moment, the same point on the timeline.
In contrast, the ldt as a LocalDateTime object does not represent a moment, is not a point on the timeline. It held no real meaning until you assigned it a time zone to give it a context. Until assigning that zone, we do not know if meant noon hour in Australia or in Africa, or in America. It could have meant any of about 26-27 hours, the range of time zones around the globe.
ISO 8601
Rather than inventing your own formats for exchanging date-time values as text, use the standard ISO 8601 formats.
The java.time classes conveniently use ISO 8601 formats by default when generating/parsing strings.
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.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
You are setting the timezone of sdf twice and not setting timezone of sdf2 and thus getting incorrect results. Also, you don't need to call getTime() when passing object to DateFormat::format().
Here is a fixed version of your code:
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
TimeZone cstTimeZone = TimeZone.getTimeZone("CST");
sdf.setTimeZone(cstTimeZone);
SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
sdf2.setTimeZone(TimeZone.getTimeZone("GMT+0530"));
System.out.println(sdf2.format(sdf.parse("11/5/2018 12:54:20")));
Note that the classes you are using are quite old and since version 8, Java provides new Date and Time APIs.
Related
I've seen many examples of converting date from one time zone to another. But all of them has output as a String. I want a date object as output.
The methods I've tried -
Approach 1
SimpleDateFormat dateTimeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss a z");
dateTimeFormat.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
Date date = new Date();
System.out.println(dateTimeFormat.format(date)); // this print IST Timezone
DateFormat timeFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss a z");
timeFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String estTime = timeFormat.format(date);
try {
date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss a z", Locale.ENGLISH).parse(estTime);
System.out.println(date);
} catch (ParseException ex) {
Logger.getLogger(A.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(timeFormat.format(date));
Approach 2
private static Date shiftTimeZone(Date date, TimeZone sourceTimeZone, TimeZone targetTimeZone) {
System.out.println(sourceTimeZone.toString());
System.out.println(targetTimeZone.toString());
Calendar sourceCalendar = Calendar.getInstance();
sourceCalendar.setTime(date);
sourceCalendar.setTimeZone(sourceTimeZone);
Calendar targetCalendar = Calendar.getInstance();
for (int field : new int[]{Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND}) {
targetCalendar.set(field, sourceCalendar.get(field));
}
targetCalendar.setTimeZone(targetTimeZone);
return targetCalendar.getTime();
}
Approach 1 gives me result as a String.
03/22/2018 10:16:57 AM EDT <- instanceOf String
Approach 2 gives me correct date and time of Eastern Time time zone, but the Date has the time zone of IST.
Thu Mar 22 10:16:57 IST 2018 <- instanceof Date
Can anyone please help me to obtain a Date object with Eastern Time TimeZone.
Update - My ultimate goal is to get Unix Timestamp of the current Eastern Time.
tl;dr
Instant.now() // Capture the current moment in UTC, an `Instant` object.
.atZone( // Adjust from UTC into a particular time zone.
ZoneId.of( “Asia/Kolkata” )
) // Returns a `ZonedDateTime` object.
.withZoneSameInstant( // Adjust into yet another time zone. All three are the same moment but vowed using different wall-clock times.
ZoneId.of( “Africa/Tunis” )
) // Returns another `ZonedDateTime` object.
Or…
ZonedDateTime.now(
ZoneId.of( “Asia/Kolkata” )
).withZoneSameInstant(
ZoneId.of( “Africa/Tunis” )
)
Avoid legacy date-time classes
Firstly, stop using the legacy date-time classes. They are an awful wretched mess. Supplanted by the java.time classes.
Date is replaced by Instant.
Calendar is replaced by ZonedDateTime
SimpleDateFormat is replaced by DateTimeFormatter.
Deceived by Date::toString
Secondly, understand that Date has a horribly confusing feature of dynamically applying your JVM’s current default time zone while generating a String. Date always represents a moment in UTC. The toString method creates a false illusion of Date carrying a time zone, when actually its value is in UTC. While well-intentioned by the class designers, this was a disastrous decision, causing no end of confusion amongst countless programmers for decades now.
Even worse: There actually is a time zone buried in a Date, but is irrelevant to this discussion. Confusing? Yes; as I said, an awful wretched mess of bad design.
Instant
The Instant class replacing Date is much clearer. An Instant represents a moment, a point on the timeline, always in UTC, with a resolution of nanoseconds.
Use Instant to capture the current moment in UTC. The JVM’s current default time zone is irrelevant. The host OS’ assigned time zone is irrelevant.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Unlike Date::toString, the Instant::toString method tells the truth. A Instant is always in UTC, so toString always reports UTC. A String is generated in standard ISO 8601 format. The Z on the end is short for Zulu and means UTC.
instant.toString(): 2018-01-23T12:34:56.123456789Z
About capturing the current moment… In Java 8, the current moment was captured in milliseconds even though the java.time classes can represent nanoseconds. In Java 9 and later, a new implementation of Clock provides for capturing the current moment in finer granularity. In Java 9.0.4 on macOS Sierra, I see microseconds. The hardware clocks on conventional computers nowadays cannot capture the current moment with accuracy beyond microseconds.
ZonedDateTime
To view that same moment through the lens of a wall-clock time used by the people of a particular region, assign that region’s time zone. Applying a ZoneId to an Instant produces a ZonedDateTime. Conceptually:
ZonedDateTime = ( Instant + ZoneId )
In code:
ZoneId z = ZoneId.of( “Pacific/Auckland” ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
Adjusting to another time zone is easy. You can start with the Instant again.
ZoneId zKolkata = ZoneId.of( “Asia/Kolkata” ) ;
ZonedDateTime zdt = instant.atZone( zKolkata ) ;
Or you can adjust the ZonedDateTime object. The java.time classes use immutable objects. So rather than “mutate” (alter) the original object, the adjustment produces a new distinct object.
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ; // Same moment, same point on the timeline, different wall-clock time.
You can skip the use of the Instant. I do not recommend doing so. Programmers should be doing their thinking, debugging, logging, exchanging of data, and much of their business logic in UTC. So Instant should be your go-to class whenever you start any work with date-time values.
ZonedDateTime zdtNewYork = ZonedDateTime.now( ZoneId.of( "America/New_York" ) ) ;
The ZonedDateTime::toString method wisely extends the ISO 8601 standard by appending the name of the time zone in square brackets.
String output = zdtNewYork.toString() ;
2018-01-23T07:34:56.123456789-05:00[America/New_York]
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.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
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?
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
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?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
I'm trying to convert current time in MST using below code
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
TimeZone toTimeZone = TimeZone.getTimeZone("MST");
sdf.setTimeZone(toTimeZone);
Date date = new Date();
String strDate = sdf.format(date.getTime());
strDate displaying correct MST time, but after parsing it is giving wrong date time.
Date currentDate = sdf.parse(strDate);
I want current MST time in Date format not in string.
A java.util.Date object does not have a concept of time zone.
There is no way to set a timezone for a Date
There is no way to change the timezone of a Date object
A Date object created with the new Date() default constructor will be initialised with the current time in the system default timezone
All you did is add a time zone information for the formatting part... setTimeZone does not convert anything.
tl;dr
ZonedDateTime zdt = LocalDateTime.parse( input , DateTimeFormatter.forPattern( "dd/MM/uuuu hh:mm:ss" ) ).atZone( ZoneId.of( "America/Denver" ) );
Avoid legacy date-time classes
You are using old outmoded troublesome legacy date-time classes.
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.
Now in maintenance mode, the Joda-Time project also 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.
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.
LocalDateTime
Your input string lacks any indication of offset-from-UTC or time zone. So we must parse as a LocalDateTime. A LocalDateTime has no offset or time zone, so it does not represent a moment on the timeline. Like saying "Christmas starts at midnight on December 25", that only has meaning (only becomes a point on the timeline) when you apply it to a particular time zone somewhere on the planet.
String input = …
DateTimeFormatter f = DateTimeFormatter.forPattern( "dd/MM/uuuu hh:mm:ss" );
LocalDateTime ldt = LocalDateTime.parse( input , f );
ZonedDateTime
If you know the context and can assume the intended offset or time zone, you can create an OffsetDateTime or ZonedDateTime respectively.
Use proper time zone names, named in the format of continent/region. By MST perhaps you meant the America/Denver time zone used in much of the Rocky Mountains parts of the United States, or America/Edmonton used in parts of Canada.
Never use the 3-4 letter abbreviations such as MST. These abbreviations are not true time zones, are not standardized, and are not even unique(!).
ZoneId zoneId = ZoneId.of( "America/Denver" ) ;
ZonedDateTime zdt = ldt.atZone( zoneId ) ;
Converting
I suggest avoiding the notoriously troublesome java.util.Date class. But if you must do so , you may convert to/from java.time types. To interoperate with other code or libraries, convert using new methods added to the old classes. In this case, use a Instant object extracted from the OffsetDateTime or ZonedDatetime and pass to java.util.Date.from.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
java.util.Date utilDate = java.util.Date.from( zdt.toInstant() ) ;
Going the other direction, use another new method added to the old class, java.util.Instant::toInstant.
Instant instant = utilDate.toInstant();
ZonedDateTime zdt = instant.atZone( zoneId ) ;
I have the number of seconds from 31 Dec 1969 19:00:00 i.e. (EST) and I want to convert the same to a date format.
I have the following code which returns any invalid date. Can anyone point out what seems to be the issue here.
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class sample
{
public static void main(String args[])
{
DateFormat df = new SimpleDateFormat("dd/MMM/yyyy HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("EST"));
Date d1 = new Date(1000*1373604190); //Converting to millisecond
String formattedDate = df.format(d1);
System.out.println(formattedDate); //I'm getting 22/Dec/1969 16:50:55
}
}
How can I solve this.
You are using int literals instead of long in your numbers. By default a integral literal is int unless you specify that is long with L at the end. Try this:
Date d1 = new Date(1000*1373604190L);
(note the L at the end of your literal 1373604190)
tl;dr
Instant.ofEpochSeconds( 1_373_604_190L )
.atZone( ZoneId.of( "America/New_York" ) )
.format( DateTimeFormatter.ofPattern( "dd MMM uuuu HH:mm:ss" , Locale.CANADA ) )
Details
the number of seconds from 31 Dec 1969 19:00:00 i.e. (EST)
Do not think parochially when doing date-time work. Rather than translate values such as the epoch reference moment in and out of your own zone, just think in UTC. Consider UTC to be The One True Time, all others being variations on that theme.
So, always refer to the epoch reference moment as 1970-01-01T00:00:00Z, the first moment of 1970 in UTC, rather than in any other time zone.
(EST)
Also, never use those 3-4 letter abbreviations as time zones. Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Those 3-4 letter abbreviation such as EST or IST are not true time zones, not standardized, and not even unique(!).
Using java.time
The modern way to do this work is with the java.time classes.
long secondsSinceEpoch = 1_373_604_190L ;
We convert that to a Instant object. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.ofEpochSeconds( secondsSinceEpoch ) ;
To see this value through the lens of some wall-clock time, apply a time zone as a ZoneId to get a ZonedDateTime object.
I am guessing that by EST you meant the time zone used by much of the eastern portions of the United States and Canada. I will arbitrarily choose the time zone America/New_York.
ZoneId z = ZoneId.of( "America/New_York" );
ZonedDateTime zdt = instant.atZone( "America/New_York" );
secondsSinceEpoch: 1373604190
instant.toString(): 2013-07-12T04:43:10Z
zdt.toString(): 2013-07-12T00:43:10-04:00[America/New_York]
See live code at IdeOne.com.
Strings
To generate a string, you can either let java.time automatically localize or you can specify an explicit formatting pattern.
Locale locale = Locale.CANADA ;
DateTimeFormatter formatterLocalized = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( locale );
String outputLocalized = zdt.format( formatterLocalized );
12-Jul-2013 12:43:10 AM
DateTimeFormatter formatterCustom = DateTimeFormatter.ofPattern( "dd MMM uuuu HH:mm:ss" , locale );
String output = zdt.format( formatterCustom );
12 Jul 2013 00:43:10
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.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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.
Server sends me time like this:
2012-06-08 17:00:00 +0100
I need to change it like HH:MM based on local time. For example this time is what time at Japan, India, US and etc.
How can I do this? Thanks
Option 1: using java.util.Date/Calendar:
First you need to parse the value to a Date, then reformat it in the format and time zone
you're interested in:
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z",
Locale.US);
Date date = inputFormat.parse(inputText);
// Potentially use the default locale. This will use the local time zone already.
SimpleDateFormat outputFormat = new SimpleDateFormat("HH:mm", Locale.US);
String outputText = outputFormat.format(date);
Option 2: using Joda Time
Joda Time is a much better date/time library for Java.
DateTimeFormatter inputFormatter = DateTimeFormat
.forPattern("yyyy-MM-dd HH:mm:ss Z")
.withLocale(Locale.US);
DateTime parsed = inputFormatter.parseDateTime(inputText);
DateTimeFormatter outputFormatter = DateTimeFormat
.forPattern("HH:mm")
.withLocale(Locale.US)
.withZone(DateTimeZone.getDefault());
String outputText = outputFormatter.print(parsed);
Note that you should only convert to/from string representations when you really need to. Otherwise, use the most appropriate type based on your usage - this is where Joda Time really shines.
Use JodaTime. It's far better and safer than Java's Date and Time API. There are a lot of methods that return a LocalTime object (HH:MM).
As an example, new DateTime(your date time).toLocalTime();
java.util.Date is always in UTC. What makes you think it's in local time? I suspect the problem is that you're displaying it via an instance of Calendar which uses the local timezone, or possibly using Date.toString() which also uses the local timezone.
If this isn't the problem, please post some sample code.
I would, however, recommend that you use Joda Time anyway, which offers a much clearer API.
The other Answers are correct but outdated. Use java.time classes instead.
tl;dr
ZonedDateTime zdt_Kolkata = OffsetDateTime.parse( "2012-06-08 17:00:00 +0100" , DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss Z" ) ).atZone( ZoneId.of( "Asia/Kolkata" ) );
Using java.time
Define a DateTimeFormatter formatting pattern to match your input String.
String input = "2012-06-08 17:00:00 +0100";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss Z" );
OffsetDateTime
Parse the String as an OffsetDateTime object that represents the +0100 in your input which means “one hour ahead of UTC”.
OffsetDateTime odt = OffsetDateTime.parse( input , f );
ZonedDateTime
Apply a ZoneId to produce a ZonedDateTime for any desired time zone. 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 zoneId_Kolkata = ZoneId.of( "Asia/Kolkata" ); // India
ZonedDateTime zdt_Kolkata = odt.atZone( zoneId_Kolkata );
…and another…
ZoneId zoneId_Montréal = ZoneId.of( "Asia/Montreal" ); // Québec Canada
ZonedDateTime zdt_Montréal = odt.atZone( zoneId_Montréal );
Instant
For UTC, extract an Instant object. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = zdt_Montréal.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.
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.