How to Change the Date Format in Java

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 DateFormatters

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 Dates. 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



Leave a reply



Submit