DateFormat parse - not return date in UTC
Excuse me for mentioning it, I suspect that there is no problem in your code, there’s only confusion. If you think the old Date
class is behaving confusingly, allow me to be the first of many to agree with you. The good and sound solution to this problem is you stop using Date
and start using the modern Java date and time API instead.
Since you are coding for Android, you first step is to get the ThreeTenABP, the library for Android that offers the modern API (if you were using Java 8 or 9, you could skip this step since the modern API wold be built in). The details are described in this question: How to use ThreeTenABP in Android Project. Now you can do:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss Z");
String dateUTCAsString = "2017-11-15T12:54:25 +0000";
Instant dateResult = OffsetDateTime.parse(dateUTCAsString, formatter).toInstant();
System.out.println(dateResult);
On my computer this just printed:
2017-11-15T12:54:25Z
The Z
at the end means Zulu time zone or UTC.
As you may know, System.out.println(dateResult)
implicitly calls the toString
method of the dateResult
object. Objects of the class Instant
produce the above format, always in UTC, as I understood you wanted. The Instant
class is the natural replacement for the old-fashioned Date
class for most purposes. Internally the Instant
holds the number of seconds and nanoseconds since the epoch, which is defined as January 1 1970 at 0:00 midnight UTC. I encourage you to consider this an irrelevant implementation detail. An Instant
is a point on the time-line.
What went wrong?
You asked for a date in UTC. Depending on how you look at it, you can or cannot have this.
- On one hand a
Date
is implemented as the number of seconds and milliseconds since the epoch, so if you use the above definition of the epoch, you may say that it is always in UTC. - On the other hand you shouldn’t worry about implementation details. Conceptually a
Date
(like anInstant
) is a point on the time-line, and does not and cannot have a time zone or offset; it cannot be in UTC. To make matters more confusing, when you do"getCurrentDateUTC: dateResult = " + dateResult
, thendateResult.toString()
is implicitly called. This method grabs your JVM’s time zone setting and converts the date-time to this zone and uses it for the generated string (without modifying theDate
object). This is why you will see the time in EET on your computer or device no matter whichDate
you try to print.
java.time
or JSR-310
The modern date and time API is know as java.time
or JSR-310. One good source for learning to use it is the Oracle tutorial.
DateFormat format method doesn't display a parsed date to a particular TimeZone
There are two different topics here; parsing and formatting.
1. Parsing
SimpleDateFormat.parse()
will try to parse the timezone from the supplied date string. If the date string you are parsing does not include an explicit timezone, then the "default" timezone on the SimpleDateFormat
object will be used. You can set the default time zone with the setTimeZone()
method. Please see the API docs for SimpleDateFormat.parse()
and DateFormat.setTimeZone()
for reference.
Here is an example that shows how the parsing is influenced by the timezone set with setTimeZone()
:
String dateString = "2015.12.10 13:58:18";
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
sdf1.setTimeZone(TimeZone.getTimeZone("GMT"));
Date date1 = sdf1.parse(dateString);
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
sdf2.setTimeZone(TimeZone.getTimeZone("EST"));
Date date2 = sdf2.parse(dateString);
// Shows that the parsing honours time zone -- will print:
// Thu Dec 10 14:58:18 CET 2015 (original date was parsed as GMT)
// Thu Dec 10 19:58:18 CET 2015 (original date was parsed as EST)
System.out.println(date1);
System.out.println(date2);
2. Formatting
Assuming that the date has been parsed correctly, then your problem is with the formatting. You need to set the timezone for the actual SimpleDateFormat
object that you are using for formatting. I modified your code to do this and it will now print what you expet:
Calendar cal = Calendar.getInstance();
cal.setTime(alreadyParsedDateTime);
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
sdf3.setTimeZone(TimeZone.getTimeZone("UTC"));
// Prints: 2015-12-23T23:00:00 for your example date string
System.out.println(sdf3.format(cal.getTime()));
How to parse a UTC offset dateformat string into the resulting date separated by | symbol
Your String 2019-12-25T17:00:00-05:00
represents UTC
timezone with offset UTC offset, so use OffsetDateTime
for parsing that string
OffsetDateTime odt = OffsetDateTime.parse("2019-12-25T17:00:00-05:00");
System.out.println(odt.format(DateTimeFormatter.ofPattern("MMM d | E | hh:mm a", Locale.US)));
If you want to set particular time zone you can use atZoneSameInstant
to pass ZoneId
for eaxmple
ZoneId zone = ZoneId.of("America/Chicago");
ZonedDateTime zdt = odt.atZoneSameInstant(zone);
Java Can't Parse UTC Date with SimpleDateFormat
This date:
"2014-01-09T17:10:14Z"
has a format of"yyyy-MM-dd'T'HH:mm:ss'Z'"
(or in Java 7 "yyyy-MM-dd'T'HH:mm:ssX"
)
So of course it will be impossible to parse it with a format dd-MM-yyyy
.
The formatting string needs to be compatible with the input!
(Note I gave a literal Z, this is back compatible. Java 7 actually understands ISO8601 and you could use an X there to have it actually be parsed.)
SimpleDateFormat with timezone displaying dates in my timezone, how do I fix this?
You can use the modern java.time package instead and specially ZonedDateTime
that handles time zones.
String str = "2019-12-20T00:00:00.000-05:00";
ZonedDateTime zonedDateTime = ZonedDateTime.parse(str);
And when showing it in the UI use DateTimeFormatter
to convert it to a formatted string
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
or with some custom format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
which will give you for the 2 formats
System.out.println(formatter.format(zonedDateTime));
2019-12-20T00:00-05:00
2019-12-20 00:00
Java SimpleDateFormat interpret parse-string as UTC
My assumption was wrong,
22.09.1985 00:00UTC is actually 22.09.1985 02:00CET
so
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date d = sdf.parse("22/09/1985");
is exactly what i wanted, the date i compared it with was wrong.
Parsing datetime to UTC
Thank you guys for your help that's what i wonted i turn out that if the date in UTC you should start with parsing in the utc format that will keep the date as its the for formating it to your local timezone format it with local time zone
private String getDate(String dateString) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Date value = null;
try {
value = formatter.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
SimpleDateFormat dateFormatter = new SimpleDateFormat("hh:mm aa");
dateFormatter.setTimeZone(TimeZone.getDefault());
String dt = dateFormatter.format(value);
return dt;
}
Related Topics
How to Read Jpeg Image Using Imageio.Read(File File)
Why Doesn't Java Throw an Exception When Dividing by 0.0
Java, Find Intersection of Two Arrays
Private Final Static Attribute VS Private Final Attribute
Differencebetween ? and Object in Java Generics
How to Clear the (Css) Visited History of an Android Webview
Map.Clear() VS New Map:Which One Will Be Better
Hosting an Executable Within Android Application
Best Way to Implement View.Onclicklistener in Android
How to Change Text of a Textview in Navigation Drawer Header
Does Glide Have a Method for Loading Both Png and Svg
How to Hash a String in Android
Android Telegram App --> Java.Lang.Unsatisfiedlinkerror: No Implementation Found for Void
How to Access Downloads Folder in Android
Disable Ssl Certificate Check in Retrofit Library
Android Geocoder Getfromlocationname Always Returns Null