user2041390
user2041390

Reputation: 53

Java SimpleDateFormat decrementing date by one day

I am trying to reformat a date string using sdf. SDF is decrementing the date by a day. Pointers would be helpful.

java version "1.8.0_31" Input: ChangeDateStringFormat("10-Mar-2015");

Code:

public static String ChangeDateStringFormat (String Input) throws InterruptedException 
{           
    System.out.print("Input Date inside ChangeDateStringFormat : " + Input );

    SimpleDateFormat sdf = new SimpleDateFormat("MMM-dd-yyyy");
    sdf.setTimeZone(TimeZone.getTimeZone("MST"));

    System.out.print(" || Output Date inside ChangeDateStringFormat : " +  sdf.format(new Date(Input)) + "\n");
    return sdf.format(new Date(Input));
}

Output Actual:

Input Date inside ChangeDateStringFormat : 10-Mar-2015 || Output Date inside ChangeDateStringFormat : Mar-09-2015

Output I was Expecting :

Input Date inside ChangeDateStringFormat : 10-Mar-2015 || Output Date inside ChangeDateStringFormat : Mar-10-2015

Upvotes: 0

Views: 3551

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 78985

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Solution using java.time, the modern Date-Time API:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(changeDateStringFormat("10-Mar-2015"));
    }

    static String changeDateStringFormat(String input) {
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("d-MMM-u", Locale.ENGLISH);
        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("MMM-dd-uuuu", Locale.ENGLISH);

        LocalDate date = LocalDate.parse(input, dtfInput);
        
        return date.format(dtfOutput);
    }
}

Output:

Mar-10-2015

ONLINE DEMO

Note: Never use SimpleDateFormat or DateTimeFormatter without a Locale.

Learn more about the modern Date-Time API from Trail: Date Time.

Side Note: Always follow Java naming conventions e.g. the name of your function should be changeDateStringFormat instead of ChangeDateStringFormat and the parameter Input should be named as input.


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

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499770

This is the problem:

new Date(Input)

You should not use that. Instead, construct a SimpleDateFormat to parse your input:

import java.text.*;
import java.util.*;

public class Test {
    public static void main(String[] args) throws ParseException {
        System.out.println(convertDateFormat("10-Mar-2015"));
    }

    public static String convertDateFormat(String input) throws ParseException {
        TimeZone zone = TimeZone.getTimeZone("MST");
        SimpleDateFormat inputFormat = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
        inputFormat.setTimeZone(zone);
        SimpleDateFormat outputFormat = new SimpleDateFormat("MMM-dd-yyyy", Locale.US);
        outputFormat.setTimeZone(zone);

        Date date = inputFormat.parse(input);
        return outputFormat.format(date);
    }
}

However:

  • If you're just parsing a date, you'd be better of specifying UTC as the time zone; you don't want to end up with problems due to time zones that switch DST at midnight
  • If you're going to run this code on Java 8 and nothing lower, I'd strongly recommend using java.time instead of Date, Calendar etc.

Upvotes: 4

Related Questions