String req  ="0229191315"

private static DateFormat dateFrmtGmt - new SimpleDateFormat ("EEE MMM d HH:mm:ss z yyyy", Locale.ENGLISH);


SimpleDateFormat sdf=new SimpleDateFormat( "MMddHHmmss");

cal.setTime(sdf.parse(gmtDate));
cal.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));

dateFrmtGmt.setTimeZone(TimeZone.getTimeZone("GMT"));

return cal;

String = "0229191315" returns Fri Mar 1 19:13:15 GMT 2024

While string="0301191315" returns Fri 1 mar 19:13:15 GMT 2024

For all the dates it is setting correct date and time but for 28 and 29 Jan 2024 settings value as 29 Feb and 1 March respectively .

2

There are 2 best solutions below

0
aled On

The issue is that you are parsing the input without a year. Looking at the documentation of the SimpleDateFormat.parse() method.

the year value of the parsed Date is 1970 with GregorianCalendar if no year value is given from the parsing operation.

Since year 1970 didn't had a February 29 date the parse returned March 1. After that you set the actual year but the date remains as it was parsed.

See a modern approach to resolve this issue using the java.time package in this answer: https://stackoverflow.com/a/44470949/721855

0
g00se On

Per @Anonymous: Use DateTimeFormatterBuilder and OffsetDateTime, both from java.time, the modern Java date and time API. Don’t use SimpleDateFormat, Calendar and TimeZone since they had severe design problems and have been outdated the last 10 years.

Define a constant PARSER as:

private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
        .appendPattern("MMddHHmmss")
        .parseDefaulting(ChronoField.YEAR, Year.now(ZoneOffset.UTC).getValue())
        .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
        .toFormatter();

Or depending on exact requirements you may need to instantiate the parser for each use so you always get the current year, not the year when the parser was created.

Offsets are from GMT or UTC. We can regard GMT and UTC as the same thing for now. So defaulting offset in seconds to 0 means defaulting to UTC, which gives you the GMT time as in your question.

Then parse into an OffsetDateTime using:

OffsetDateTime d = OffsetDateTime.parse(req, PARSER);

This yields 2024-02-29T19:13:15Z. The trailing Z denotes UTC.