Reputation: 766
I have seen several questions like this but I can't quite get the conversion right. I want to convert a date like the following
20121116203036Z
to
2012-11-16 15:30:36
I have the following code
dateStringTime.set( year, mon-1 , day, hour, minute, second );
Date date = dateStringTime.getTime();
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("EST"));
String output = formatter.format();
return output;
which works but it gives me the below
2012-11-16 20:30:36
Any advice on how to get 15 instead of 20?
Upvotes: 2
Views: 1467
Reputation: 338171
OffsetDateTime.parse(
"20121116203036Z" ,
DateTimeFormatter.ofPattern( "yyyyMMddHHmmssX" )
).toLocalDateTime()
.toString()
.replace( "T" , " " )
The java.time classes built into Java make this easy. Avoid the troublesome old date-time classes such as Date
& DateFormat
, now legacy.
String input = "20121116203036Z";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssX" );
OffsetDateTime odt = OffsetDateTime.parse( input , f );
odt.toString(): 2012-11-16T20:30:36Z
To get your output you could define a custom DateTimeFormatter
. A lazier way is to convert to a LocalDateTime
just to lose the Z
on the end, which indicates the offset-from-UTC (Z
is short for Zulu
and means UTC). Then use toString
to generate a string in ISO 8601 format except replace the T
in the middle with a SPACE.
String output = odt.toLocalDateTime().toString().replace( "T" , " " );
2012-11-16 20:30:36
I suggest rather than using your format for such date-time values, instead use ISO 8601 standard formats. The usual format for such a value is 2016-11-16T02:45:02Z
. Note the T
in the middle separating year-month-day from hour-minute-second. Alternatively, the standard allows minimizing the use of separators, considered the “basic” version: 20161116T024502Z
but retains the T
in the middle.
The java.time classes can parse and generate the expanded versions but not the basic version.
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date
, .Calendar
, & java.text.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.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (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.
Upvotes: 1
Reputation: 4786
Your problem is that you're entering the date in the wrong timezone. When you do this
dateStringTime.set(year, month-1 , day, hour, minute, second);
you are actually entering the date using your default timezone, which is unlikely in your case to be UTC. Under the covers, the Java Date
is represented as UTC, so it will translate the date/time to UTC rather than entering directly in UTC.
Basically, it's doing the following sequence of timezone translations: EST -> UTC -> EST
If you intend to specify a date/time using UTC, you should do this:
dateStringTime.setTimeZone(TimeZone.getTimeZone("UTC"));
dateStringTime.set(year, month-1 , day, hour, minute, second);
Then you'll only be going from UTC -> EST and you should get the proper output.
Upvotes: 1
Reputation: 12334
First, your code is not formatting 'date', try this:
String output = formatter.format(date);
I also notice you are not showing us how you are creating dateStringTime
which I assumed to be a Calendar
. I noticed that the Calendar.getInstance()
method also accepts a Locale
which might affect the timezone.
My code:
Calendar dateStringTime = Calendar.getInstance();
//convert 20121116203036Z
int year = 2012;
int mon = 11;
int day = 16;
int hour = 20;
int minute = 30;
int second = 36;
dateStringTime.set( year, mon-1 , day, hour, minute, second );
Date date = dateStringTime.getTime();
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("EST"));
String output = formatter.format(date);
System.out.println(output);
My output:
2012-11-16 21:30:36
You notice that the hour is 1 hour off? That is because I'm in the Central time zone and the JVM is taking that into account when I ask for 'EST'. It thinks that the original time is in the current timezone.
what happens when you comment out
//formatter.setTimeZone(TimeZone.getTimeZone("EST"));
Upvotes: 2
Reputation:
TimeZone.getDefault() will give the runtime timezone.
If you will remove the getRawOffet value from date
, you will have the UTC.
one more step is to add/ remove the EST value from from UTC and is done the conversion
Upvotes: 1