Given a DateTime for example 2015-07-09T05:10:00+02:00 using Joda-Time?
How can I convert it to local time, meaning adding the timezone to the time itself.
Desired output: 2015-07-09T07:10:00
I tried dateTime.toDateTime(DateTimeZone.UTC) but that did not give the desired result.
Adding a bit more info and examples to the correct answers (accepted answer and other one).
UPDATE Added section at end on java.time classes. These supplant Joda-Time.
Purpose of LocalDateTime
You may be confused about the purpose of LocalDateTime.
If trying to represent a date-time value using "wall clock time" as seen by someone in a locality looking at their own clock and calendar, then adjust the time zone of the DateTime object to suit the desired locality.
LocalDateTime is not meant for a particular locality but for the general idea of date+time. For example, "This year's Christmas starts at midnight on December 25, 2014". Conceptually, that is a LocalDateTime, intended to mean different moments in Paris than Montréal and Auckland.
Adjusting Time Zone
Use the DateTimeZone class in Joda-Time to adjust to a desired time zone. Joda-Time uses immutable objects. So rather than change the time zone ("mutate"), we instantiate a new DateTime object based on the old but with the desired difference (some other time zone).
Use proper time zone names. Generally a continent/cityOrRegion.
DateTimeZone zoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTimeZone zoneAuckland = DateTimeZone.forID( "Pacific/Auckland" );
Parse string, assign a time zone, adjust to other time zones.
DateTime dateTimeParis = new DateTime( "2015-07-09T05:10:00+02:00" , zoneParis );
DateTime dateTimeMontréal = dateTimeParis.withZone( zoneMontréal );
DateTime dateTimeAuckland = dateTimeParis.withZone( zoneAuckland );
Dump to console.
System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeAuckland: " + dateTimeAuckland );
When run.
dateTimeParis: 2015-07-09T05:10:00.000+02:00
dateTimeMontréal: 2015-07-08T23:10:00.000-04:00
dateTimeAuckland: 2015-07-09T15:10:00.000+12:00
Localize Using Formatted Strings
Joda-Time can translate to a particular locale’s language and customary style when creating a string representation of your date-time object.
DateTimeFormatter formatterMontréal = DateTimeFormat.forStyle( "FF" ).withZone( zoneMontréal ).withLocale( Locale.CANADA_FRENCH );
String outputMontréal = formatterMontréal.print( dateTimeParis );
System.out.println( "outputMontréal: " + outputMontréal );
When run:
outputMontréal: mercredi 8 juillet 2015 23 h 10 EDT
java.time
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes. The Joda-Time framework inspired java.time, so concepts are quite similar.
ZoneId and ZoneOffset are the two classes to represent a time zone and offset-from-UTC respectively. An offset is merely a number of hours and minutes and seconds. A time zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).
ZoneId zoneParis = ZoneId.of( "Europe/Paris" );
ZoneId zoneMontreal = ZoneId.of( "America/Montreal" );
ZoneId zoneAuckland = ZoneId.of( "Pacific/Auckland" );
The primary date-time classes in java.time are:
Instant – A moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
OffsetDateTime – An Instant plus a ZoneOffset.
ZonedDateTime – An Instant plus a ZoneId.
The java.time classes use ISO 8601 standard formats by default when parsing/generating strings representing date-time values. So no need to specify a formatting pattern with such inputs.
This input here indicates an offset-from-UTC but not a full time zone. So we parse as an OffsetDateTime rather than a ZonedDateTime.
OffsetDateTime odt = OffsetDateTime.parse( "2015-07-09T05:10:00+02:00" );
As the basic building-block of java.time, always in UTC by definition, you may want to extract an Instant.
Instant instant = odt.toInstant(); // `Instant` is always in UTC by definition.
You can adjust into a time zone.
ZonedDateTime zdtParis = odt.atZoneSameInstant( zoneParis );
ZonedDateTime zdtMontreal = odt.atZoneSameInstant( zoneMontreal );
ZonedDateTime zdtAuckland = zdtMontreal.withZoneSameInstant( zoneAuckland );
Localize via the DateTimeFormatter class.
DateTimeFormatter f = DateTimeformatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH );
String output = zdtMontreal.format( f );
See live code in IdeOne.com.
odt: 2015-07-09T05:10+02:00
instant: 2015-07-09T03:10:00Z
zdtParis: 2015-07-09T05:10+02:00[Europe/Paris]
zdtMontreal: 2015-07-08T23:10-04:00[America/Montreal]
zdtAuckland: 2015-07-09T15:10+12:00[Pacific/Auckland]
output: mercredi 8 juillet 2015 23 h 10 EDT
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….
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.
What #Nazgul said is right, but in case all you want to achieve is a "wall-time" in UTC zone you can do something like that:
DateTime dateTimePlus2 = DateTime.parse("2015-07-09T05:10:00+02:00");
System.out.println(dateTimePlus2);
DateTime dateTimeUTC = dateTimePlus2.withZone(DateTimeZone.UTC);
System.out.println(dateTimeUTC);
LocalDateTime localDateTimeUTC = dateTimeUTC.toLocalDateTime();
System.out.println(localDateTimeUTC);
Result:
2015-07-09T05:10:00.000+02:00
2015-07-09T03:10:00.000Z ("Z" == Zulu tz == UTC)
2015-07-09T03:10:00.000
As you can see, the time is not "07:10" as you expected, because UTC+2 zone is two hours ahead of UTC. Converting to UTC subtracts 2 hours.
DateTime without timezone dosnt make sense. DateTime are always relative to the timezone in which they are used. Without the timezone information a date time combination makes no sense for the geography as such. raw timestamp millies can however be accessed as the number of millies gone since 1st Jan 1970 but any concrete date time combinations must have a timezone with it.
Related
I am trying to create a proper conversion method for my app which will get the input as PST and can convert it to CST or EST and also support the daylight saving.
Here is the problem. Check this below code and the output. I am simply converting my PST date to CST and EST and printing it. But in output CST and EST is same. there needs to be 1 hour of difference but it is not reflecting.
System.out.println("CURRENT in PST : " + new Date());
SimpleDateFormat utcDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
utcDateFormat.setTimeZone(TimeZone.getTimeZone("PST"));
System.out.println("convert in PST : " + utcDateFormat.format( new Date()));
utcDateFormat.setTimeZone(TimeZone.getTimeZone("CST"));
System.out.println("convert in CST : " + utcDateFormat.format(new Date()));
utcDateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
System.out.println("convert in EST : " + utcDateFormat.format(new Date()));
OutPut :
CURRENT in PST : Wed Jun 13 15:14:15 PDT 2018
convert in PST : 2018-06-13T15:14:15Z
convert in CST : 2018-06-13T17:14:15Z
convert in EST : 2018-06-13T17:14:15Z
So can any one please let me know why? And how I can do this conversion perfectly for all timezones of USA.
I used EST5EDT and it worked but don't know it will support when daylight saving start or ends.
I can use JAVA 8.
tl;dr
how I can do this conversion perfectly for all timezones of USA.
Instant now = Instant.now() ; // Capture current moment in UTC.
ZonedDateTime zdtLosAngeles = now.atZone( ZoneId.of( "America/Los_Angeles" ) ) ;
ZonedDateTime zdtChicago = now.atZone( ZoneId.of( "America/Chicago" ) ) ;
ZonedDateTime zdtNewYork = now.atZone( ZoneId.of( "America/New_York" ) ) ;
ZonedDateTime zdtGuam = now.atZone( ZoneId.of( "America/Guam" ) ) ;
ZonedDateTime zdtHonolulu = now.atZone( ZoneId.of( "America/Los_Angeles" ) ) ;
ZonedDateTime zdtAnchorage = now.atZone( ZoneId.of( "America/Anchorage" ) ) ;
ZonedDateTime zdtIndianapolis = now.atZone( ZoneId.of( "America/Indiana/Indianapolis" ) ) ;
ZonedDateTime zdtPortOfSpain = now.atZone( ZoneId.of( "America/Port_of_Spain" ) ) ;
ZonedDateTime zdtPhoenix = now.atZone( ZoneId.of( "America/Phoenix" ) ) ;
… and so on through the list of the many time zones in the United States.
Date is UTC
"CURRENT in PST : " + new Date()
This is incorrect; this code is not behaving as you apparently are expecting. You may get a String such as Wed Jun 13 15:58:37 PDT 2018, or you may not.
A java.util.Date is always in UTC, by definition. Defined as a count of milliseconds since the epoch reference of first moment of 1970 in UTC. You generated output string may be in west coast time, but that is only by accident.
The confusing part is that the Date::toString method is unfortunately designed to inject the JVM’s current default time zone dynamically while generating a String to represent this Date object’s value. If your JVM happens to have a current default time zone of a zone such as America/Los_Angeles, you will get a string with a west coast US time-of-day. But then your results will vary at runtime should the default time zone be set otherwise, and your "CURRENT in PST:" label will be incorrect. And remember that the JVM’s current default time zone can be changed at any moment during runtime by any code in any thread of any app within the JVM.
The legacy date-time classes are riddled with such poor design choices. Avoid using these classes.
java.time
The modern approach uses the java.time classes rather than those troublesome old legacy date-time classes.
Instant replaces java.util.Date. 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.now() ; // Capture the current moment in UTC.
Apply a time zone (ZoneId) to get a ZonedDateTime object. Same moment, same point on the timeline, but viewed through the wall-clock time used by the people of a certain region.
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 pseudo-zones such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
As a shortcut, you can skip the Instant object by calling ZonedDateTime.now and passing a ZoneId.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
And how I can do this conversion perfectly for all timezones of USA.
Firstly, never use the pseudo-zones “PST”, “CST”, “EST” is discussed above. Use real time zones.
There are many more than three zones in the United States, such as America/Chicago, America/New_York, America/Fort_Wayne, Pacific/Honolulu, America/Puerto_Rico, and so on. Why so many? Because current and past practices have varied. For example, some places in the US opt out of the silliness of Daylight Saving Time (DST). Various places have various histories where the offset-from-UTC in that zone were changed by people at different points in their history.
Secondly, keep your time zone definitions up-to-date. Most software systems use a copy of tzdata (formerly known as Olson Database) published by IANA. Your host OS, your JVM implementation, and your database server, likely all have a copy of tzdata that must be kept up-to-date if the rules for any zone you care about change.
Never ignore zone/offset
"yyyy-MM-dd'T'HH:mm:ss'Z'"
Your formatting pattern made a dreadful choice in putting single-quote marks around the Z. That Z means UTC, and is pronounced Zulu. Your single-quotes tell the formatter to ignore that particular string as if it were meaningless. But it is not meaningless, it is vital information about your input data which you are choosing to ignore and discard.
Another thing… That particular format is defined by the ISO 8601 standard. The java.time classes use these standard formats by default when parsing/generating strings.
Instant.parse( "2018-01-23T12:34:56Z" ) // Parse standard ISO 8601 string into a `Instant` object.
instant.toString() // Yields "2018-01-23T12:34:56Z".
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, 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 have to get DateTime with using TimeZone and then get Timestamp from that DateTime
My Code is give below :
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dt = new Date();
String currentTime = formatter.format(dt);
System.out.println("currentTime>>>>" + currentTime);
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("Canada/Eastern"));
Date parsedDate = format.parse(currentTime);
System.out.println("parsedDate>>>>" + parsedDate);
Timestamp timestamp = new Timestamp(parsedDate.getTime());
System.out.println("timestamp>>>>>>" + timestamp);
Problem is that I am not getting right datetime of Canada/Eastern TimeZone in timestamp.
I am getting the below time
currentTime>>>>2016-11-09 15:17:09
parsedDate>>>>Thu Nov 10 01:47:09 IST 2016
timestamp>>>>>>2016-11-10 01:47:09.0
Indian time is correct : 2016-11-09 15:17:09
When I parse it to Canada/Eastern it shows : Thu Nov 10 01:47:09 IST 2016
But eastern canada time is 04:50:21 EST Wednesday, 9 November 2016
I am using Java with Eclipse Mars 1.
tl;dr
Instant.now()
.atZone( ZoneId.of( "America/Toronto" ) )
No parsing! Do not parse to adjust time zone.
Avoid the troublesome old classes: java.text.SimpleDateFormat, java.util.Date, java.util.TimeZone.
java.time
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes.
Instant
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.now();
2016-11-10T04:52:02.586Z
Time zone
You can adjust this Instant into a time zone by applying a ZoneId to get a ZonedDateTime.
Do not parse as a way to adjust time zone! perhaps you are conflating a date-time object with a string that might represent its value. A date-time object can generate a string, and can parse a string, but the string is always distinct and separate from the date-time 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(!).
Furthermore, your Canada/Eastern zone is actually just an alias for the real zone of America/Toronto.
ZoneId z = ZoneId.of( "America/Toronto" );
ZonedDateTime zdt = instant.atZone( z );
2016-11-09T23:52:02.586-05:00[America/Toronto]
You could adjust into India time as well.
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtKolkata = instant.atZone( zKolkata );
2016-11-10T10:22:02.586+05:30[Asia/Kolkata]
Dump to console.
System.out.println( "instant: " + instant );
System.out.println( "zdt: " + zdt );
System.out.println( "zdtKolkata: " + zdtKolkata );
instant: 2016-11-10T04:52:02.586Z
zdt: 2016-11-09T23:52:02.586-05:00[America/Toronto]
zdtKolkata: 2016-11-10T10:22:02.586+05:30[Asia/Kolkata]
See live code in IdeOne.com.
Database
By Timestamp I assume you meant java.sql.Timestamp. That class is now outmoded by the java.time classes, if you have a JDBC driver that complies with JDBC 4.2 or later. Just pass the Instant object to PreparedStatement::setObject. Fetch via ResultSet::getObject.
myPreparedStatement.setObject( … , instant );
If your JDBC driver does not comply, fall back to converting to java.sql.Timestamp. But minimize use of that class, only for talking to the database. Immediately convert back into java.time. Do not attempt business logic with Timestamp.
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
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 java.time.
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….
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.
Timestamp is unique and same every where in all timezones, which is value of new Date() in millis. What you are looking for here is formatted time of given timestamp (dt in above example.).
Date dt = new Date();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("IST time: " + format.format(dt));
format.setTimeZone(TimeZone.getTimeZone("Canada/Eastern"));
String parsedDate = format.format(dt);
System.out.println("Canada Time: " + parsedDate);
Output:
IST time: 2016-11-09 16:33:22
Canada Time: 2016-11-09 06:03:22
A Timestamp doesn't have a time zone in Java, it only represents a moment in time based on a number of milliseconds elapsed since a reference point, the epoch.
So it seems to me that you want your Timestamp to point to the current instant, which would be written very simply:
//with Java 8
Timestamp ts = Timestamp.from(Instant.now());
//or prior to Java 8:
Timestamp ts = new Timestamp(new Date().getTime());
You can set the TimeZone based on GMT. We know that Canada time is GMT-5,
so you can get the current Canada time like this:
TimeZone tz = TimeZone.getTimeZone("GMT-5");
Calendar c = Calendar.getInstance(tz);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CANADA);
dateFormat.setTimeZone(tz);
System.out.println(dateFormat.format(c.getTime()));
Output: 2016-11-09 06:08:47
You need to explicitly use DateFormat.setTimeZone() to print the Date in the desired timezone.
If you don't do this, the c.getTime() result will be your zone current time.
I wanted to convert a date from one time zone to another, using SimpleDateFormat class in java. But somehow it is generating different results which are suppose to be in the same TimeZone.
Here is a test case, and its generating one result as IST and other one as GMT. i think it should be generating only GMT's for both cases.
public class TestOneCoreJava {
public static void main(String[] args) throws ParseException {// Asia/Calcutta
DateFormat formatter = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a");
System.out.println(getDateStringToShow(formatter.parse("26-Nov-10 03:31:20 PM +0530"),"Asia/Calcutta", "Europe/Dublin", false));
System.out.println(getDateStringToShow(formatter.parse("02-Oct-10 10:00:00 AM +0530"),"Asia/Calcutta", "Europe/Dublin", false));
//------Output--
//26-Nov-10 GMT
//02-Oct-10 IST
}
public static String getDateStringToShow(Date date,
String sourceTimeZoneId, String targetTimeZoneId, boolean includeTime) {
String result = null;
// System.out.println("CHANGING TIMEZONE:1 "+UnitedLexConstants.SIMPLE_FORMAT.format(date));
String date1 = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a").format(date);
SimpleDateFormat sourceTimeZoneFormat = new SimpleDateFormat("Z");
sourceTimeZoneFormat.setTimeZone(TimeZone.getTimeZone(sourceTimeZoneId));
date1 += " " + sourceTimeZoneFormat.format(date);
// Changed from 'Z' to 'z' to show IST etc, in place of +5:30 etc.
SimpleDateFormat targetTimeZoneFormat = new SimpleDateFormat("dd-MMM-yy hh:mm:ss a z");
targetTimeZoneFormat.setTimeZone(TimeZone.getTimeZone(targetTimeZoneId));
SimpleDateFormat timeZoneDayFormat = null;
if (includeTime) {
timeZoneDayFormat = targetTimeZoneFormat;
} else {
timeZoneDayFormat = new SimpleDateFormat("dd-MMM-yy z");
}
timeZoneDayFormat.setTimeZone(TimeZone.getTimeZone(targetTimeZoneId));
try {
result = timeZoneDayFormat.format(targetTimeZoneFormat.parse(date1));
// System.out.println("CHANGING TIMEZONE:3 "+result);
} catch (ParseException e) {
e.printStackTrace();
}
return result;
}
}
tl;dr
Use modern java.time classes, specifically ZonedDateTime and ZoneId. See Oracle Tutorial.
ZonedDateTime // Represent a date and time-of-day in a specific time zone.
.now( // Capture the current moment as seen in the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Pacific/Auckland" ) // Specify time zone using proper name in `Continent/Region` format. Never use 3-4 letter pseudo-zone such as IST or PST or EST.
) // Returns a `ZonedDateTime` object.
.withZoneSameInstant( // Adjust from one time zone to another. Same point on the timeline, same moment, but different wall-clock time.
ZoneId.of( "Africa/Tunis" )
) // Returns a new fresh `ZonedDateTime` object rather than altering/“mutating” the original, per immutable objects pattern.
.toString() // Generate text in standard ISO 8601 format, extended to append name of zone in square brackets.
2018-09-18T21:47:32.035960+01:00[Africa/Tunis]
For UTC, call ZonedDateTime::toInstant.
Avoid 3-Letter Time Zone Codes
Avoid those three-letter time zone codes. They are neither standardized nor unique. For example, your use of "IST" may mean India Standard Time, Irish Standard Time, and maybe others.
Use proper time zone names. The definition of time zones and their names change frequently, so keep your source up-to-date. For example the old "Asia/Calcutta" is now "Asia/Kolkata". And not just names; governments are notorious for changing the rules/behavior of a time zone, occasionally at the last minute.
Avoid j.u.Date
Avoid using the bundled java.util.Date and Calendar classes. They are notoriously troublesome and will be supplanted in Java 8 by the new java.time.* package (which was inspired by Joda-Time).
java.time
Instant
Learn to think and work in UTC rather than your own parochial time zone. Logging, data-exchange, and data-storage should usually be done in UTC.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
instant.toString(): 2018-09-18T20:48:43.354953Z
ZonedDateTime
Adjust into a time zone. Same moment, same point on the timeline, different wall-clock time. Apply a ZoneId (time zone) to get a ZonedDateTime object.
ZoneId zMontreal = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtMontreal = instant.atZone( zMontreal ) ; // Same moment, different wall-clock time.
We can adjust again, using either the Instant or the ZonedDateTime.
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtKolkata = zdtMontreal.withZoneSameInstant( zKolkata ) ;
ISO 8601
Calling toString on any of these classes produce text in standard ISO 8601 class. The ZonedDateTime class extends the standard wisely by appending the name of the time zone in square brackets.
When exchanging date-time values as text, always use ISO 8601 formats. Do not use custom formats or localized formats as seen in your Question.
The java.time classes use the standard formats by default for both parsing and generating strings.
Instant instant = Instant.parse( "2018-01-23T01:23:45.123456Z" ) ;
Using standard formats avoids all that messy string manipulation seen in the Question.
Adjust to UTC
You can always take a ZonedDateTime back to UTC by extracting a Instant.
Instant instant = zdtKolkata.toInstant() ;
DateTimeFormatter
To represent your date-time value in other formats, search Stack Overflow for DateTimeFormatter class. You will find many examples and discussions.
UPDATE: The Joda-Time project is now in maintenance-mode, and advises migration to the java.time classes. I am leaving this section intact as history.
Joda-Time
Beware of java.util.Date objects that seem like they have a time zone but in fact do not. In Joda-Time, a DateTime does indeed know its assigned time zone. Generally should specify a desired time zone. Otherwise, the JVM's default time zone will be assigned.
Joda-Time uses mainly immutable objects. Rather than modify an instance, a new fresh instance is created. When calling methods such as toDateTime, a new fresh DateTime instance is returned leaving the original object intact and unchanged.
//DateTime now = new DateTime(); // Default time zone automatically assigned.
// Convert a java.util.Date to Joda-Time.
java.util.Date date = new java.util.Date();
DateTime now = new DateTime( date ); // Default time zone automatically assigned.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime nowIndia = now.toDateTime( timeZone );
// For UTC/GMT, use built-in constant.
DateTime nowUtcGmt = nowIndia.toDateTime( DateTimeZone.UTC );
// Convert from Joda-Time to java.util.Date.
java.util.Date date2 = nowIndia.toDate();
Dump to console…
System.out.println( "date: " + date );
System.out.println( "now: " + now );
System.out.println( "nowIndia: " + nowIndia );
System.out.println( "nowUtcGmt: " + nowUtcGmt );
System.out.println( "date2: " + date2 );
When run…
date: Sat Jan 25 16:52:28 PST 2014
now: 2014-01-25T16:52:28.003-08:00
nowIndia: 2014-01-26T06:22:28.003+05:30
nowUtcGmt: 2014-01-26T00:52:28.003Z
date2: Sat Jan 25 16:52:28 PST 2014
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.
When dealing with Timezone issues in Google API. I came across such kind of issues.
Look at this piece of code of yours:-
System.out.println(getDateStringToShow(formatter.parse("26-Nov-10 03:31:20 PM
+0530"),"Asia/Calcutta", "Europe/Dublin", false));
System.out.println(getDateStringToShow(formatter.parse("02-Nov-10 10:00:00 AM
+0530"),"Asia/Calcutta", "Europe/Dublin", false));
If i give above as input it will run fine the way we want to.
If you still want to go with this way then you have to perform calculation according to your need.
Like adjusting the time Mathematically and things similar to it.
Or a Simple fix for your case will be something like this
SimpleDateFormat d =new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
d.setTimeZone(TimeZone.getTimeZone("Europe/Dublin"));
Date firsttime = d.parse("2013-12-19T03:31:20");
Date seondtime = d.parse("2013-12-19T10:00:00");
System.out.println(getDateStringToShow(firsttime,"Asia/Calcutta",
"Europe/Dublin", false));
System.out.println(getDateStringToShow(seondtime,"Asia/Calcutta",
"Europe/Dublin", false));
My suggestion will be to refer JODA API . More preferrable over Old School Date.
I declared Calendar and SimpleDateFormat like this:
calendar = Calendar.getInstance(TimeZone.getTimeZone("Malaysia"));
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MMMMM.dd hh:mm aaa");
or:
calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));
Then I call this:
sdf.format(calendar.getTime());
but result is not in correct time zone (+8 hours). What could be the problem?
Unless you are going to perform Date/Time related calculations, there is no point in instantiating Calendar with given TimeZone. After calling Calendar's getTime() method, you will receive Date object, which is timezone-less either way (GMT based, actually).
What you need to do, is to set TimeZone for formatter instead. And also do not bother with passing your own format, there is a built-in already:
// get current time
// you could just as well use Date now = new Date();
Calendar now = Calendar.getInstance();
// Locale for formatter
Locale malaysianLocale = new Locale("ms", "MY");
// Default date and time format for Malaysia
DateFormat defaultMalaysianFormatter = DateFormat.getDateTimeInstance(
DateFormat.DEFAULT, DateFormat.DEFAULT, malaysianLocale);
// This step is crucial
TimeZone malaysianTimeZone = TimeZone.getTimeZone("Asia/Kuala_Lumpur");
defaultMalaysianFormatter.setTimeZone(malaysianTimeZone);
System.out.println(defaultMalaysianFormatter.format(now.getTime()));
This prints something like 10 Mei 2011 2:30:05 AM, which I believe is your desired result.
Time zone id should be set as Asia/Kuala_Lumpur. Date.toString() always returns time string using default time zone. But your default time zone is different.
Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("Asia/Kuala_Lumpur"));
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, tzCal.get(Calendar.YEAR));
cal.set(Calendar.MONTH, tzCal.get(Calendar.MONTH));
cal.set(Calendar.DAY_OF_MONTH, tzCal.get(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, tzCal.get(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, tzCal.get(Calendar.MINUTE));
cal.set(Calendar.SECOND, tzCal.get(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, tzCal.get(Calendar.MILLISECOND));
System.out.println("Current Time = " + sdf.format(cal.getTime()));
The TimeZone.getTimeZone() call is incorrect. You have to pass a the correct identifier.
EDIT -- You can try to getAvailableIDs() and iterate through them to make sure you have the correct id.
If you've read the javadoc of TimeZone carefully, the way to use getTimeZone is:
TimeZone.getTimeZone("GMT-8")
or
TimeZone.getTimeZone("GMT+8")
tl;dr
java.time.ZonedDateTime.now(
ZoneId.of( "Asia/Kuala_Lumpur" )
).toString()
2018-01-23T18:48:32.263+08:00[Asia/Kuala_Lumpur]
Avoid legacy classes
The Question and other Answers use troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
java.time
The modern approach uses java.time classes. Forget all about the terribly confusing Calendar class.
Current moment
First get the current moment in UTC. 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.now() ;
Time zone
Adjust into another time zone.
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 pseudo-zones such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Asia/Kuala_Lumpur" ) ; // Or "Asia/Kuching", etc.
Apply the ZoneId to instantiate a ZonedDateTime object. Both the ZonedDateTime and Instant represent the same moment, the very same point on the timeline, but is viewed through a different wall-clock time.
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock time.
Offset
If you had only an offset-from-UTC such as +08:00 rather than a known time zone, you would use ZoneOffset to get a OffsetDateTime instead of a ZoneId & ZonedDateTime. But a time zone is always preferable to a mere offset. A zone is a history of offsets used by the people of particular region.
Strings
To generate a string in standard ISO 8601 format, call toString method.
The ZonedDateTime class wisely extends the standard by appending the time zone name in square brackets.
String output = zdt.toString() ; // YYYY-MM-DDTHH:MM:SS.SSSSSSSSS[tz]
Localize to the user’s preferences. To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( l );
String output = zdt.format( f );
Dump to console.
System.out.println( "instant.toString(): " + instant ) ;
System.out.println( "output: " + output ) ;
System.out.println( "outputLocalized (always Locale.US on IdeOne.com): " + outputLocalized ) ;
See this code run live at IdeOne.com. Note that IdeOne.com overrides any Locale setting to always use Locale.US.
instant.toString(): 2018-01-23T10:48:32.263Z
output: 2018-01-23T18:48:32.263+08:00[Asia/Kuala_Lumpur]
ooutputLocalized (always Locale.US on IdeOne.com): Tuesday, January 23, 2018 6:48:32 PM MYT
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, 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 have a GMT field in which the user enter a time to be converted to IST (for eg: in hour field 18, minute field 30, in session field am/pm). I need to get those inputs and convert to IST in java???
This is very easy and obvious if you realize that the timezone is only relevant for a date formatted as String - second/millisecond timestamps (of which java.util.Date is merely a wrapper) are always implicitly UTC (what GMT is properly called). And converting between such a timestamp and a string always uses a timezone, both ways.
So this is what you need to do:
DateFormat utcFormat = new SimpleDateFormat(patternString);
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
DateFormat indianFormat = new SimpleDateFormat(patternString);
indianFormat .setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
Date timestamp = utcFormat.parse(inputString);
String output = indianFormat.format(timestamp);
tl;dr
OffsetDateTime.of(
LocalDate.now( ZoneOffset.UTC ) ,
LocalTime.of( 18 , 30 ),
ZoneOffset.UTC
).atZoneSameInstant( ZoneId.of( "Asia/Kolkata" ) )
Details
The modern approach uses the java.time classes.
Get the current date in UTC as a LocalDate without time-of-day and without time zone or offset.
LocalDate localDate = LocalDate.now( ZoneOffset.UTC );
Specify the time per user inputs as a LocalTime without a date and without a time zone or offset.
LocalTime localTime = LocalTime.of( 18 , 30 );
Put them together with an offset-from-UTC of zero, UTC itself as the constant ZoneOffset.UTC, to get an OffsetDateTime.
OffsetDateTime odt = OffsetDateTime.of( localDate , localTime, ZoneOffset.UTC );
Apply a time zone as a ZoneId to get a ZonedDateTime for India time. Or by IST did you mean Irish Standard Time? Iran Standard Time?
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 = odt.atZoneSameInstant( z );
See this code live at IdeOne.com.
localDate.toString(): 2017-02-13
localTime.toString(): 18:30
odt.toString(): 2017-02-13T18:30Z
zdt.toString(): 2017-02-14T00:00+05:30[Asia/Kolkata]
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.
Well, joda-time is easier. Try something like this
DateTime dt = new DateTime(<year>,<month>,<day>, <hour>,<minute>, <second>, <millisecond>);
DateTime dtIST = dt.withZone(DateTimeZone.forTimeZone(TimeZone.getTimeZone("IST");
Note here that the use of the three letter abbreviation is deprecated and that time zones should be referred to like "America/Los_Angeles" refers to PST.I haven't the time to get the corrsesponding for IST right now but something should be left as an exercise to the reader!
UPDATE: As Basil Bourque states in the comments, Joda-Time is in maintenance mode. Use java.time instead.
When I add the below code, it worked for me.
DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
utcFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
DateFormat indianFormat = new SimpleDateFormat("dd-HH-mm");
utcFormat.setTimeZone(TimeZone.getTimeZone("IST"));
Date timestamp = utcFormat.parse("2019-04-26-19-00");
String istTime = indianFormat.format(timestamp);
If you'r looking for Indian TimeZone do this
"GMT+5:30"
val sdf = SimpleDateFormat("dd-MM-yyyy HH:mm:ss")
sdf.timeZone = TimeZone.getTimeZone("GMT+5:30")