How can I change the date format in Java?
How to convert from one date format to another using SimpleDateFormat:
final String OLD_FORMAT = "dd/MM/yyyy";
final String NEW_FORMAT = "yyyy/MM/dd";
// August 12, 2010
String oldDateString = "12/08/2010";
String newDateString;
SimpleDateFormat sdf = new SimpleDateFormat(OLD_FORMAT);
Date d = sdf.parse(oldDateString);
sdf.applyPattern(NEW_FORMAT);
newDateString = sdf.format(d);
java.util.Date format conversion yyyy-mm-dd to mm-dd-yyyy
Date
is a container for the number of milliseconds since the Unix epoch ( 00:00:00 UTC on 1 January 1970).
It has no concept of format.
Java 8+
LocalDateTime ldt = LocalDateTime.now();
System.out.println(DateTimeFormatter.ofPattern("MM-dd-yyyy", Locale.ENGLISH).format(ldt));
System.out.println(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH).format(ldt));
System.out.println(ldt);
Outputs...
05-11-2018
2018-05-11
2018-05-11T17:24:42.980
Java 7-
You should be making use of the ThreeTen Backport
Original Answer
For example...
Date myDate = new Date();
System.out.println(myDate);
System.out.println(new SimpleDateFormat("MM-dd-yyyy").format(myDate));
System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(myDate));
System.out.println(myDate);
Outputs...
Wed Aug 28 16:20:39 EST 2013
08-28-2013
2013-08-28
Wed Aug 28 16:20:39 EST 2013
None of the formatting has changed the underlying Date
value. This is the purpose of the DateFormatter
s
Updated with additional example
Just in case the first example didn't make sense...
This example uses two formatters to format the same date. I then use these same formatters to parse the String
values back to Date
s. The resulting parse does not alter the way Date
reports it's value.
Date#toString
is just a dump of it's contents. You can't change this, but you can format the Date
object any way you like
try {
Date myDate = new Date();
System.out.println(myDate);
SimpleDateFormat mdyFormat = new SimpleDateFormat("MM-dd-yyyy");
SimpleDateFormat dmyFormat = new SimpleDateFormat("yyyy-MM-dd");
// Format the date to Strings
String mdy = mdyFormat.format(myDate);
String dmy = dmyFormat.format(myDate);
// Results...
System.out.println(mdy);
System.out.println(dmy);
// Parse the Strings back to dates
// Note, the formats don't "stick" with the Date value
System.out.println(mdyFormat.parse(mdy));
System.out.println(dmyFormat.parse(dmy));
} catch (ParseException exp) {
exp.printStackTrace();
}
Which outputs...
Wed Aug 28 16:24:54 EST 2013
08-28-2013
2013-08-28
Wed Aug 28 00:00:00 EST 2013
Wed Aug 28 00:00:00 EST 2013
Also, be careful of the format patterns. Take a closer look at SimpleDateFormat
to make sure you're not using the wrong patterns ;)
Change date format dd-MM-yyyy to yyyy-MM-dd in Java
Try this (see update below)
try {
String startDateString = "08-12-2017";
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(sdf2.format(sdf.parse(startDateString)));
} catch (ParseException e) {
e.printStackTrace();
}
Update - Java 8
String startDateString = "08-12-2017";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println(LocalDate.parse(startDateString, formatter).format(formatter2));
How to change dynamically date format
java.time.Duration
Assuming that your string denotes an amount of time (for example, a duration), the right class to use for it in Java is Duration
from java.time, the modern Java date and time API. Unfortunately Duration
cannot parse your strings out of the box. It has a parse
method that only accepts ISO 8601 format. ISO 8601 format for a duration goes like for example PT1H48M30S
. It looks unusual at first, but is straightforward to read when you know how. Read the example just given as a period of time of 1 hour 48 minutes 30 seconds. So to parse your strings in hh:mm:ss and mm:ss format I first convert them to ISO 8601 using a couple of regular expressions.
// Strings can be hh:mm:ss or just mm:ss
String[] examples = { "01:48:30", "26:57" };
for (String example : examples) {
// First try to replace form with two colons, then form with one colon.
// Exactly one of them should succeed.
String isoString = example.replaceFirst("^(\\d+):(\\d+):(\\d+)$", "PT$1H$2M$3S")
.replaceFirst("^(\\d+):(\\d+)$", "PT$1M$2S");
Duration dur = Duration.parse(isoString);
System.out.format("%8s -> %-10s -> %7d milliseconds%n", example, dur, dur.toMillis());
}
In addition my code also shows how to convert each duration to milliseconds. Output is:
01:48:30 -> PT1H48M30S -> 6510000 milliseconds
26:57 -> PT26M57S -> 1617000 milliseconds
Links
- Oracle tutorial: Date Time explaining how to use java.time.
- Wikipedia article: ISO 8601
How to change the date format of List<Date>
tl;dr
format.parse( Info.get("TIME") ) // Get a legacy `java.util.Date` object.
.toInstant() // Convert from legacy class to modern class.
.atOffset( // Convert from the basic `Instant` class to the more flexible `OffsetDateTime` class.
ZoneOffset.UTC // Specify the offset-from-UTC in which you want to view the date and time-of-day.
)
.format( // Generate text representing the value of our `OffsetDateTime` object.
DateTimeFormatter.ofPattern( "dd/MM/yyyy HH:mm:ss" ) // Specify your custom formatting pattern. Better to cache this object, in real work.
) // Returns a `String
Date
was replaced years ago by Instant
. The Instant::toString
method uses a much better format, a modern standard format.
Instant.now().toString()
2019-06-04T20:11:18.607231Z
Convert your Date
objects, myDate.toInstant()
.
Details
The Object::toString
method is not meant to be flexible. Its purpose is to to provide a simplistic view of an object while debuggig or logging.
However, as you have seen, the java.util.Date::toString
implementation is terrible.
First it lies, applying the JVM’s current default time zone to the moment stored in the Date
object. That moment is actually in UTC. This misreporting creates the illusion of a time zone that is not actually in the object.
Secondly, the Date::toString
method uses a terrible format, English only, difficult to read by humans, and difficult to parse by machine.
The Date
class has many other problems. You should no longer use this class at all. With the adoption of JSR 310, it was supplanted by the java.time.Instant
class.
You should replace Date
with Instant
wherever you can. Where you cannot, convert. Call new methods added to the old classes.
Instant instant = myJavaUtilDate.toInstant() ;
Fortunately, the toString
method on Instant
is much better designed. It tells you the truth, a moment in UTC. And it uses the standard ISO 8601 formats. That standard was invented expressly for communicating date-time values as text in a way that is both easy to parse by machine and easy to read by humans across cultures.
String output = instant.toString() ;
2019-06-04T20:11:18.607231Z
So a list of Instant
objects will look like this.
Instant now = Instant.now();
List < Instant > instants = List.of( now.minus( 1L , ChronoUnit.HOURS ) , now , now.plus( 20L , ChronoUnit.MINUTES ) );
String output = instants.toString();
[2019-06-04T19:41:51.210465Z, 2019-06-04T20:41:51.210465Z, 2019-06-04T21:01:51.210465Z]
Your code snippet
As for your code snippet, convert to a java.time.OffsetDateTime
object, and generate text using a custom-defined formatting pattern.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/yyyy HH:mm:ss" ) ;
…
if(Info.get("TIME")!=null)
{
try {
Date date = format.parse( Info.get("TIME") ) ;
Instant instant = date.toInstant() ;
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
String output = odt.format( f ) ;
message.TimeHistory.add(date);
}
catch (Exception e){
}
}
Java Date changing format
Please try to keep two concepts apart: your data and the presentation of the data to your user (or formatting for other purposes like inclusion in JSON). An int
holding the value 7 can be presented as (formatted into) 7, 07, 007 or +7 while still just holding the same value without any formatting information — the formatting lies outside the int
. Just the same, a Date
holds a point in time, it can be presented as (formatted into) “June 1st 2017, 12:46:01.169”, “2017/06/01” or “1 Jun 2017” while still just holding the same value without any formatting information — the formatting lies outside the Date
.
Depending on your requirements, one option is you store your date as a Date
(or better, an instance of one of the modern date and time classes like LocalDate
) and keep a formatter around so you can format it every time you need to show it to the user. If this won’t work and you need to store the date in a specific format, then store it as a String
.
Java 8 (7, 6) date and time API
Now I have been ranting about using the newer Java date and time classes in the comments, so it might be unfair not to show you that they work. The question tries to format as yyyy-MM-dd
, which we may do with the following piece of code.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu/MM/dd");
for (LocalDate date : localDates) {
String formatterDate = date.format(dateFormatter);
System.out.println(formatterDate);
}
In one run I got
2017/05/23
2017/06/01
Should your objects in the list have other types than LocalDate
, most other newer date and time types can be formatted in exactly the same way using the same DateTimeFormatter
. Instant
is a little special in this respect because it doesn’t contain a date, but you may do for example myInstant.atZone(ZoneId.of("Europe/Oslo")).format(dateFormatter)
to obtain the date it was/will be in Oslo’s time zone at that instant.
The modern classes were introduced in Java 8 and are enhanced a bit in Java 9. They have been backported to Java 6 and 7 in the ThreeTen Backport with a special edition for Android, ThreeTenABP. So I really see no reason why you should not prefer to use them in your own code.
Change Date Format Java
You can definitely use the approach that utilizes a list of possible or expected patterns and give each one a try
, but you should use the most optimized library for it instead of one which is only still alive due to a mass of legacy code referencing it.
tl;dr
Your friends for this task (since Java 8) are
java.time.LocalDate
java.time.format.DateTimeFormatter
java.time.format.DateTimeFormatterBuilder
java.time.format.DateTimeParseException
Here's an example:
public static void main(String[] args) {
// start with an example String
String oldDateString = "16-OCT-19";
// build up a list of possible / possibly expected patterns
List<String> patterns = List.of(
"dd-MM-uu", "dd-MMM-uu", "dd-MMMM-uu",
"dd-MM-uuuu", "dd-MMM-uuuu", "dd-MMMM-uuuu"
);
// then build a formatter for the desired output
DateTimeFormatter outFmt = DateTimeFormatter.ofPattern("dd/MM/uuuu");
// for each pattern in your list
for (String pattern : patterns) {
try {
// build a formatter that
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
// doesn't care about case
.parseCaseInsensitive()
// uses the current pattern and
.appendPattern(pattern)
// considers the language/locale
.toFormatter(Locale.ENGLISH);
// then try to parse the String with that formatter and
LocalDate localDate = LocalDate.parse(oldDateString, dtf);
// print it using the desired output formatter
System.out.println(localDate.format(outFmt));
// finally stop the iteration in case of success
break;
} catch (DateTimeParseException dtpEx) {
// build some meaningful statements
String msg = String.format(
"%s !\n ——> you cannot parse '%s' using pattern %s",
dtpEx.getMessage(), oldDateString, pattern);
// and print it for each parsing fail
System.err.println(msg);
}
}
}
Try it with different inputs and maybe extend the pattern list.
However, this code example fails for the first pattern in the list but the second one is a match, so this prints
Text '16-OCT-19' could not be parsed at index 3 !
——> you cannot parse '16-OCT-19' using pattern dd-MM-uu
16/10/2019
The remaining patterns are skipped.
String to date format and vice versa
java.time
I strongly recommend that you use java.time, the modern Java date and time API, for your date work.
It generally takes two formatters for converting a string date in one format to a string in another format: one for describing the format you got, and one for the required format. In this case the former is built in. For your required result define a formatter statically:
private static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(Locale.forLanguageTag("es-PA"));
The do:
String dateFormat = "20211109";
LocalDate start = LocalDate.parse(dateFormat, DateTimeFormatter.BASIC_ISO_DATE);
String string = start.format(DATE_FORMATTER);
System.out.println(string);
Output:
11/09/2021
For formatting I took the built-in medium date format for Panama since this is one of the locales where the format fits what you asked for. You should of course use your users’ locale, not the one of Panama, for an output format that they will recognize as their own. In this way we are saving ourselves the trouble of composing a format pattern string, and at the same time the code lends itself excellently to internationalization.
You shouldn’t want to convert from one string format to another
If you are asking how to convert a date from one string format to another, you are really asking the wrong question. In all but the smallest throw-away programs, we should not handle dates as strings, but always store them in LocalDate
objects. When we take string input, we parse. Only when we need to give string output, we format back.
Using a format pattern
If for one reason or another your users are not happy with Java’s localized format, and you need more control over the output format, you may use a format pattern as you tried in your question:
private static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofPattern("MM/dd/yyyy", Locale.ROOT);
Links
- Oracle tutorial: Date Time explaining how to use java.time.
- Wikipedia article: ISO 8601
- Related question: error output converting date format from YYYYMMDD to dd-mm-yyyy
- Related question: String to date format java
Related Topics
Including Jars in Classpath on Commandline (Javac or Apt)
How to Get the Cellrow When There Is an Itemevent in the Jcombobox Within the Cell
How to Change the Date Format in Java
Trust Store VS Key Store - Creating With Keytool
How to Send an Email by Java Application Using Gmail, Yahoo, or Hotmail
How to Set the Java.Library.Path from Eclipse
Does Gc Release Back Memory to Os
How to Run Eclipse in Clean Mode? What Happens If We Do So
Convert Arraylist≪String≫ to String[] Array
How to Enter Quotes in a Java String
Method Has the Same Erasure as Another Method in Type
How to Pass a Function as a Parameter in Java
How to Find Valid Certification Path to Requested Target - Error Even After Cert Imported
Java Order of Initialization and Instantiation
Catching Java.Lang.Outofmemoryerror