-2

I want to convert the format from "yyyyMMdd" to "ccyyMMdd" simpledateformat in java. I am getting "c" as illegal character in java. Please help me to find the slution to convert in to "ccyyMMdd" format in java Simpledateformat

What is the differnce betwen "cc" and "yy" in java?

Chitra
  • 13
  • 1
  • 7
  • 2
    https://stackoverflow.com/questions/33420395/what-does-ccyymmdd-date-format-mean/33420499 – Simon B Apr 15 '19 at 07:21
  • What did you expect to get with "cc"? – Ivar Apr 15 '19 at 07:26
  • https://stackoverflow.com/questions/6229347/how-to-get-century-from-date-in-java – Ulad Apr 15 '19 at 07:26
  • 1
    By the way, you should cease using `SimpleDateFormat`, and start using the new Java Date and Time API (in package `java.time`). – MC Emperor Apr 15 '19 at 08:07
  • I recommend you don’t use `SimpleDateFormat`. That class and its friends like `Date` are poorly designed and long outdated (`SimpleDateFormat` itself in particular notoriously troublesome). Instead use `DateTimeFormatter` and other classes from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Apr 15 '19 at 08:21
  • FYI, the terribly troublesome date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Apr 15 '19 at 21:35
  • Always search Stack Overflow before posting. – Basil Bourque Apr 15 '19 at 21:35

3 Answers3

2

The SimpleDateFormat doesn't support c for Century. But if you simply want a 4digit year, you can use yyyy

You can find the full list supported on the official doc of SimpleDateFormat

//import java.util.Date;
//import java.text.SimpleDateFormat;

String s = "190415";
SimpleDateFormat sdfIn = new SimpleDateFormat("yyMMdd");
SimpleDateFormat sdfout = new SimpleDateFormat("yyyyMMdd");

Date d = sdfIn.parse(s);
System.out.println("OLD : " + sdfout.format(d));

OLD : 20190415

As pointed, you should also switch to the new Java Date/Time API but you will find the same problem, DateTimeFormatter doesn't have any "century" feature.

//import java.time.LocalDate;
//import java.time.format.DateTimeFormatter;

String s = "190415";
DateTimeFormatter dtfIn = DateTimeFormatter.ofPattern("yyMMdd");
DateTimeFormatter dtfOut = DateTimeFormatter.ofPattern("yyyyMMdd");

LocalDate ld = LocalDate.parse(s, dtfIn);
System.out.println("NEW : " + dtfOut.format(ld));

NEW : 20190415

AxelH
  • 14,325
  • 2
  • 25
  • 55
1

Like the others I am assuming that cc is for century. So ccyy is the same as yyyy. Formatters for other languages than Java exist that accept cc or CC for century.

Edit: no conversion necessary

Since ccyy means yyyy, there is no conversion to do from yyyyMMdd to ccyyMMdd. The string you already got in yyyyMMdd format is also the string that you want.

Original answer

Originally you had asked for a conversion from yyMMdd to ccyyMMdd. For example, todays’s date would be converted from 190415 to 20190415.

To make that conversion correctly you need to know which century is intended. If the date is for a concert ticket to be sold, you can probably safely assume that the year is within the next 20 years (including current year). If it’s a birthday of a living person, you’re already screwed, sorry, because it might be in the last 110 years or more, so you cannot know whether 150415 means year 1915 or 2015, century 19 or 20. In any case, I recommend that you decide on a range of acceptable dates, best somewhat narrower than 100 years so that you have some validation and a chance to detect if some day a date violates your assumptions.

java.time

For the sake of the example let’s assume the date is within the last 30 or the coming 5 years (this allows us to obtain century 19 or 20 depending on the year).

    // The base year just needs to be before the minimum year
    // and at most 99 years before the maximum year
    int baseYear = Year.now().minusYears(40).getValue();

    DateTimeFormatter originalDateFormatter = new DateTimeFormatterBuilder()
            .appendValueReduced(ChronoField.YEAR, 2, 2, baseYear)
            .appendPattern("MMdd")
            .toFormatter();
    
    String originalDateString = "921126";
    LocalDate today = LocalDate.now(ZoneId.of("Africa/Bangui"));
    LocalDate date = LocalDate.parse(originalDateString, originalDateFormatter);
    if (date.isBefore(today.minusYears(30)) || date.isAfter(today.plusYears(5))) {
        System.out.println("Date " + originalDateString + " is out of range");
    } else {
        String ccyymmddDateString = date.format(DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println("String " + originalDateString + " was reformatted to " + ccyymmddDateString);
    }

Output when running today is:

String 921126 was reformatted to 19921126

Some other original strings yield:

String 200430 was reformatted to 20200430

Date 240430 is out of range

The format you want, yyyyMMdd, agrees with the built-in BASIC_ISO_DATE format, so I just use that to format the date.

I recommend you don’t use SimpleDateFormat. That class is notoriously troublesome and fortunately long outdated. Also SimpleDateFormat doesn’t let you control the interpretation of a 2-digit year the way I do above. Instead I am using DateTimeFormatter and other classes from java.time, the modern Java date and time API.

Link: Oracle tutorial: Date Time explaining how to use java.time.

Community
  • 1
  • 1
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

cc means century.

It's not possible to convert yyMMdd to ccyyMMdd, as you don't have full year in the initial date. For example, date 190415 may be in 21th century as well in 20th century.

Ulad
  • 1,083
  • 8
  • 17
  • Having a date like `190515` parse with `yyMMdd` will get you the year `2019`... – AxelH Apr 15 '19 at 07:58
  • Having date like `800415` will give you `1980`, because simple date format parser built in such way, but string `800415` may represent date `20800415` and `19800415` etc. – Ulad Apr 15 '19 at 08:10
  • Agreed, but there is no such thing as a date without a "century" context. With a two digit String, the full year will be based on the current year. `currentYear - 80 < value < currentYear + 20`. As of today, you can get a date in `16/04/1939 < value < 15/04/2039` – AxelH Apr 15 '19 at 08:22
  • Agreed, but this century context is conditionally created, so we don't have 1 to 1 match for such dates. – Ulad Apr 15 '19 at 09:10