With java.text.DateFormat, it's possible to build a date formatter with a date and a time style :
DateFormat df = getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG);
system.out.println(df.format(new Date()));
Is it possible to use something similar with Joda-Time ?
Standard Formatting Built Into JodaTime
There's a bunch of standard Date and Time formats built right into JodaTime.
Here's an example of one that I use:
DateTime dateTime = DateTime.now(DateTimeZone.UTC);
String formattedDateTime = dateTime.toString(DateTimeFormat.fullDateTime());
Notice the DateTimeFormat.fullDateTime().
Some other options for this include:
fullTime()
fullDate()
shortDateTime()
forStyle("MS") Indicates a Medium Date and a Short Time.
forStyle("S-") Indicates a Short Date and No Time.
... etc ...
The full listing can be found at:
http://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html#forStyle(java.lang.String)
Cheers,
JP
Use DateTimeFormat.forPattern() with a pattern that does what you want.
For instance, DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss");
Related
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"
I upgraded to:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern ("dd/MM/yyyy HH:mm:ss");
org.threeten.bp.LocalDateTime _date = org.threeten.bp.LocalDateTime.parse ("10/19/2020 18:00:47", dtf);
and get:
2020-10-19T18:00:47
but I still don't have an exit with the standard: 2020-10-19T18:00:47.868-03:00
The previously accepted answer by user3197884 is correct and informative (+1). I didn’t feel it fully answered the question as asked, so I wanted to contribute the conversion into an org.threeten.bp.OffsetDateTime.
DateTimeFormatter dtf = DateTimeFormatter.ofPattern ("MM/dd/yyyy HH:mm:ss");
OffsetDateTime date = LocalDateTime.parse("10/19/2020 18:00:47", dtf)
.atZone(ZoneId.of("America/Argentina/Buenos_Aires"))
.toOffsetDateTime();
System.out.println(date);
Output is what you asked for:
2020-10-19T18:00:47-03:00
Since your string doesn’t have an offset or time zone in it, we need to provide the offset in some other way. Exactly which is the best way in your particular situation I dare not tell, but a very common good way is providing the time zone that was assumed for the string. I just picked one, please insert your own time zone instead.
Rather than swapping 10 and 19 in the string I have swapped dd and MM in the format pattern. Obviously either works.
Your DateTimeFormatter has ("dd/MM/yyyy HH:mm:ss") but you have used "10/19/2020 18:00:47".
Month cannot be 19.
Change your input to "19/10/2020 18:00:47" and it should work.
org.threeten.bp.format.DateTimeFormatter dtf = org.threeten.bp.format.DateTimeFormatter.ofPattern ("dd/MM/yyyy HH:mm:ss");
org.threeten.bp.LocalDateTime _date = org.threeten.bp.LocalDateTime.parse("19/10/2020 18:00:47", dtf);
System.out.println(_date);
This question already has answers here:
Android convert UTC Date to local timezone [duplicate]
(2 answers)
Closed 5 years ago.
I have a date String like 2017-09-16T05:06:18.157 and I want to convert it to local time (IST). In Indian Standard Time it will be around 2017-09-16 10:36:18.
With Joda-Time, I have tried to convert it to local but I was not able to do it.
Below is my code:
private String getConvertDate(String date_server) {
DateTimeFormatter inputFormatter = DateTimeFormat
.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
.withLocale(Locale.US);
DateTime parsed = inputFormatter.parseDateTime(date_server);
DateTimeFormatter outputFormatter = DateTimeFormat
.forPattern("yyyy-MM-dd HH:mm:ss")
.withLocale(Locale.US)
.withZone(DateTimeZone.getDefault());
return outputFormatter.print(parsed);
}
Good you found a solution with SimpleDateFormat. I'd just like to add more insights about it (basically because the old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs).
The input String (2017-09-16T05:06:18.157) contains only the date (year/month/day) and time (hour/minute/second/millisecond), but no timezone information. So, when calling parseDateTime, Joda-Time just assumes that it's in the JVM default timezone.
If you know that the input is in UTC, but the input itself has no information about it, you must tell it. One way is to set in the formatter:
// set the formatter to UTC
DateTimeFormatter inputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
.withZone(DateTimeZone.UTC);
// DateTime will be in UTC
DateTime parsed = inputFormatter.parseDateTime("2017-09-16T05:06:18.157");
Another alternative is to first parse the input to a org.joda.time.LocalDateTime (a class that represents a date and time without a timezone), and then convert it to a DateTime in UTC:
// parse to LocalDateTime
DateTime = parsed = LocalDateTime.parse("2017-09-16T05:06:18.157")
// convert to a DateTime in UTC
.toDateTime(DateTimeZone.UTC);
Both produces the same DateTime, corresponding to UTC 2017-09-16T05:06:18.157Z.
To format it to "IST timezone" (which is actually not a timezone - more on that below), you can also set the timezone in the formatter:
// convert to Asia/Kolkata
DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(DateTimeZone.forID("Asia/Kolkata"));
System.out.println(outputFormatter.print(parsed));
Or you can convert the DateTime to another timezone, using the withZone() method:
DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
// convert to Asia/Kolkata
System.out.println(outputFormatter.print(parsed.withZone(DateTimeZone.forID("Asia/Kolkata"))));
Both will print:
2017-09-16 10:36:18
In your code you're using DateTimeZone.getDefault(), that gets the JVM default timezone (with some tricky details). But the default timezone can be changed without notice, even at runtime, so it's always better to specify which one you want to use.
Also, keep in mind that short names like IST are not real timezones. Always prefer to use IANA timezones names (always in the format Region/City, like Asia/Kolkata or Europe/Berlin).
Avoid using the 3-letter abbreviations (like IST or PST) because they are ambiguous and not standard. Just check in this list that IST can be "India Standard Time", "Israel Standard Time" and "Irish Standard Time".
You can get a list of available timezones (and choose the one that fits best your system) by calling DateTimeZone.getAvailableIDs().
Java new Date/Time API
Joda-Time is in maintainance mode and is being replaced by the new APIs, so I don't recommend start a new project with it. Even in joda's website it says: "Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
If you can't (or don't want to) migrate from Joda-Time to the new API, you can ignore this section.
In Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need the ThreeTenABP (more on how to use it here).
This new API has lots of different date/time types for each situation.
First, you can parse the input to a org.threeten.bp.LocalDateTime, then I use a org.threeten.bp.ZoneOffset to convert it to UTC, resulting in a org.threeten.bp.OffsetDateTime.
Then, I use a org.threeten.bp.ZoneId to convert this to another timezone, and use a org.threeten.bp.format.DateTimeFormatter to format it (this is basically what's suggested by #Ole V.V's comment - just to show how straightforward it is, as there aren't anything much different to do):
// parse to LocalDateTime
OffsetDateTime parsed = LocalDateTime.parse("2017-09-16T05:06:18.157")
// convert to UTC
.atOffset(ZoneOffset.UTC);
// convert to Asia/Kolkata
ZoneId zone = ZoneId.of("Asia/Kolkata");
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(outputFormatter.format(parsed.atZoneSameInstant(zone)));
The output is:
2017-09-16 10:36:18
try this code:
String serverdateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";
public String convertServerDateToUserTimeZone(String serverDate) {
String ourdate;
try {
SimpleDateFormat formatter = new SimpleDateFormat(serverdateFormat, Locale.UK);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Date value = formatter.parse(serverDate);
TimeZone timeZone = TimeZone.getTimeZone("Asia/Kolkata");
SimpleDateFormat dateFormatter = new SimpleDateFormat(serverdateFormat, Locale.UK); //this format changeable
dateFormatter.setTimeZone(timeZone);
ourdate = dateFormatter.format(value);
//Log.d("OurDate", OurDate);
} catch (Exception e) {
ourdate = "0000-00-00 00:00:00";
}
return ourdate;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TimeZone utcZone = TimeZone.getTimeZone("UTC");
simpleDateFormat.setTimeZone(utcZone);
Date myDate =simpleDateFormat.parse(rawQuestion.getString("Asia/Kolkata"));
simpleDateFormat.setTimeZone(TimeZone.getDefault());
String formattedDate = simpleDateFormat.format(myDate);
I want to convert from string to date using Java 8.
I can easily convert using SimpleDateFormat and yyyy-MM-dd format
String startDate2="2017-03-24";
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(new java.sql.Date(sdf1.parse(startDate2).getTime()));
output:
2017-03-24
String startDate2="2017-03-24";
SimpleDateFormat sdf1 = new SimpleDateFormat("uuuu-MM-dd");
System.out.println(new java.sql.Date(sdf1.parse(startDate2).getTime()));
But when I use 'uuuu-MM-dd' instead of 'yyyy-MM-dd'
output :
1970-03-24(wrong)
now in Java 8:
String startDate1="2017-03-23";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
But I don't know how I can get the date which would be sql date type same as above correct output.
java.sql.Date has a static valueOf method that takes a Java 8 LocalDate so you can do:
String startDate1 = "2017-03-23";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
LocalDate date = LocalDate.parse(startDate1, formatter);
java.sql.Date sqlDate = java.sql.Date.valueOf(date);
As far as I can see, you have a text in yyyy-MM-dd format and you want it in uuuu-MM-dd format. So you need two formats:
String startDate2="2017-03-24";
SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat targetFormat = new SimpleDateFormat("uuuu-MM-dd");
java.sql.Date date = new java.sql.Date(sourceFormat.parse(startDate2).getTime());
String formattedAsDayOfWeek = targetFormat.format(date);
System.out.println(formattedAsDayOfWeek);
Bottom line is that Date contains a millisecond value. java.sql.Date.toString() uses the yyyy-MM-dd format regardless how you parsed it. java.util.sql.Date uses another format: EEE MMM dd hh:mm:ss zzz yyyy with English Locale.
You can do other formatting with DateFormat -s.
I presume you need the uuuu-MM-dd format for inserting data to the database. What does that logic look like?
You don’t want a java.sql.Date. You want a LocalDate. Your SQL database wants one too.
String startDate2 = "2017-03-24";
LocalDate date = LocalDate.parse(startDate2);
System.out.println(date);
Output is:
2017-03-24
I am exploiting the fact that your string is in ISO 8601 format. The classes of java.time including LocalDate parse this format as their default, that is, without any explicit formatter.
You also note that we don’t need any explicit formatter for formatting back into uuuu-MM-dd format for the output. The toString method implicitly called from System..out.println() produces ISO 8601 format back.
Assuming that you are using a JDBC 4.2 compliant driver (I think we all are now), I am taking the way to pass it on to your SQL database from this question: Insert & fetch java.time.LocalDate objects to/from an SQL database such as H2:
myPreparedStatement.setObject ( 1 , date ); // Automatic detection and conversion of data type.
Refer to the linked question for much more detail.
The java.sql.Date class is poorly designed, a true hack on top of the already poorly designed java.util.Date class. Both classes are long outdated. Don’t use any of them anymore.
One more link: Wikipedia article: ISO 8601
I am trying to use setDate() in a PreparedStatement, however the date that I have is in the format of 2008-07-31. The code is:
pstmt.setDate(f++, (Date) DateFormat.getDateInstance(DateFormat.DEFAULT).parse(value.substring(0, 10)));
However, it gives me the error:
Exception in thread "main" java.text.ParseException: Unparseable date: "2008-07-31"
Why is this?
If you have a very specific date, don't ask Java to use a default date format - set it yourself.
For example:
DateFormat parser = new SimpleDateFormat("yyyy-MM-dd");
Date date = parser.parse(value.substring(0, 10));
You should also potentially set the time zone of the parser... my guess is that UTC is the most appropriate time zone here.
Note that this has nothing to do with prepared statements as such - it's just date parsing.
(As an alternative to using DateFormat and SimpleDateFormat, you could use Joda Time which has a nicer API and thread-safe formatters/parsers. You can ask Joda Time to convert from its own types to Date values. Possibly overkill if you only need it for parsing here, but if you're doing anything else with dates, it's well worth looking into.)
You need make sure the default DateFormat is in yyyy-MM-dd format (usually it's a config in OS), or you can use SimpleDateFormat or java.sql.Date to parse date string.
java.util.Date d;
SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd");
d = sdf.parse ("2008-07-31");
// or
d = java.sql.Date.valueOf ("2008-07-31");
or, you could just set parameter as String, if the underlying database driver support the VARCHAR/CHAR to DATE conversion.
DateFormat.DEFAULT points to MEDIUM format and MEDIUM format looks like Jan 12, 1952. So, you may have create a SimpleDateFormat object with the format you are using.
I think there is mismatch in the format of the date that you are providing as input and the format in which you have specified while formatting which is default in your case.
SimpleDateFormat parser = new SimpleDateFormay("yyyy-MM-dd");
Try using the same format for both the dates.
First convert String to Date and then set that to PreparedStatement. Check with below code.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
Date convertedDate = dateFormat.parse(dateString);
I'd use
pstmt.setDate(f++,
new java.sql.Date(
new SimpleDateFormat("yyyy-MM-dd")
.parse(value.substring(0, 10))
.getTime()
)
);