I have a String in a database (match.getDate) that has the following date format:
01/04/2018
This is the date I want to format, stored as day/month/year. I want to format this for my Android app.
I want to format the date into:
Sun 01 Apr 2018
My code below:
SimpleDateFormat fDate = new SimpleDateFormat("dd/MM/yyyy");
try {
textViewDate.setText(fDate.parse(match.getDate()).toString());
} catch (ParseException ex) {
System.out.println(ex.toString());
}
This outputs:
Sun Apr 08 00:00:00 GMT+00:00 2018.
I have also tried "EE, MM d, yyyy", but it gives me:
java.text.ParseException: Unparseable date: "01/04/2018"
The other answers solved your problem, but I think it's important to know some concepts and why your first attempt didn't work.
There's a difference between a date and a text that represents a date.
Example: today's date is March 9th 2018. That date is just a concept, an idea of "a specific point in our calendar system".
The same date, though, can be represented in many formats. It can be "graphical", in the form of a circle around a number in a piece of paper with lots of other numbers in some specific order, or it can be in plain text, such as:
09/03/2018 (day/month/year)
03/09/2018 (monty/day/year)
2018-03-09 (ISO8601 format)
March, 9th 2018
9 de março de 2018 (in Portuguese)
2018年3月5日 (in Japanese)
and so on...
Note that the text representations are different, but all of them represent the same date (the same value).
With that in mind, let's see how Java works with these concepts.
a text is represented by a String. This class contains a sequence of characters, nothing more. These characters can represent anything; in this case, it's a date
a date was initially represented by java.util.Date, and then by java.util.Calendar, but those classes are full of problems and you should avoid them if possible. Today we have a better API for that.
In Android, you can use the java.time classes if available in the API level you're using, or the threeten backport for API levels lower than that (check here how to use it). You'll have easier and more reliable tools to deal with dates.
In your case, you have a String (a text representing a date) and you want to convert it to another format. You must do it in 2 steps:
convert the String to some date-type (transform the text to numerical day/month/year values) - that's called parsing
convert this date-type value to some format (transform the numerical values to text in a specific format) - that's called formatting
Why your attempts didn't work:
the first attempt gave you the wrong format because you called Date::toString() method, which produces an output (a text representation) in that format (Sun Apr 08 00:00:00 GMT+00:00 2018) - so the parsing was correct, but the formatting wasn't
in the second attempt, you used the output pattern (EE dd MMM yyyy, the one you should use for formatting) to parse the date (which caused the ParseException).
For step 1, you can use a LocalDate, a type that represents a date (day, month and year, without hours and without timezone), because that's what your input is:
String input = "01/04/2018";
DateTimeFormatter inputParser = DateTimeFormatter.ofPattern("dd/MM/yyyy");
// parse the input
LocalDate date = LocalDate.parse(input, inputParser);
That's more reliable than SimpleDateFormat because it solves lots of strange bugs and problems of the old API.
Now that we have our LocalDate object, we can do step 2:
// convert to another format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EE dd MMM yyyy", Locale.ENGLISH);
String output = date.format(formatter);
Note that I used a java.util.Locale. That's because the output you want has the day of week and month name in English, and if you don't specify a locale, it'll use the JVM's default (and who guarantees it'll always be English? it's better to tell the API which language you're using instead of relying on the default configs, because those can be changed anytime, even by other applications running in the same JVM).
And how do I know which letters must be used in DateTimeFormatter? Well, I've just read the javadoc.
Use this date formatter method I have created
public static String dateFormater(String dateFromJSON, String expectedFormat, String oldFormat) {
SimpleDateFormat dateFormat = new SimpleDateFormat(oldFormat);
Date date = null;
String convertedDate = null;
try {
date = dateFormat.parse(dateFromJSON);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(expectedFormat);
convertedDate = simpleDateFormat.format(date);
} catch (Exception e) {
e.printStackTrace();
}
return convertedDate;
}
and call this method like
dateFormater(" 01/04/2018" , "EE dd MMM yyyy" , "dd/MM/yyyy")
and you will get the desired output
You need two date formatters here. One to parse the input, and a different formatter to format the output.
SimpleDateFormat inDateFmt = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat outDateFmt = new SimpleDateFormat("EEE dd MMM yyyy");
try {
Date date = inDateFmt.parse(match.getDate());
textViewDate.setText(outDateFmt.format(date));
} catch (ParseException ex) {
System.out.println(ex.toString());
}
Try this, you can create any date format you want with this
public String parseTime(String date){
SimpleDateFormat format = new SimpleDateFormat("yyyy-dd-MM HH:mm:ss");
try {
Date date1 = format.parse(date.replace("T"," "));
String d= new SimpleDateFormat("yyyy/dd/MM HH:mm:ss").format(date1);
return d;
}catch (Exception e){
e.printStackTrace();
}
return "";
}
Try with new SimpleDateFormat("EEE dd MMM yyyy", Locale.ENGLISH);
Sample Code:
DateFormat originalFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);
DateFormat targetFormat = new SimpleDateFormat("EEE dd MMM yyyy", Locale.ENGLISH);
Date date = originalFormat.parse("01/04/2018");
String formattedDate = targetFormat.format(date); // Sun 01 Apr 2018
tl;dr
LocalDate
.parse(
"01/04/2018" ,
DateTimeFormatter // Parses & generates text in various formats
.ofPattern( "dd/MM/uuuu" ) // Define a formatting pattern to match your input.
) // Returns a `LocalDate` object.
.toString() // Generates text in standard ISO 8601 format.
2018-04-01
Use data types appropriately
I have a String in a database (match.getDate) that has the following date format:
Do not store date-time values as text.
You should be storing date-time values in a database using date-time data types. In standard SQL, a date-only value without time-of-day and without time zone is stored in a column of type DATE.
Another problem is that you are trying to represent a date-only value in Java class that represents a moment, a date with time-of-day in context of time zone or offset-from-UTC. Square peg, round hole. Using a date-only data types makes your problems go away.
java.time
The other Answers used outmoded classes, years ago supplanted by the modern java.time classes built into Java 8 and later, and built into Android 26 and later. For earlier Java & Android, see links below.
In Java, a date-only value without time-of-day and without time zone is represented by the LocalDate class.
LocalDate ld = LocalDate.parse( "2020-01-23" ) ; // Parsing a string in standard ISO 8601 format.
For a custom formatting pattern, use DateTimeFormatter.
String input = "01/04/2018" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
Generate a string in standard ISO 8601 format.
String output = ld.toString() ;
Generate a string in your custom format.
String output = ld.format( f ) ;
Tip: Use DateTimeFormatter.ofLocalizedDate to automatically localize your output.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
first of check your match.getDate() method which format given date if is given above define format date then used below code and show date in define above format ...
String date="09/03/2018";
SimpleDateFormat parseDateFormat = new SimpleDateFormat("dd/MM/yyyy"); // if your match.getDate() given this format date.and if is given different format that time define that format.
DateFormat formatdate = new SimpleDateFormat("EEE dd MMM yyyy");
try {
Date date1=parseDateFormat.parse(date);
Log.d("New Date",formatdate.format(date1));
} catch (ParseException e) {
e.printStackTrace();
}
output:: Fri 09 Mar 2018
Related
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.
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 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 am new to Java, usually work with PHP.
I am trying to convert this string:
Mon Mar 14 16:02:37 GMT 2011
Into a Calendar Object so that I can easily pull the Year and Month like this:
String yearAndMonth = cal.get(Calendar.YEAR)+cal.get(Calendar.MONTH);
Would it be a bad idea to parse it manually? Using a substring method?
Any advice would help thanks!
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
cal.setTime(sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
note: set Locale according to your environment/requirement
See Also
Javadoc
tl;dr
The modern approach uses the java.time classes.
YearMonth.from(
ZonedDateTime.parse(
"Mon Mar 14 16:02:37 GMT 2011" ,
DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" )
)
).toString()
2011-03
Avoid legacy date-time classes
The modern way is with java.time classes. The old date-time classes such as Calendar have proven to be poorly-designed, confusing, and troublesome.
Define a custom formatter to match your string input.
String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
Parse as a ZonedDateTime.
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
You are interested in the year and month. The java.time classes include YearMonth class for that purpose.
YearMonth ym = YearMonth.from( zdt );
You can interrogate for the year and month numbers if needed.
int year = ym.getYear();
int month = ym.getMonthValue();
But the toString method generates a string in standard ISO 8601 format.
String output = ym.toString();
Put this all together.
String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
YearMonth ym = YearMonth.from( zdt );
int year = ym.getYear();
int month = ym.getMonthValue();
Dump to console.
System.out.println( "input: " + input );
System.out.println( "zdt: " + zdt );
System.out.println( "ym: " + ym );
input: Mon Mar 14 16:02:37 GMT 2011
zdt: 2011-03-14T16:02:37Z[GMT]
ym: 2011-03
Live code
See this code running in IdeOne.com.
Conversion
If you must have a Calendar object, you can convert to a GregorianCalendar using new methods added to the old classes.
GregorianCalendar gc = GregorianCalendar.from( zdt );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 brought some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android (26+) bundle implementations of the java.time classes.
For earlier Android (<26), the process of API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
Well, I think it would be a bad idea to replicate the code which is already present in classes like SimpleDateFormat.
On the other hand, personally I'd suggest avoiding Calendar and Date entirely if you can, and using Joda Time instead, as a far better designed date and time API. For example, you need to be aware that SimpleDateFormat is not thread-safe, so you either need thread-locals, synchronization, or a new instance each time you use it. Joda parsers and formatters are thread-safe.
No new Calendar needs to be created, SimpleDateFormat already uses a Calendar underneath.
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.EN_US);
Date date = sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
Calendar cal = sdf.getCalendar();
(I can't comment yet, that's why I created a new answer)
SimpleDateFormat is great, just note that HH is different from hh when working with hours. HH will return 24 hour based hours and hh will return 12 hour based hours.
For example, the following will return 12 hour time:
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");
While this will return 24 hour time:
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
Parse a time with timezone, Z in pattern is for time zone
String aTime = "2017-10-25T11:39:00+09:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
try {
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(aTime));
Log.i(TAG, "time = " + cal.getTimeInMillis());
} catch (ParseException e) {
e.printStackTrace();
}
Output: it will return the UTC time
1508899140000
If we don't set the time zone in pattern like yyyy-MM-dd'T'HH:mm:ss. SimpleDateFormat will use the time zone which have set in Setting
Yes it would be bad practice to parse it yourself. Take a look at SimpleDateFormat, it will turn the String into a Date and you can set the Date into a Calendar instance.
Simple method:
public Calendar stringToCalendar(String date, String pattern) throws ParseException {
String DEFAULT_LOCALE_NAME = "pt";
String DEFAULT_COUNTRY = "BR";
Locale DEFAULT_LOCALE = new Locale(DEFAULT_LOCALE_NAME, DEFAULT_COUNTRY);
SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
Date d = format.parse(date);
Calendar c = getCalendar();
c.setTime(d);
return c;
}
The string I want to format looks like this:
String datetime = "9/1/10 11:34:35 AM"
Following pattern for SimpleDateFormat works:
SimpleDateFormat sdf = SimpleDateFormat("M/d/yy h:mm:ss");
Date d = sdf.parse(datetime);
System.out.println(d);
Output> [Wed Sep 01 11:34:35 CEST 2010]
However I need to parse the AM/PM marker as well, and when I add that to the pattern I receive an exception.
Pattern that doesn't work:
SimpleDateFormat sdf = SimpleDateFormat("M/d/yy h:mm:ss a");
I have tried with this also with same exception:
SimpleDateFormat sdf = SimpleDateFormat("M/d/yy h:mm:ss aa");
Exception:
java.text.ParseException: Unparseable date: "9/1/10 11:34:35 AM"
I have looked through the API at http://download.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html#text but canät seem to find where I do wrong.
Any suggestions?
One possibility is that your default Locale has different symbols for AM/PM. When constructing a date format you should always supply a Locale unless you really want to use the system's default Locale, e.g.:
SimpleDateFormat sdf = new SimpleDateFormat("M/d/yy h:mm:ss a", Locale.US)
Modern answer:
String datetime = "9/1/10 11:34:35 AM";
LocalDateTime dt = LocalDateTime.parse(datetime,
DateTimeFormatter.ofPattern("M/d/yy h:mm:ss a", Locale.ENGLISH));
This produces a LocalDateTime of 2010-09-01T11:34:35. Beware of two digit years, though; DateTimeFormatter will assume 2000 through 2099. For my birthday this would have been incorrect.
We still need to provide the locale. Since AM/PM markers are hardly used in practice in other locales than English, I considered Locale.ENGLISH a fairly safe bet. Please substitute your own.
The other answers were fine answers in 2010 and 2011. Already in 2014 the above was valid and I would have preferred it.
I am taking an example of date given below and print the formatted date into 24-hour format if suits your requirement.
String inputdate="9/1/10 11:34:35 AM";
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("dd/MM/yy hh:mm:ss aa",Locale.getDefault());
try {
System.out.println(""+new SimpleDateFormat("dd/MM/yy HH:mm:ss",Locale.getDefault()).format(simpleDateFormat.parse(inputdate)));
} catch (ParseException e) {
e.printStackTrace();
}
If you still have any query, Please respond. Thanks.
java.time
You can build a case-insensitive parser using DateTimeFormatterBuilder. Since a date-time parsing/formatting type (e.g. DateTimeFormatter, SimpleDateFormat etc.) is Locale-sensitive, you should always use a Locale with such a type. I've used Locale.ENGLISH because your date-time string has AM/PM marker in English.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
import java.util.stream.Stream;
public class Main {
public static void main(String args[]) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("M/d/uu H:m:s a")
.toFormatter(Locale.ENGLISH);
//Test
Stream.of(
"9/1/10 11:34:35 AM",
"9/1/10 11:34:35 am",
"09/1/10 11:34:35 AM",
"9/01/10 11:34:35 Am"
).forEach(s -> System.out.println(LocalDateTime.parse(s, dtf)));;
}
}
Output:
2010-09-01T11:34:35
2010-09-01T11:34:35
2010-09-01T11:34:35
2010-09-01T11:34:35
Learn more about the the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
If you are working with FreeMarker for Java and pop on this issue use below code. I had this problem, my locale set AM/PM as DE. Not sure why...
<#setting locale="en_US">
Just a note about Locale:
the symbols used for AM/PM depend on Locale!
This affects parsing strings, eventually causing errors if the used AM/PM field does not match the predefined symbols. (obviously also affects formatting)
java.time.format.DateTimeFormatter and java.text.SimpleDateFormat accept an optional Locale when being created. If none is given. the systems default one is used.
Warning: using DateTimeFormatter the case of the AM/PM flag is also relevant when parsing, at least for some locales.
As an example, the Indian Locale requires the AM/PM flag being lowercase (am, pm), while some other locales (ROOT, ITALY, US, GERMANY) only accept uppercase AM/PM.
This throws DateTimeParseException: Text '2021-03-31 10:15:30 AM +05:30' could not be parsed at index 20
ZonedDateTime.parse("2021-03-31 10:15:30 AM +05:30",
DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss a Z",
new Locale("en", "IN")))
This results in 2021-03-31T10:15:30+05:30
ZonedDateTime.parse("2021-03-31 10:15:30 am +05:30",
DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss a Z",
new Locale("en", "IN")))
Using Locale.US, Locale.GERMANY or Locale.ROOT, the results are inverted.
Note: case of AM/PM does not matter when parsing with SimpleDateFormat (I am not recommending its use, I prefer DateTimeFormatter)