Java SimpleDateFormat(yyyy-MM-dd'T'HH:mm:ss'Z') gives timezone as IST
You haven't set the timezone only added a Z
to the end of the date/time, so it will look like a GMT date/time but this doesn't change the value.
Set the timezone to GMT and it will be correct.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
Change date from MM/dd to yyyy-MM-dd'T'HH:mm:ss.SSZ in Java
In the question, the date format pattern indicates a desire for 2-digit fractional seconds. SimpleDateFormat
cannot do that.
The newer Java 8 Time API can, and you should be using that anyway.
If you're running on Java 6 or 7, get the ThreeTen-Backport library.
To parse a MM/dd
formatted string and get a full timestamp with current year and time-of-day, in the default time zone, use the following code:
String strDate = "06/05";
MonthDay monthDay = MonthDay.parse(strDate, DateTimeFormatter.ofPattern("MM/dd"));
ZonedDateTime date = ZonedDateTime.now().with(monthDay);
System.out.println(date.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSZ")));
Sample Output
2020-06-05T14:52:48.45-0400
date format yyyy-MM-ddTHH:mm:ssZ
Using UTC
ISO 8601 (MSDN datetime formats)
Console.WriteLine(DateTime.UtcNow.ToString("s") + "Z");
2009-11-13T10:39:35Z
The Z is there because
If the time is in UTC, add a 'Z'
directly after the time without a
space. 'Z' is the zone designator for
the zero UTC offset. "09:30 UTC" is
therefore represented as "09:30Z" or
"0930Z". "14:45:15 UTC" would be
"14:45:15Z" or "144515Z".
If you want to include an offset
int hours = TimeZoneInfo.Local.BaseUtcOffset.Hours;
string offset = string.Format("{0}{1}",((hours >0)? "+" :""),hours.ToString("00"));
string isoformat = DateTime.Now.ToString("s") + offset;
Console.WriteLine(isoformat);
Two things to note: + or - is needed after the time but obviously + doesn't show on positive numbers. According to wikipedia the offset can be in +hh format or +hh:mm. I've kept to just hours.
As far as I know, RFC1123 (HTTP date, the "u" formatter) isn't meant to give time zone offsets. All times are intended to be GMT/UTC.
Understanding specific UTC time format YYYY-MM-DDTHH:MM:SS.SSSZ
Firstly please have a read of the iso8601 information. It's becoming more common place to deal with times in different time zones (e.g. server time zone and client time zone) and the standard is really useful.
In particular please read about UTC or "Zulu" time here.
The program is correct, since the London time is one hour ahead of "UTC" time in summer
The trailing 'Z' is a short notation for UTC (Zulu). You could also write "+00:00" instead of 'Z'. The SS.SSS refer to seconds and milliseconds - not related to the time zone. In devnull's comment he shows you how to apply an offset for summer.
Edit:
There's been some discussion in the comments about whether iso8601 timezone includes timezone or not, and whether timezone will in fact be printed out.
This depends completely on the date/time implementation. If we are using SimpleDateFormat
then timezone is supported and will be printed.
Here's a code example to illustrate
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(formatter.format(new Date()));
formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(formatter.format(new Date()));
Output
2016-06-02T12:53:14.924Z
2016-06-02T13:53:14.925+01:00
Naturally, if you are using a different date/time library such as joda-time
, then the implentation details will be different.
Edit: As @DerrylThomas pointed out with SimpleDateFormat
wise to use lower case y for years - unless it's intended to use week year - explained in a bit of detail in another answer to a similar question https://stackoverflow.com/a/56911450.
Python 3 How to format to yyyy-mm-ddThh:mm:ssZ
Try datetime
library
import datetime
output_date = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
print(output_date)
For more information, refer to the Python Documentation.
Why I can't parse this date format yyyy-MM-dd'T'HH:mm:ss.SSSZ?
You should use Z
the same way you use T
for the parser to recognize the character in format
val stringDate = "2021-12-16T16:42:00.000Z"
val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
var consultationDate = sdf.parse(stringDate)
Not able to understand YYYY-MM-DDTHH:MM:SS date format
LocalDateTime dateTime = LocalDateTime.parse("2018-01-30T23:59:59.000");
System.out.println(dateTime);
This prints:
2018-01-30T23:59:59
Your string is in ISO 8601 format. UTC or Coordinated Universal Time is not a format, it is a standard time used to define the time the rest of use in our respective time zones.
The date-time classes you were using, SimpleDateFormat
and Date
, are long outdated and the former in particular notoriously troublesome. I recommend that you instead use java.time
, the modern Java date and time API. It is so much nicer to work with.
A LocalDateTime
is a date with time of day and without time zone or offset from UTC. Its one-argument parse
method parses ISO 8601, which is why no explicit formatter is needed.
What went wrong in your code
Your format pattern string has a number of issues to it. Which is one reason why you should appreciate the above solution without any explicit formatter. The first thing that goes wrong is: Your format pattern string has a colon, :
, between seconds and milliseconds, whereas your date-time string has a dot, .
. This is why you get the exception.
However, fixing this, your code yields the following Date
:
Sun Dec 31 23:00:00 CET 2017
It’s one month off from the expected, and the minutes and seconds are missing. Because:
- Uppercase
YYYY
is for week-based year and only useful with a week number. You need lowercaseyyyy
for year. - Uppercase
DD
is for day of year. You need lowercasedd
for day of month. - You correctly used uppercase
MM
for month. Trying the same again for minutes won’t work. Maybe you can guess by now: it’s lowercasemm
. - Not surprising you need lowercase
ss
for seconds. - Using
MS
for milliseconds is interesting.SimpleDateFormat
takes it asM
for month (which we’ve already had twice before) and uppercaseS
for millisecond. Instead you needed uppercaseSSS
for the three digits of milliseconds.
Links
- Oracle tutorial: Date Time explaining how to use
java.time
. - Wikipedia article: ISO 8601
- Wikipedia article: Coordinated Universal Time on UTC
Java format yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ss
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
SimpleDateFormat output = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(time);
String formattedTime = output.format(d);
This works. You have to use two SimpleDateFormats, one for input and one for output, but it will give you just what you are wanting.
Related Topics
Adding Images into Excel Using Epplus
Sqlparameter Does Not Allows Table Name - Other Options Without SQL Injection Attack
Struggling Trying to Get Cookie Out of Response with Httpclient in .Net 4.5
Open File Dialog and Select a File Using Wpf Controls and C#
Selectively Suppress Custom Obsolete Warnings
Who Should Call Dispose on Idisposable Objects When Passed into Another Object
C# Native Host with Chrome Native Messaging
When Is Optimization Premature
How to Pass Values Between Forms in C# Windows Application
How to Implement Gzip Compression in ASP.NET
What Does Default(Object); Do in C#
Display Progress Bar While Doing Some Work in C#
C# Generic "Where Constraint" with "Any Generic Type" Definition