I have an android app that receives a string in this format:"MM-dd-yyyy HH:mm:ss" from my server. I want to convert this string to a Date object with UTC as timezone since the time in the string is UTC. I've already checked several similar questions but didn't find my answer
Here is what I'm using currently:
SimpleDateFormat format = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
Date date = new Date();
try {
date = format.parse(itemContent [3]);
entity.setValidTill(date);
}catch (Exception e){
}
But what it does when I print that date with Log is show it as:
Sun Aug 27 15:00:00 GMT+04:00 2017
I want it to be:
Sun Aug 27 15:00:00 GMT 00:00 2017
So here is the main question how to get DateTime for UTC using a string with format as above?
Edit:
Just put it in a better context. I'm trying to get users to see the difference between current datetime & the that datetime saved in server. So my solution was to get gmt time for users & compare with the server time(which is gmt) so everyone see same difference regardless of their timezone. With C# you can get DateTime.UtcNow while with java I couldn't find an alternative
Briefly, as your Question is really a duplicate of many others…
You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
Parse your input string as a LocalDateTime as it lacks any indicator of offset-from-UTC or time zone.
Define a formatter to parse your input string.
String input = "08-27-2017 15:00:00" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
ldt.toString(): 2017-08-27T15:00
A LocalDateTime is not a moment on the timeline, only a rough idea about a range of possible moments. Has no meaning without the context of an offset (or time zone).
If you are certain that input was intended for UTC, assign the constant ZoneOffset.UTC for a OffsetDateTime.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
odt.toString(): 2017-08-27T15:00Z
To calculate a delta between that moment and the current moment, use the Period class for coarser granularity in your span of time, or Duration for finer granularity. Both classes generate strings in standard ISO 8601 format of PnYnMnDTnHnMnS.
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC ) ;
Duration d = Duration.between( odt , now ) ;
now.toString(): 2017-08-27T21:16:56.396Z
d.toString(): PT6H16M56.396S
See this code run live at IdeOne.com.
In the standard strings seen above, the Z is short for Zulu and means UTC.
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….
just add this code under the first line of your code:
format.setTimeZone(TimeZone.getTimeZone("UTC"));
Related
I'm a beginner in android development and I've been searching for hours to find an answer for my question but I didn't really understand anything I found.
The match between 2 teams is starting at 20:00 gmt and I want to make it + - based on the area. For example in germany +1 gmt the time should be 21:00. I only want the hours and minutes format like that.
tl;dr
OffsetDateTime
.of(
LocalDate.of( 2021 , Month.MARCH , 23 ) ,
LocalTime.of( 20 , 0 ) ,
ZoneOffset.UTC
) // Returns a `OffsetDateTime` object.
.atZoneSameInstant(
ZoneId.of( "Europe/Berlin" )
) // Returns a `ZonedDateTime` object.
.toLocalTime() // Returns a `LocalTime` object.
.toString() // Returns a `String` object, with text in standard ISO 8601 format.
21:00
Details
Location does not necessarily correlate to time zone. Users choose their time zone as a preference. Servers should generally be set to UTC (an offset of zero). You can get the JVM’s current default time zone by calling ZoneId.systemDefault. If crucial, you should explicitly ask the user to confirm their desired zone.
I only want the hours and minutes format like that.
Date-time objects are not text, and do not have a "format". Think in terms of the logic needed for handling date-time values rather than in terms of manipulating strings.
starting at 20:00 gmt and I want to make it + - based on the area
Representing that 8 PM in UTC (the new GMT):
LocalDate tomorrow = LocalDate.now( ZoneOffset.UTC ).plusDays( 1 ) ;
LocalTime eightPM = LocalTime.of( 20 , 0 ) ;
OffsetDateTime odt = OffsetDateTime.of( tomorrow , eightPM , ZoneOffset.UTC ) ;
For example in germany +1 gmt the time should be 21:00
Define your desired time zone.
ZoneId z = ZoneId.of( "Europe/Berlin" ) ;
Adjust from the OffsetDateTime to a ZonedDateTime.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
See that code run live at IdeOne.com.
odt.toString(): 2021-02-17T20:00Z
zdt.toString(): 2021-02-17T21:00+01:00[Europe/Berlin]
The odt & zdt objects seen here both refer to the very same simultaneous moment, the same point on the timeline.
This has all been covered many times before on Stack Overflow. Search to learn more.
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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. Hibernate 5 & JPA 2.2 support java.time.
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 brought 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 (26+) bundle implementations of the java.time classes.
For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
It's not Android specific but just a general question about Java.
Use Calendar and SimpleDateFormat like this:
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
calendar.set(2021, 1, 16, 20, 00, 00); // 2021-02-16T20:00:00 GMT
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+01:00"));
System.out.println(simpleDateFormat.format(calendar.getTime()));
Set (input) your date as GMT. Then format it GMT+01:00 with SimpleDateFormat and print (output) it.
I am trying to convert UTC time to user's Locale time. However, I am getting back the same UTC time.
Apparently, setting the time zone to locale/default does not work.
Another method seems to be available using Instant, but requires API level 26.
This is my input date in string: "2020-01-16T19:44:48.303+0000".
I am expecting to have the date and time in this format: "M/dd/yy - h:mm aa"
private String toLocaleTime(String timeStr){
// Date date;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'+0000'");
simpleDateFormat.setTimeZone(TimeZone.getDefault());
String localeTime = "";
try {
//date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).parse(timeStr);
localeTime = simpleDateFormat.format(simpleDateFormat.parse(timeStr));
} catch (ParseException e) {
e.printStackTrace();
}
//String str = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US).format(date);
Log.d("LocaleTime", ""+ localeTime);
return localeTime;
}
java.time
A Locale has nothing to do with the content of a date-time object. A locale only comes into the picture when generating text to represent the value of the date-time object. I suspect your intention is to adjust from an offset-from-UTC of hours-minutes-seconds to the wall-clock time used by the people of a particular region (a time zone).
Never use SimoleDateFormat or Date or Calendar. These terrible date-time classes were supplanted by java.time years ago. For Android before 26, add the ThreeTenABP library to your project.
This is my input date in string: "2020-01-16T19:44:48.303+0000"
Tip: The java.time classes and other date-time frameworks work better if you include the colon character between the hours and seconds in the offset: +00:00.
If all your inputs have the same offset, replace that part of the string.
String input = "2020-01-16T19:44:48.303+0000".replace( "+0000" , "+00:00" ) ;
Parse as an Instant, a moment in UTC.
Instant instant = Instant.parse( input ) ;
Generate a string in your desired format. Do you really want one-digit month with two digit day? And one digit hour with two digit minute?
DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/dd/uu - h:mm a" ).withLocale( locale ) ;
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
String output = instant.atZone( z ).format( z ) ;
I suggest you instead let java.time automatically localize for you with DateTimeFormatter.ofLocalizedDateTime.
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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….
You tell the parsing date formatter to parse using UTC time zone, the tell the formatting date formatter to format using the default time zone (by not telling it anything):
String input = "2020-01-16T19:44:48.303+0000";
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'+0000'");
inputFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = inputFormat.parse(input);
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
// Not needed: outputFormat.setTimeZone(TimeZone.getDefault());
String output = outputFormat.format(date);
System.out.println("input: " + input);
System.out.println("output: " + output);
System.out.println(new SimpleDateFormat("zzzz XX").format(date));
Output
input: 2020-01-16T19:44:48.303+0000
output: 2020-01-16T14:44:48.303
Eastern Standard Time -0500
I have a date time value 2016-12-21T07:48:36 with an offset of UTC+14. How to convert the datetime into equivalent standard GMT time.
I tried with sampleDateFormat.parse() method.But, I am not able to get the TimeZone object for UTC offset like.
sampleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC+14:00"))
Please help me to convert the UTC datetime into standard GMT time in Java 7.
I will assume you have the original date as a string. Do the following:
Create a SimpleDateFormat and set the timezone to "GMT+14"
Parse the string value. You get a Date object
Set the timezone of the SimpleDateFormat to "UTC" (or use a different SimpleDateFormat instance)
Format the date (if you want the result as a string as well)
Example:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class ConvertToUTC {
public static void main(String[] args) throws Exception {
String dateval = "2016-12-21T07:48:36";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("GMT+14"));
Date date = df.parse(dateval);
System.out.println(df.format(date)); // GMT+14
df.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(df.format(date)); // UTC
}
}
use "GMT+14:00" instead of "UTC+14:00"
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("GMT+14:00"));
final Date d = f.parse("2016-12-21T07:48:36");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(d)); // -> 2016-12-20T05:48:36
tl;dr
LocalDateTime.parse( "2016-12-21T07:48:36" ) // Parse as a `LocalDateTime` given the lack of an offset or zone. *Not* an actual moment, only a rough approximation of potential moments along a range of about 26-27 hours.
.atOffset( ZoneOffset.ofHours( 14 ) ) // Assign an offset-from-UTC as context, giving meaning to determine an actual point on the timeline.
.toInstant() // Renders `Instant` object in UTC.
java.time
The modern way is with the java.time classes built into Java 8 and later. Much of the functionality is back-ported to Java 6 & 7 in the ThreeTen-Backport project.
ZoneOffset offset = ZoneOffset.ofHours( 14 ); // fourteen hours ahead of UTC.
Parse the string as a LocalDateTime as it lacks any info about offset or zone. Your input is in standard ISO 8601 format, so no need to specify a formatting pattern.
LocalDateTime ldt = LocalDateTime.parse( "2016-12-21T07:48:36" );
Apply the offset to the local date-time to get an OffsetDateTime an object.
OffsetDateTime odt = ldt.atOffset( offset );
From that, extract an Instant which is always in UTC.
Instant instant = odt.toInstant();
instant.toString(): 2016-12-20T17:48:36Z
In UTC, the value is a different date, the 20th instead of 21st.
See live code at IdeOne.com.
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.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor 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 used the below code where I've printed the modified GMT date in String & in Date format, it's giving me two different values.
Date initial = new Date();
DateFormat dateFormatter = DateFormat.getInstance();
dateFormatter.setTimeZone (TimeZone.getTimeZone("UTC"));
String gmtS = dateFormatter.format(initial);
Date gmt = dateFormatter.parse(gmtS);
System.out.println("Data type is Date = " + gmt);
System.out.println("Data type is String "+gmtS);
Output
gtm where value id of type Date = Thu Jul 03 23:15:00 EDT 2014
gmtS where value id of type String = 7/4/14 3:15 AM
But I want to see the value (7/4/14 3:15 AM) as a Date type.
Any help is really appreciated.
When you output a Date by calling toString() (which is what System.out.println("Data type is Date = " + gmt); does) you will get that Date according to the system time zone, because that is what Date.toString() returns.
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
where:
...
zzz is the time zone (and may reflect daylight saving time). Standard time
zone abbreviations include those recognized by the method parse. If time
zone information is not available, then zzz is empty - that is, it
consists of no characters at all.
So, to get the output you expect use your dateFormatter to format it again.
String gmtS = dateFormatter.format(initial);
Date gmt = dateFormatter.parse(gmtS);
System.out.println("Data type is Date = " + dateFormatter.format(gmt));
tl;dr
Instant.now().toString()
2019-02-07T19:15:29.123456Z
Avoid legacy date-time classes
You are using date-time classes that are terribly troublesome, with many flaws in design.
First, you should know that java.util.Date represents a moment in UTC, always in UTC by definition. But its toString method tells a lie, dynamically applying the JVM’s current default time zone while generating the text representing the moment in the Date object.
java.time
The modern approach uses the java.time classes.
Instant
For a moment in UTC, use Instant. Like java.time.Date it represents a moment always in UTC (but with a finer resolution of nanoseconds versus milliseconds). Indeed, you can convert easily back-and-forth between Date and Instant by using new methods added to the old class.
Unlike toString on Date, the toString method on Instant always tells the truth. The method generates text in standard ISO 8601 format. The T in the middle separates the date portion from the time portion. The Z on the end is short for UTC and is pronounced “Zulu”.
Instant.now().toString(): 2019-01-23T12:34:56.123456789Z
OffsetDateTime
The Instant class is a basic building-block class in java.time, with limited functionality. If you want more flexible formatting, use the OffsetDateTime class with the offset set to UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Or skip the Instant class.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
To generate text representing the value of the OffsetDateTime object, use the DateTimeFormatter class. Search Stack Overflow as this has been covered many many times already.
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.
Hi I am coding the following:
String sph=(String) android.text.format.DateFormat.format("yyyy-MM-dd_hh-mm-ss_SSS", new java.util.Date());
I want the current date and time and milliseconds
what it gives me is:
2011-09-01_09-55-03-SSS
The SSS is not converting back to milliseconds...
Does anyone know why and what should it be to get the milliseconds in 3 position?
Thanks
Use the following:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss_SSS");
String dateString = formatter.format(new java.util.Date());
tl;dr
ZonedDateTime // Represent a moment in the wall-clock time used by the people of a certain region (a time zone).
.now() // Capture current moment. Better to pass optional argument for `ZoneId` (time zone). Returns a `ZonedDateTime` object.
.format( // Generate a `String` with text in a custom formatting pattern.
DateTimeFormatter.ofPattern( "uuuu-MM-dd_HH-mm-ss-SSS" )
) // Returns a `String` object.
2018-08-26_15-43-24-895
Instant
You are using troublesome old legacy date-time classes. Instead use the java.time classes.
If you want the date-time in UTC, use the Instant class. This class holds nanosecond resolution, more than enough for milliseconds.
Instant instant = Instant.now();
String output = instant.toString();
That toString method uses the DateTimeFormatter.ISO_INSTANT formatter which prints 0, 3, 6, or 9 digits in the decimal fraction, as many as needed appropriate to the actual data value.
In Java 8 the current moment is captured only up to milliseconds but a new implementation of Clock in Java 9 may capture up to nanoseconds. So truncate to milliseconds if that is your requirement. Specify your desired truncation by a TemporalUnit as implemented in ChronoUnit.MILLIS.
Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS );
ZonedDateTime
If you want a specify time zone, apply a ZoneId to get a ZonedDateTime.
Instant instant = Instant.now();
instant.toString(): 2018-08-26T19:43:24.895621Z
Instant instantTruncated = instant.truncatedTo( ChronoUnit.MILLIS );
instantTruncated.toString(): 2018-08-26T19:43:24.895Z
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
String output = zdt.toString();
2018-08-26T15:43:24.895621-04:00[America/Montreal]
Again if you want other formats, search Stack Overflow for DateTimeFormatter.
DateTimeFormatter
If you want to force three digits for milliseconds, even if the value is all zeros, specify a custom formatting pattern using DateTimeFormatter class.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd_HH-mm-ss-SSS" ) ;
String output = zdt.format( f ) ;
2018-08-26_15-43-24-895
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
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….
Try using the same format with SimpleDateFormat