parse exception while converting string with timezone to date - java

I am trying to parse a string with a time zone into a date format, how can I accomplish this?
I am using the code below, but I am getting a parse exception. What I am trying to do is getting the date in UTC time zone, irrespecitve of the time zone I get in the input string. Below is the code:
public class Test1
{
public static void main(String[] args) throws ParseException
{
// TODO Auto-generated method stub
String DIA_TIME1="201307111611400";
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmmssz");
Date testdate=sdf1.parse(DIA_TIME1);
System.out.println("Current System Time is: " + testdate);
}
}

You have both String date and format, for your date try:
String DIA_TIME1="20130711161140-0000";
and for the string format:
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmmssZ");
the last one is upper case Z.
Or, if ois not your intention to have a time zone, you have a spare 0 at the end.

Try this (your date does not contain timezone, it seems that you have milliseconds):
new SimpleDateFormat("yyyyMMddHHmmssS");

Related

Local to GMT and vice versa- Date and time conversion not working

I was trying to convert input date time to GMT+0 , later convert that back to its local time. Though local to GMT+0 conversion works, the later conversion-gmt to local fails!
Calendar cal=Calendar.getInstance();
cal.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println("my inputTime:"+ sdf.format(cal.getTime()));
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("gmt+0 converted time:"+ sdf.format(cal.getTime()));
//now i want to get my local time from this converted gmt+0 standard time
String standdardTimeStr=sdf.format(cal.getTime());
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date date=sdf2.parse(standdardTimeStr);
Calendar cal2= Calendar.getInstance();
cal2.setTime(date);
System.out.println("standard input time:"+ sdf2.format(cal2.getTime()));
sdf2.setTimeZone(TimeZone.getTimeZone("GMT+6")); //or Asia/Dhaka
System.out.println("gmt+6 convertedtime:"+ sdf2.format(cal2.getTime()));
And this is my output:
my inputTime:2020-07-13T15:02:16.849
gmt+0 converted time:2020-07-13T09:02:16.849
standard input time:2020-07-13T09:02:16.849 //taking upper line as input-gmt+0
gmt+6 convertedtime:2020-07-13T09:02:16.849 //this date was supposed to be same as the first date
Please point out what am I doing wrong in coding or conceptually?
Just for the case you want a solution with a modern API, see this commented example:
public static void main(String[] args) {
// provide some fix example datetime String
String dateTime = "2020-05-08T13:57:06.345";
// create the two time zones needed before
ZoneId utc = ZoneId.of("UTC"); // UTC = GMT (+0)
ZoneId local = ZoneId.systemDefault(); // the zone of your JVM / system
/*
* then parse the String which doesn't contain information about a zone
* to an object that just knows date and time
*/
LocalDateTime ldt = LocalDateTime.parse(dateTime);
// and use that to create a zone-aware object with the same date and time
ZonedDateTime utcZdt = ZonedDateTime.of(ldt, utc);
// finally adjust its date and time by changing the zone
ZonedDateTime localZdt = utcZdt.withZoneSameInstant(local);
// then print both results
System.out.println(utcZdt + "\t==\t" + localZdt);
// and maybe try to use a different output format by defining a custom formatter
DateTimeFormatter gmtStyleDtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSO");
System.out.println(utcZdt.format(gmtStyleDtf)
+ "\t==\t" + localZdt.format(gmtStyleDtf));
}
which ouputs the following lines on my system (might be different on yours due to different time zones):
2020-05-08T13:57:06.345Z[UTC] == 2020-05-08T15:57:06.345+02:00[Europe/Berlin]
2020-05-08T13:57:06.345GMT == 2020-05-08T15:57:06.345GMT+2
EDIT:
Here's a possibility of doing the same thing but just dealing with offsets instead of time zones:
public static void main(String[] args) {
// provide some fix example datetime String
String dateTime = "2020-05-08T13:57:06.345";
// create the two offsets needed
ZoneOffset gmt = ZoneOffset.ofHours(0); // UTC = GMT (+0)
ZoneOffset gmtPlusSix = ZoneOffset.ofHours(6); // Asia/Dhaka ;-)
/*
* then parse the String which doesn't contain information about a zone
* to an object that just knows date and time
* NOTE: this just parses the String and does nothing else
*/
LocalDateTime justDateAndTime = LocalDateTime.parse(dateTime);
// and use that to create an offset-aware object with the same date and time
OffsetDateTime dateAndTimeAndGmtPlusSix = OffsetDateTime.of(justDateAndTime, gmtPlusSix);
// finally adjust its date and time by changing the offset keeping the instant
OffsetDateTime dateAndTimeInGmt = dateAndTimeAndGmtPlusSix.withOffsetSameInstant(gmt);
// then print both results
System.out.println(dateAndTimeAndGmtPlusSix + "\t==\t" + dateAndTimeInGmt);
// and maybe try to use a different output format by defining a custom formatter
DateTimeFormatter gmtStyleDtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSO");
System.out.println(dateAndTimeAndGmtPlusSix.format(gmtStyleDtf)
+ "\t==\t" + dateAndTimeInGmt.format(gmtStyleDtf));
}
Output:
2020-05-08T13:57:06.345+06:00 == 2020-05-08T07:57:06.345Z
2020-05-08T13:57:06.345GMT+6 == 2020-05-08T07:57:06.345GMT
Note that a Z is equivalent to an offset of GMT/UTC +0.
This way, you could create a method like
public static String convert(String datetime, int fromOffset, int toOffset) {
ZoneOffset fromZoneOffset = ZoneOffset.ofHours(fromOffset);
ZoneOffset toZoneOffset = ZoneOffset.ofHours(toOffset);
OffsetDateTime odt = LocalDateTime.parse(datetime).atOffset(fromZoneOffset);
return odt.withOffsetSameInstant(toZoneOffset)
.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
maybe handle invalid argument values, use it like this
public static void main(String[] args) {
String dateTime = "2020-05-08T13:57:06.345";
System.out.println(convert(dateTime, 6, 0)));
}
and receive the output
2020-05-08T07:57:06.345
I don't know why you're using a Calendar object. Javadoc of Calendar.getInstance() says:
The Calendar returned is based on the current time in the default time zone
Which means that calling cal.setTime(new Date()); is entirely redundant.
But, even worse than that, the following three are all the same:
// The very long way
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
Date date = cal.getTime();
// The long way
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
// The simple way
Date date = new Date();
A Date object always stores the date/time in UTC (GMT+0). Time zones are applied when a string is parsed, and when a string is formatted.
Parsing a string that doesn't specify a time zone offset will be parsed in the time zone of the SimpleDateFormat, which is the default time zone (aka the "local" time zone) unless otherwise specified, and the parsed value is converted to UTC for storage in a Date object.
Formatting a Date value to string will always use the time zone of the SimpleDateFormat.
Cleaning up the code in the question to not use Calendar, since that just obfuscates the issue, and commenting it to show what is going on, will answer your question of "point out what am I doing wrong in coding or conceptually":
Date now = new Date();
// Format the date in the local time zone
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println("my inputTime:"+ sdf.format(now));
// Format the date in GMT time zone
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("gmt+0 converted time:"+ sdf.format(now));
// Format the date in GMT time zone (again), since the time ** ERROR MIGHT **
// zone of the formatter is still set to GMT ** BE HERE **
String standdardTimeStr = sdf.format(now);
// Parse the GMT date string as-if it is in local time zone ** OR MAYBE HERE **
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date date = sdf2.parse(standdardTimeStr); // Date value here is wrong
// Format the bad date value back to string in the same time
// zone, which means you get GMT time back, even though that
// is not the value of the `date` variable
System.out.println("standard input time:"+ sdf2.format(date));
// Do it again, same result, because the time zone is changed ** ERROR HERE **
// on the wrong formatter object
sdf.setTimeZone(TimeZone.getTimeZone("GMT+6")); //or Asia/Dhaka
System.out.println("gmt+6 convertedtime:"+ sdf2.format(date));
You are missing to take the string representation of time to convert it back to local. The modified code below will give an idea on the same:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class TimeZoneExample {
public static void main(String[] args) throws ParseException {
Calendar cal = Calendar.getInstance();
final Date currentTime = cal.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
String timeInCurrentTimeZone = sdf.format(currentTime);
System.out.println("Time in current time zone: " + timeInCurrentTimeZone);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String timeInGMT = sdf.format(currentTime);
System.out.println("Time in GMT: " + timeInGMT);
// Now, take this time in GMT and parse the string -- this is the key, we want to work with the time which got
// displayed not the internal representation and that's why we will get the time from string!
Date parsedTime = sdf.parse(timeInGMT);
String parsedString = sdf.format(parsedTime);
System.out.println("(GMT) Time in Parsed String: " + parsedString); // here it will show up it in GMT as sdf is still set to GMT
// Change the zone for sdf
sdf.setTimeZone(TimeZone.getTimeZone("GMT+6")); // or Asia/Dhaka
System.out.println("(Local) Time in Parsed String: " + sdf.format(parsedTime)); // here it you will see the zone difference
}
}
Note: You will get better picture if you take fixed time instead of current time.

How to convert timestamp date to java.util date(yyyy-mm-dd) in java

I am getting date from Oracle is in Timestamp but I need to convert it in to this format 2020-02-17 (yyyy-mm-dd) format, but currently in postman I am receiving date as "2020-02-17T09:40:37.850+0000" in this format.
Any help on this would be really appreciated
You can easily convert a java.sql.Timestamp to a java.time.LocalDate and get a date String by formatting the LocalDate like this:
public static void main(String[] args) {
// just a timestamp stub that takes "now"
java.sql.Timestamp ts = java.sql.Timestamp.from(Instant.now());
// convert it to a modern date object
LocalDate justDate = ts.toLocalDateTime().toLocalDate();
// print it using a suitable formatter
System.out.println(justDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
}
The output (today) is
2020-02-17
You just need Java 8 or higher for this or import a backport library.
EDIT
If you don't need a String but a java.util.Date, do it with Instant only, like this:
public static void main(String[] args) {
// just a timestamp stub that takes "now"
Instant now = Instant.now();
Timestamp ts = Timestamp.from(now);
// create an Instant from the Timestamp
Instant timestampInstant = ts.toInstant();
// and then create a Date out from that Instant
java.util.Date creationDate = java.util.Date.from(now);
// do something with the Date here...
}
But please consider using java.time wherever possible, which might be in your domain class...
private String getZonedDateTime(String startTime){
// input -> startTime: 2020-02-17T09:40:37.850+0000
// output -> 2020-02-17
return ZonedDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"))
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
Just pass the Date String which you have and get it in what format you want.
That question is answered here
And what you want exactly, to display the date with that format or save with that format.
If you want display the date with (yyyy-mm-dd)
String dateFormated = new SimpleDateFormat("yyyy-MM-dd").format(myTimestamp);
System.out.println(dateFormated);
If you want save the date with that format you can try to do this:
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd);
String dateFormated = dateFormat.format(myTimestamp);
Date parsedDate = dateFormat.parse(dateFormated);
Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
} catch(Exception e) {
}

Unexpected Output while trying yo convert String to date using FastDateFormat

Problem:
I need to pass Date class Object to a function and that Date Object should contain one Day ahead of the System Time.
For Ex:
If Today's Date is 2017-04-20 17:01:31.Then,Date Object should contain 2017-04-21 17:01:31
Is it possible to store a specified format into Date Class Object and pass into it.
I tried the following thing and it didn't work.
Can anyone guide me if it is possible through Code or should I use SQL Query Concept to add a Day.
Below is my Code
public static void main(String[] args) throws ParseException {
String dateFormat="yyyy-MM-dd HH:mm:ss";
String s2=addDate(dateFormat);
convertStringToDate(s2,dateFormat);
}
public static Date convertStringToDate(String dateInStr, String dateFormat) throws ParseException
{
FastDateFormat fdf=FastDateFormat.getInstance(dateFormat);//("yyyy-MM-dd HH:mm:ss");
Date date = null;
date = fdf.parse(dateInStr);
System.out.println("From convertStringToDate ");
System.out.println(date);
return date;
}
public static String addDate(String dateFormat) throws ParseException{
FastDateFormat fdf=FastDateFormat.getInstance(dateFormat);
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE,1);
String s1=fdf.format(c.getTime());
System.out.println("From addDate ");
System.out.println(s1);
return s1;
}
Expected Output from convertStringToDate:
2017-04-21 17:01:31
OutputShown from convertStringToDate:
Fri Apr 21 17:01:31 IST 2017
You need to obtain the instance of class Date. In your method addDate you get the required Date and then convert it to String and return a String. And then you convert your String back to Date Why don't you just return Date from your method addDate and be done with it?

Unable to parse String using Java Date parser

I was parsing a datetime string using this: http://developer.android.com/reference/java/text/SimpleDateFormat.html but somehow i was getting runtime error on parsing: https://ideone.com/gpFqwp
Can anyone point me to my mistake here?
static String date = "2015-09-17T08:22:49Z";
public static DateFormat inputDatetimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
public static DateFormat displayDateFormat = DateFormat.getDateTimeInstance();
public static void main (String[] args) throws java.lang.Exception
{
System.out.println(displayDateFormat.format(inputDatetimeFormatter.parse(date)));
}
DateFormat inputDatetimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
See javadoc for SimpleDateFormat in Java 7
or use
DateFormat inputDatetimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
See javadoc for SimpleDateFormat in Java 6
here is a sample
Change inputDatetimeFormatter to new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");. Then it will run fine.
EDIT : What is the purpose of the Z at the end of your date string?
Is it just a letter that you always want to be there?
Then you will have to change inputDatetimeFormatter to the above.
If the purpose of Z is for the time zone then your date string is wrong (shouldn't contain Z but a time zone, e.g. -0800).
Then it would give :
static String date = "2015-09-17T08:22:49-0800"; // Replace -0800 by wanted time zone
public static DateFormat inputDatetimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); // Now you can use Z (instead of 'Z') to indicate that the time zone is following

How to convert string date to Date object as per the System's Regional date time format settings?

In my project,i am using object of Date class,
for example
Date date = Date(dateInStringForm);[Though it is deprecated]
It is working perfect with IST[Indian Standard Time] but when i change the settings in Region & Language in control panel [Operating system : Windows7] to any other country for example, portugal then it is throwing java.lang.IllegalArgumentException. How can we make this conversion generic ?
Following is my trial example code,
import java.util.Date;
public class GenericDateTime {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// Date date = new Date("Jan 20, 2015 3:19:52 PM"); //Indian Standard Time Format
Date date = new Date("20/Jan/2015 15:19:51"); //Portugese Time Format
System.out.println("Date Object Form--->>>" + date);
}
}
Its has nothing to do with Timezone. You're giving a different format than a Date() would allow and can parse. There is no generic way that will accept any kind of date format without not knowing the format before converting.
So to accept any specific format you can use SimpleDateFormat.
public static void main(String[] args) {
SimpleDateFormat dateFormat= new SimpleDateFormat("dd/MMM/yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date date = dateFormat.parse("20/Jan/2015 15:19:51");
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
Instead of passing date as String you can use SimpleTimeFormat to specify date format and pass date string as UTC time. If you are free to use external libs Joda Time would be best option for you.

Categories