The time I am getting from Android phone is
"Mon May 9 09:34:13 CDT 2016\r\r\n" but after parsing the same date using date format SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy",Locale.US);
After parsing it gives me a date into the
"Mon May 09 20:04:56 IST 2016".
It clearly shows that the hours is increase by 11 hours.
How to address this issue, Could anybody help me?
tl;dr
Your India time is correctly adjusted 10.5 hours ahead of Chicago time. Feature, not a bug. (I am assuming your :56 seconds was a typo in your Question.)
If you want no such adjustment, but instead want the same date and same time-of-day assigned to a different time zone, then do this:
ZonedDateTime.parse(
"Mon May 9 09:34:13 CDT 2016" , // If at all possible, avoid using such an awful format for exchanging date-time strings. Always use standard ISO 8601 formats instead.
DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" )
) // Returns a `ZonedDateTime` object.
.withZoneSameLocal(
ZoneId.of( "Asia/Kolkata" )
) // Returns a fresh `ZonedDateTime` object, with values based on the original but for the change in assigned zone.
.toString() // Generates a String is standard ISO 8601 format, extending the standard by appending the name of the time zone in square brackets.
2016-05-09T09:34:13+05:30[Asia/Kolkata]
We get the same date and same time-of-day, but a different offset-from-UTC means this is a different moment, a different point on the timeline.
Correct values
[Note: I am assuming the :56 in your Mon May 09 20:04:56 IST 2016 was a typo, and should have been :13. ]
The strings Mon May 9 09:34:13 CDT 2016 and Mon May 09 20:04:13 IST 2016 represent the same moment. This is a feature, not a bug. If by CDT you mean a time zone such as America/Chicago, that value on that date represents a moment five hours behind UTC, -05:00. If by IST, you mean a time zone such as Asia/Kolkata, India on that date is five and a half hours ahead of UTC, +05:30. Add those offsets together, and we get a difference of ten and a half hours. This fits: 09:34:13 plus 10.5 hours is 20:04:13.
In other words, if someone in Chicago is talking to someone in Kolkata on the telephone, if they both look up at the time on the clock on their own wall, one will see 09:34:13 while the other sees 20:04:13.
Perhaps you wanted to purposely not adjust for time zone, but re-create the same date with the same time-of-day but in a different time zone. This would not be the same moment, this would a different point on the timeline. See below for such code.
java.time
You are using troublesome old classes that were supplanted long ago by the modern java.time classes.
When possible, avoid manipulating strings as a way of handling date-time. Instead, use smart objects, not dumb strings.
Instant instant = Instant.now() ; // Capture current moment in UTC.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, but different wall-clock time.
If you must exchange date-time values as text, use standard ISO 8601 formats rather than formats such as seen in your Question.
Also, never use the 3-4 letter pseudo-time-zones such as CDT or IST. These are not true time zones, are not standardized, and many are not unique(!). Use full time zone names is the IANA-specified Continent/Region format.
But to your Question directly, parsing the string Mon May 9 09:34:13 CDT 2016. Define a formatting pattern to match.
String input = "Mon May 9 09:34:13 CDT 2016";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
zdt.toString(): 2016-05-09T09:34:13-05:00[America/Chicago]
ZonedDateTime::withZoneSameInstant
Adjust into India time.
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata );
zdtKolkata.toString(): 2016-05-09T20:04:13+05:30[Asia/Kolkata]
Same behavior as you saw with the legacy classes. Adding 10.5 hours to 09:34:13 gets us 20:04:13. Same moment, same point on the timeline, but different wall-clock time.
ZonedDateTime::withZoneSameLocal
But what if you want the same date and same time-of-day, but switch out the time zone? This would result in a different moment, different points on the timeline (assuming the two zones don’t share the same offset). The ZonedDateTime does support this manipulation via the ZonedDateTime::withZoneSameLocal(ZoneId zone) method.
ZonedDateTime zdtSameLocalKolkata = zdt.withZoneSameLocal( zKolkata );
zdtSameLocalKolkata.toString(): 2016-05-09T09:34:13+05:30[Asia/Kolkata]
Now we see the time-of-day unchanged, still 09:34:13. But the offset-from-UTC is different than Chicago, so we know this does not represent the same moment.
You can verify the fact they are different moments by adjusting both into UTC. The easy way to make that adjustment is to extract Instant object. An Instant is always in UTC by definition.
Instant instantOfZdtChicago = zdt.toInstant() ;
Instant instantOfZdtSameLocalKolkata = zdtSameLocalKolkata.toInstant():
instantOfZdtChicago.toString(): 2016-05-09T14:34:13Z
instantOfZdtSameLocalKolkata.toString(): 2016-05-09T04:04:13Z
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….
Don't forget Date class is a class with no format at all....
if you want to print a date you need to use the format method of the intenace you created...
example:
public static void main(String[] args) throws ParseException {
String myDate = "Mon May 9 09:34:13 CDT 2016";
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
Date d = dateFormat.parse(myDate);
System.out.println(d); // this is not formatted printing Mon May 09 16:34:13 CEST 2016
System.out.println(dateFormat.format(d)); // this is printed using the same format you use above
}
Related
I am trying to convert a UTC string to just the hours and the minutes. I get the UTC string from an API but have given an example below of what it looks like.
When it gets to someDate it throws an Unparseable Date error and references the string setString.
Can anyone see what I am doing wrong here?
Example of how I am getting the date from UTC
String utcStr = "1521698232";
Date setSunrise = new Date(Long.parseLong(sunrise)*1000);
Trying to convert it to HH:mm
String setString = "Thu Mar 22 05:57:06 GMT+00:00 2018";
Date someDate = new SimpleDateFormat("EEE MMM d HH:mm:ss z'+00:00' yyyy").parse(setString);
Date printDate = new SimpleDateFormat("hh:mm").format(someDate);
tl;dr
You are working too hard, going in a roundabout manner. Also, you are using troublesome old obsolete classes. Also, I suspect you are ignoring the crucial issue of time zone.
Here is a much simpler and cleaner modern solution, with consideration for time zone.
Instant.ofEpochSecond( // Represent a moment in time in UTC, with a resolution of nanoseconds.
Long.parseLong( "1521698232" ) // Count of whole seconds since epoch of 1970-01-01T00:00:Z.
) // Returns a `Instant` object.
.atZone( // Apply a time zone (`ZoneId`) to adjust from UTC to the wall-clock time of the target audience.
ZoneId.of( "Asia/Kolkata" ) // Use only proper time zone names `continent/region`. Never use 3-4 letter codes such as `IST` or `EST`.
) // Produces a `ZonedDateTime` object.
.toLocalTime() // Extract only the time-of-day as a `LocalTime` object.
.truncatedTo( ChronoUnit.MINUTES ) // Lop off any seconds and fractional second.
.toString() // Generate a String in standard ISO 8601 format: HH:MM:SS.SSSSSSSSS
11:27
Count-from-epoch
convert a UTC string
No such thing as a “UTC string”.
Your input seems to represent a number of whole seconds since the epoch reference of first moment of 1970 UTC, 1970-01-01T00:00Z. This is sometimes referred to as Unix Time or POSIX Time.
ISO 8601
"Thu Mar 22 05:57:06 GMT+00:00 2018";
This is a terrible format for a date-time value.
Instead use standard ISO 8601 strings when exchanging date-time values as text. The java.time classes use ISO 8601 formats by default when parsing/generating strings.
Avoid legacy date-time classes
The Date and SimpleDateFormat classes are part of the troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
Date is replaced by 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).
String input = "1521698232" ; // Count of seconds since epoch reference of 1970-01-01T00:00Z.
long secondsSinceEpoch = Long.parseLong( input ) ;
Instant instant = Instant.ofEpochSecond( secondsSinceEpoch ) ;
instant.toString(): 2018-03-22T05:57:12Z
As discussed above, the Instant (like Date) is in UTC. If you ask for the time-of-day, you'll get a time-of-day in UTC. More likely you really want the time-of-day for that moment by the wall-clock time used by people in a certain region (a time zone).
A time zone is crucial in determining a date and time-of-day. For any given moment, the date and time-of-day varies around the globe by 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( "Pacific/Auckland" ) ;
Apply that zone to adjust from UTC, producing a ZonedDateTime object.
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString(): 2018-03-22T18:57:12+13:00[Pacific/Auckland]
Now ask for the time-of-day. The resulting LocalTime objects lacks a date and lacks a time zone. It is just a time-of-day on a 24-hour clock.
LocalTime lt = zdt.toLocalTime() ;
If you only care about the hours and minutes, lop off and seconds and fractional second by truncating. Specify the level of truncation via the ChronoUnit class.
LocalTime ltTrunc = lt.truncatedTo( ChronoUnit.MINUTES ) ;
Generate a String in standard ISO 8601 format.
String output = ltTrunc.toString() ; // Generate a `String` in standard ISO 8601 format.
18:57
To generate a String in other formats, search Stack Overflow for DateTimeFormatter. You will find many discussions and examples.
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.
The +00:00 part is a UTC offset, and you can't treat as a literal (inside quotes, like you did). That's an important information, because it tells you how many hours ahead or behind UTC the date refers to (in this case, it's zero, so it's the same as UTC itself).
Another detail is that the day-of-week and month name are in English, so you should set a java.util.Locale in your class. If you don't use a locale, it'll use the JVM default and there's no guarantee that it'll always be English in all environments. If you're sure about the language used in the inputs, set the locale:
String setString = "Thu Mar 22 05:57:06 GMT+00:00 2018";
SimpleDateFormat parser = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy", Locale.ENGLISH);
Date someDate = parser.parse(setString);
For the output, 2 things:
using hh will print the hour-of-am-pm, which means values from 1 to 12. If you want the hours value from 0 to 23, use HH - this is all explained in the docs
the value of the hours will be converted to the device's default timezone, which means that not always will be the same of the input (in my case, my country is using -03:00 - 3 hours behind UTC - so the value of the hours is 2 AM.
To use the same offset in the input, you must set it in the formatter:
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
String printDate = formatter.format(someDate); // 05:57
To use java-time classes, the other answer by Basil tells you how to use this API in Android. I'd just like to add the similar code to parse your specific input:
String setString = "Thu Mar 22 05:57:06 GMT+00:00 2018";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("EEE MMM d HH:mm:ss O yyyy", Locale.ENGLISH);
OffsetDateTime odt = OffsetDateTime.parse(setString, parser);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
String printDate = formatter.format(odt);
This is my program snippet
import java.lang.Math;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class Main
{
public static void main(String[] args)
{
String dateTime = "2017-03-12 02:46:00";
// convert string to java.util.Date
try {
SimpleDateFormat e = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = e.parse(dateTime);
System.out.println(d);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
This is the output of that program
Sun Mar 12 03:46:00 PDT 2017
Expected Output
Sun Mar 12 02:46:00 PDT/PST 2017
Apparently, it is adding daylight saving time which occurs on PST at 2017-03-12 02:00:00
Few things I am bounded.
I cannot change server default timezone or anything specific to JVM
I must return back java.util.Date as final value.
Edit:
To some comment pointing me out how java.util.Date only stores long timestamp. Can you please give me a way where this function works
java.util.Date convertStringToDate(String str) {
// code to convert String to Date
}
convertStringToDate("2017-03-12 02:46:00");
should give me 2017-03-12 02:46:00 value in Date class? I don't care about what timezone it provides. It should have that value, whatever timezone it is while printing. Again my JVM is in PST.
Use java.time, not legacy date-time classes
You are using troublesome old date-time classes such as java.util.Date that are now legacy, supplanted by the java.time classes.
LocalDateTime
2016-03-12 02:46:00 value …I don't care about what timezone it provides. It should have that value, whatever timezone it is…
If you truly want to represent that date and time-of-day without regard for time zone, use the LocalDateTime class. This class purposely ignores time zone.
To parse, adjust your input string to comply with the ISO 8601 standard formats used by the java.time classes for parsing/generating strings.
String input = "2016-03-12 02:46:00".replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( input );
But beware: By ignoring time zone you lose the meaning of this date+time. Without the context of a time zone, we do not know if you mean the 2 AM in Auckland NZ, or 2 AM in Kolkata India (some hours later), or 2 AM in Paris France (more hours later), or 2 AM in Montréal Québec (still more hours later). A LocalDateTime is a rough idea about possible moments, but is not actually a point on the timeline.
ZonedDateTime
This is the output of that program Sun Mar 12 03:46:00 PDT 2017
Expected Output Sun Mar 12 02:46:00 PDT/PST 2017
Now you contradict yourself.
By including the PDT or PST with your expected output, you mean a specific moment on the timeline perceived through the lens of a particular region’s wall-clock time. This contradicts your statement that you want "2016-03-12 02:46:00" regardless of time zone. It is crucial that you understand this distinction to properly handle date-time work.
If indeed the intent of the string 2016-03-12 02:46:00 is to represent a moment in the wall-clock time of the left coast of north America (as I guess you meant by PDT), then we must parse that string firstly as a LocalDateTime as it lacks any indicator of time zone, but then immediately adjust it into a time zone to get 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 or PDT or PST as they are not true time zones, not standardized, and not even unique(!).
Here I arbitrarily chose America/Los_Angeles as the time zone, as your Question does not mention a specific time zone, only “PDT”.
String input = "2017-03-12 02:46:00".replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( input );
ZoneId z = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime zdt = ldt.atZone( z );
But it just so happens that March 12 of 2017 has an anomaly. That is the day when the craziness known as Daylight Saving Time (DST) kicks in. The clocks in much of the left coast of north America at 2 AM jump to 3 AM. There is no two o’clock hour. The day is 23 hours long rather than the usual 24 hours. So your request for 2:46 is asking for a nonexistent moment, an invalid value. The design choice in java.time to resolve this conundrum is to jump forward, following the "Spring Forward" of DST. The result is in the 3 AM hour, 03:46.
See this code run live in IdeOne.com.
input: 2017-03-12T02:46:00
ldt.toString(): 2017-03-12T02:46
zdt.toString(): 2017-03-12T03:46-07:00[America/Los_Angeles]
Note the 2 AM hour becomes the 3 AM hour in that output.
A reasonable person could make arguments for a different design choice in handling this anomaly, such as throwing an Exception. But this is how java.time works. Study the class doc and be sure you understand the behavior on this important topic.
If you want to detect such an anomaly, call toLocalDateTime on the ZonedDateTime object, and compare to the first LocalDateTime. With no anomaly, the pair of LocalDateTime objects will be equal; with an anomaly they will not be equal.
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.
I am working on a project that fetches Date/Time from backend in IST(Indian standard Time) as shown "2013-01-09T19:32:49.103+05:30". However when i parse it using following DateFormat
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
followed by parsing..
Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");
System.out.println("XYZ ==============>"+date);
its Displaying date in GMT format as output i.e
Wed Jan 09 14:02:49 GMT+00:00 2013.
I have tried it using TimeZone class as..
TimeZone timeZone=TimeZone.getTimeZone("IST");
sdf.setTimeZone(timeZone);
but no effect..
How could i get a Date class Object having Date in IST format instead of GMT...
Please provide an appropriate solution..
EDIT:
This is how Code Looks Like:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
TimeZone timeZone=TimeZone.getTimeZone("IST");
sdf.setTimeZone(timeZone);
Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");
String formattedDate=sdf.format(date);
System.out.println("XYZ ==============>"+formattedDate);
Date does not have any time zone. It is just a holder of the number of milliseconds since January 1, 1970, 00:00:00 GMT. Take the same DateFormat that you used for parsing, set IST timezone and format your date as in the following example
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
System.out.println(sdf.format(date));
output
2013-01-09T19:32:49.103+05:30
Note that XXX pattern is used for ISO 8601 time zone (-08:00) since 1.7. If you are in 1.6 try Z. See SimpleDateFormat API for details of format patterns
How could i get a Date class Object having Date in IST format instead of GMT...
You can't. Date doesn't have a format or a time zone. It simply represents a number of milliseconds since the Unix epoch of midnight on January 1st 1970 UTC. Instead, Date.toString() always uses the default time zone.
To use a specific format and time zone, use DateFormat instead of Date.toString(). You can set the time zone with DateFormat.setTimeZone() and then convert a Date to a String using DateFormat.format(). DateFormat itself has some factory methods for creation, or you can use SimpleDateFormat if you want to specify a particular pattern.
As Abu says, Joda Time is a much better date/time API than the built-in one, although for just formatting a date/time the standard library doesn't do a bad job. Just note that DateFormat and its subclasses are generally not thread-safe.
tl;dr
OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" ) // Parsed.
.toInstant() // Adjusted to UTC.
See live code in IdeOne.com.
ISO 8601
Your input string of 2013-01-09T19:32:49.103+05:30 happen to be in standard ISO 8601 format. The +05:30 at the end indicates an offset-from-UTC of five and a half hours ahead, used in India.
java.time
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes.
The java.time classes happen to use ISO 8601 formats by default when parsing/generating Strings representing date-time values. So no need to specify a formatting pattern at all.
As your input represents a moment on the timeline with an offset-from-UTC, we parse as a OffsetDateTime object.
OffsetDateTime odt = OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" );
odt.toString(): 2013-01-09T19:32:49.103+05:30
To obtain a simple object in UTC value, extract an Instant. This Instant class is a basic building-block class of java.time. 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).
You can think of OffsetDateTime as an Instant plus a ZoneOffset.
Instant instant = odt.toInstant(); // UTC.
When calling toString, a String object is generated in standard ISO 8601 format. The Z on the end is short for Zulu and means UTC.
instant.toString(): 2013-01-09T14:02:49.103Z
An Instant is limited in various ways such as when generating Strings in various formats. So you may want to work with an OffsetDateTime adjusted into UTC as its offset; an offset-of-zero, in other words. The ZoneOffset class holds a constant for UTC, ZoneOffset.UTC.
OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC );
You can also apply an offset (or time zone) to an Instant. Call atOffset or atZone.
The Instant class is the basic building-block class of java.time. Likely to be used often in your code as best practice is to do most of your work in UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.ofHoursMinutes( 5 , 30 ) );
Time zone
Note that an offset-from-UTC is not a time zone. A time zone is an offset plus a set of rules, past and present, for handling anomalies such as Daylight Saving Time (DST). So a time zone is always preferable to a mere offset if you are indeed sure of the correct 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 abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
If you know the intended time zone, apply a ZoneId to get a ZonedDateTime object. But never assume without verifying with the source of your input data. Many different zones may share a particular offset. For example, in the case of our input here, the offset +05:30 happens to be used today in both India (Asia/Kolkata) and Sri Lanka (Asia/Colombo). Those two time zones may have different rules for different anomalies in their past, present, or future.
ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );
The toString method of ZonedDateTime extends standard ISO 8601 format in a wise way by appending the name of the time zone is square brackets. In this case, [Asia/Kolkata].
zdt.toString(): 2013-01-09T19:32:49.103+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 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.
You can do this simply by use of Calender class. Please check below snippets:
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
calendar.setTimeInMillis(<--time stamp-->);
//calendar.setTime(<--date object of gmt date-->);
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy 'at' hh:mm a");
sdf.setTimeZone(TimeZone.getDefault());
String result=sdf.format(calendar.getTime());
i have made an application in which i need to perform date conversion.
Here is my code.
GregorianCalendar c = new GregorianCalendar(Locale.GERMANY);
c.set(2011, 04, 29,0,0,0);
String cdate = (String) DateFormat.format("yyyy-MM-dd HH:mm:ss", c.getTime());
Log.i(tag,cdate);
now when i check my LOG here is the output:
04-22 12:44:15.956: INFO/GridCellAdapter(30248): 2011-04-29 HH:00:00
why is the hour field not getting set. i have explicitly passed 0 when i was making the calendar object, still it is display HH in the LOG.
what could be the problem?
thank you in advance.
use lower-case hh:
String cdate = (String) DateFormat.format("yyyy-MM-dd hh:mm:ss", c.getTime());
set c.set(Calendar.HOUR_OF_DAY,0) and it should work.
Have you tried like this?
c.set(Calendar.YEAR, 2009);
c.set(Calendar.MONTH,11);
c.set(Calendar.DAY_OF_MONTH,4);
c.set(Calendar.HOUR_OF_DAY,0);
c.set(Calendar.MINUTE,0);
c.set(Calendar.SECOND,0)
tl;dr
LocalDate.of( 2011 , 4 , 29 ) // Represent April 29, 2011.
.atStartOfDay( ZoneId.of( "America/Montreal" ) ) // Determine the first moment of the day. Often 00:00:00 but not always.
.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // Generate a String representing the value of this date, using standard ISO 8601 format.
.replace( "T" , " " ) // Replace the `T` in the middle of standard ISO 8601 format with a space for readability.
Using java.time
The modern way is with the java.time classes.
If you are trying to get the first moment of the day, do not assume the time 00:00:00. Anomalies in some time zones mean the day may start at another time-of-day such as 01:00:00.
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
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( "America/Montreal" );
LocalDate today = LocalDate.now( z );
You want a specific date in your Question.
LocalDate localDate = LocalDate.of( 2011 , 4 , 29 ) ;
Apply the time zone again in determining the first moment of the day.
ZonedDateTime zdt = localDate.atStartOfDay( z ); // Determine the first moment of the day on this date for this zone.
I recommend always including an indicator of the time zone or offset-from-UTC with your date-time strings. But if you insist, you can use a DateTimeFormatter predefined in java.time that does not include zone/offset: DateTimeFormatter.ISO_LOCAL_DATE_TIME. Merely remove the T from the middle.
String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " ) ;
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
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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")