I have a query for an Oracle database that returns a datetime column. In the java method, the column is converted to a string.
A portion of the code looks like this:
ResultSet rs;
HashMap<String, String> hm=new HashMap<String, String> ();
hm.put("SchEndDate2", rs1.getString("END_DT_TM_GMT"));
When I view the strings value in the debugger it looks like this: "2019-07-04 11:00:00.0"
I need to convert this string to the datetime format of this: "yyyy-MM-dd'T'HH:mm"
I tried this SimpleDateFormat to complete this but when I convert the string to the format it returns the dateTime in Eastern Daylight Time and not GMT.
The value after going thru the conversion is this: "Thu Jul 04 07:00:00 EDT 2019"
This is the code that I am using to convert the string to a DateTime.
EndDate=map.get("SchEndDate2");
//EndDate : **"2019-07-04 11:00:00.0"**
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
Date databaseDateTime = formatter.parse(EndDate);
//databaseDateTime: **"Thu Jul 04 07:00:00 EDT 2019"**
Why is the format incorrect and the timezone not correctly set?
Two points.
Don’t fetch your date and time as a string from Oracle. Fetch a proper date-time object. In this case a LocalDateTime.
Don’t use SimpleDateFormat, TimeZone and Date. Those classes are poorly designed and long outdated, the first in particular notoriously troublesome. Use java.time, the modern Java date and time API.
In code:
ResultSet rs = // …;
LocalDateTime dateTime = rs.getObject("END_DT_TM_GMT", LocalDateTime.class);
String databaseDateTimeAsString = dateTime.toString();
System.out.println(databaseDateTimeAsString);
Example output:
2019-07-04T11:00
It’s not quite the output format that you asked for, but it most likely will serve your purpose. The format you asked for is ISO 8601. So is the output I have given you. In the ISO 8601 standard, including the seconds and fraction of second when they are 0 is optional. If you insist on including them, use a formatter. For example:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS");
String databaseDateTimeAsString = dateTime.format(formatter);
2019-07-04T11:00:00.000
Using rs.getObject() for getting a LocalDateTime as shown requires a JDBC 4.2 compliant database driver. You probably have got that. In case you haven’t and you cannot upgrade, use:
LocalDateTime dateTime = rs.getTimestamp("END_DT_TM_GMT").toLocalDateTime();
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
Try converting the Date object to an Instant. Here's an example showing your input string first converted to a Date, and then converting that to an Instant. The date contains the timezone-specific rendering, but the instant does not.
String input = "2019-07-04 11:00:00.0";
System.out.println("input: " + input);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
Date date = formatter.parse(input);
System.out.println("date: " + date);
Instant instant = date.toInstant();
System.out.println("instant: " + instant);
And here's the output:
input: 2019-07-04 11:00:00.0
date: Thu Jul 04 05:00:00 MDT 2019
instant: 2019-07-04T11:00:00Z
Related
String current = "07:00:00.160"
DateFormat df2 = new SimpleDateFormat("HH:mm:ss.SSS");
DateList.add(df2.parse(current));
Returns [Thu Jan 01 07:00:00 GMT 1970]
I have tried this as well
Date currentdate;
currentdate = df2.parse(current);
df2.format(currentdate);
DateList.add(currentdate);
Returns also
[Thu Jan 01 07:00:00 GMT 1970]
and I have also tried using df2.setLenient(false);
java.time.LocalTime
I recommend that you use java.time, the modern Java date and time API, for your time work. The class to use for time of day is LocalTime.
We don’t even need to specify a formatter for parsing your string since it is in the default format for a time of day (also laid down in the ISO 8601 standard).
String current = "07:00:00.160";
LocalTime time = LocalTime.parse(current);
System.out.println(time);
Outout:
07:00:00.160
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
I try to convert String to Date format but I got an exception!
Here is my code:
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
startDate = format.parse(startDateString);
it should convert "14-MAY-2004" to Date. Thanks.
java.time
I recommend that you use java.time, the modern Java date and time API, for your date work.
DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("d-MMM-uuuu")
.toFormatter(Locale.ENGLISH);
String startDateString = "14-MAY-2004";
LocalDate startDate = LocalDate.parse(startDateString, dateFormatter);
System.out.println(startDate);
Output is:
2004-05-14
Only if you indispensably need a Date object for a legacy API not yet upgraded to java.time, convert:
Instant startOfDay = startDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
Date oldfashionedDate = Date.from(startOfDay);
System.out.println(oldfashionedDate);
Output in my time zone:
Fri May 14 00:00:00 CEST 2004
What went wrong in your code?
It’s almost certainly a locale problem. You didn’t specify a locale and hence no language for the month name or abbreviation. Always do that when the date string includes text in some language. Your SimpleDateFormat was using the default formatting locale of your JVM, and if that was a non-English-speaking locale, parsing was deemed to fail with an exception as you mentioned.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Similar question: Java - Unparseable date
From the statment "it should convert 14-MAY-2004 to date" i assume your input string is 14-MAY-2004 and you want this string to be converted to Date
String js="14-May-2004";
Date dt=new Date(js);
LocalDateTime localDateTime=dt.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
localDateTime.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));//or in the same format use- "dd-MMM-yyyy"
SimpleDateFormat df = new SimpleDateFormat();
Date lastLogin = null;
try {
String troubleChild = lineScanner.next();
lastLogin = df.parse(troubleChild);
} catch (ParseException e) {
System.out.println("ohnoes");
}
Hi I'm quite new to using the date functions and I've come up with a problem. I have a file that is being parsed into various variables and they all work except this one i can never get it so that it passes the try/catch clause i've looked up similar problems but none of them work on my code.(The date i am inputting is in the format: Mon, Oct 30 22:20:11 GMT 2017) please can I get some help and thanks for it!
Solution: java.time
Please don’t take the trouble with the long outmoded classes Date and SimpleDateFormat. Instead use java.time, the modern Java date and time API also known as JSR-310:
DateTimeFormatter dtf
= DateTimeFormatter.ofPattern("E, MMM d H:mm:ss z uuuu", Locale.UK);
String inputDate = "Mon, Oct 30 22:20:11 GMT 2017";
ZonedDateTime lastLogin = ZonedDateTime.parse(inputDate, dtf);
System.out.println(lastLogin);
This prints
2017-10-30T22:20:11Z[GMT]
Since dates and times may come in so many different textual formats, I am using a format pattern string to specify your particular format. For which letters you may use, and what difference it makes whether you use 1, 3 or 4 of the same letter, see the documentation. Beware that format pattern strings are case sensitive.
Problem: SimpleDateFormat
You used the no-arg SimpleDateFormat constructor. The way I read the documentation, this gives you the default date format for your locale. If your JVM is running UK locale, I believe the format goes like 28/11/17 10:57 — not much like the input format you were trying to parse. You can use System.out.println(df.format(new Date())); to find out. The usual SimpleDateFormat constructor to use would be SimpleDateFormat(String, Locale) so that you may again supply a format pattern string and a locale.
I am trying to Parse "8:30 AM" but I am getting Unparseable Date Exception.
From my UI side I am getting "8:30 AM" and "6:30 PM" kind of values but I have to convert that String into Date format and save that date in my database.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
public static void main(String[] args) {
SimpleDateFormat timingFormat = new SimpleDateFormat("h a",
Locale.US);
String dateInString = "8:30 AM";
try {
// This line throws Unparseable exception
Date date = timingFormat.parse(dateInString);
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
From Documentation
the year value of the parsed Date is 1970 with GregorianCalendar if no
year value is given from the parsing operation. The TimeZone value may
be overwritten, depending on the given pattern and the time zone value
in text.
try this
SimpleDateFormat timingFormat = new SimpleDateFormat("h a", Locale.US);
Date date = timingFormat.parse("8 AM");
System.out.println(date.toString());
Output
Thu Jan 01 08:00:00 IST 1970
UPDATE
To get today date,you can try something like this after parsing
int hours = date.getHours();
Date today = new Date();
today.setHours(hours);
System.out.println(today);
Note getHours() and setHours are deprecated methods.Its recommended to go for Calendar.You will have to set hours, minutes explicitly.
UPDATE
if input is 8:30 or so,then you will have to parse it like this
SimpleDateFormat timingFormat = new SimpleDateFormat("h:mm a", Locale.US);
Date date = timingFormat.parse("8:30 AM");
System.out.println(date.toString());
Output
Thu Jan 01 08:30:00 IST 1970
Depending on the input,you need to select which kind of format you are insterested.You can check that whether string contains : or not,based on that you can use SimpleDateFormat.
Just to Parse 8:30 AM just change the formatter above with
SimpleDateFormat timingFormat = new SimpleDateFormat("h:mm a");
Regards
The accepted answer is correct but outdated.
As mentioned, the Question has an input string which means only a time-of-day while the java.util.Date class represents both a date plus a time-of-day.
What you need is a class that represents only a time-of-day. No such class in the older versions of Java before Java 8.
java.time
The java.time framework built into Java 8 and later supplants the troublesome old java.util.Date/.Calendar classes. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.
LocalTime
The java.time classes include the LocalTime class. This class represents a time-of-day without any date nor time zone.
Note that for the formatter we specified a Locale using the English language to correctly identify the strings AM and PM which could vary by human language.
String input = "8:30 AM";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "h:m a" , Locale.ENGLISH );
LocalTime localTime = LocalTime.parse ( input , formatter );
Dump to console.
System.out.println ( "localTime: " + localTime );
localTime: 08:30
Database
Next, the database. Eventually we should see JDBC drivers updated to directly handle the java.time types. Until then, we must convert from java.time types to the old java.sql types.
Convert From java.time to java.sql
For this Question, that means the java.sql.Time class. That old java.sql.Time class has a new method for convenient conversions, valueOf.
java.sql.Time sqlTime = java.sql.Time.valueOf ( localTime );
From there, the JDBC driver converts from the java.sql time to the database type. For this Question, that probably means the standard TIME SQL type.
Pass java.sql.* Object To Database Via JDBC Driver
Use a PreparedStatement to insert or update your data by passing that sqlTime variable seen above. Search StackOverflow.com for countless examples of such insert/update work in SQL.
I tried this:
DateFormat fmt = new SimpleDateFormat("MMMM dd, yyyy");
Date d = fmt.parse("June 27, 2007");
error:
Exception in thread "main" java.text.ParseException: Unparseable date: "June 27, 2007"
The java docs say I should use four characters to match the full form.
I'm only able to use MMM successfully with abbreviated months like "Jun" but i need to match full form.
Text: For formatting, if the number
of pattern letters is 4 or more, the
full form is used; otherwise a short
or abbreviated form is used if
available. For parsing, both forms are
accepted, independent of the number of
pattern letters.
https://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
You are probably using a locale where the month names are not "January", "February", etc. but some other words in your local language.
Try specifying the locale you wish to use, for example Locale.US:
DateFormat fmt = new SimpleDateFormat("MMMM dd, yyyy", Locale.US);
Date d = fmt.parse("June 27, 2007");
Also, you have an extra space in the date string, but actually this has no effect on the result. It works either way.
LocalDate from java.time
Use LocalDate from java.time, the modern Java date and time API, for a date
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMMM d, u", Locale.ENGLISH);
LocalDate date = LocalDate.parse("June 27, 2007", dateFormatter);
System.out.println(date);
Output:
2007-06-27
As others have said already, remember to specify an English-speaking locale when your string is in English. A LocalDate is a date without time of day, so a lot better suitable for the date from your string than the old Date class. Despite its name a Date does not represent a date but a point in time that falls on at least two different dates in different time zones of the world.
Only if you need an old-fashioned Date for an API that you cannot afford to upgrade to java.time just now, convert like this:
Instant startOfDay = date.atStartOfDay(ZoneId.systemDefault()).toInstant();
Date oldfashionedDate = Date.from(startOfDay);
System.out.println(oldfashionedDate);
Output in my time zone:
Wed Jun 27 00:00:00 CEST 2007
Link
Oracle tutorial: Date Time explaining how to use java.time.
Just to top this up to the new Java 8 API:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("MMMM dd, yyyy").toFormatter();
TemporalAccessor ta = formatter.parse("June 27, 2007");
Instant instant = LocalDate.from(ta).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date d = Date.from(instant);
assertThat(d.getYear(), is(107));
assertThat(d.getMonth(), is(5));
A bit more verbose but you also see that the methods of Date used are deprecated ;-) Time to move on.
val currentTime = Calendar.getInstance().time
SimpleDateFormat("MMMM", Locale.getDefault()).format(date.time)