How to format date to 'yyyy-MM-dd' using Apex

You didn't do the same thing in both examples:

String foo(Date input)
{ // your first example
    return DateTime.newInstance(
        input.year(), input.month(), input.day()
    ).format('yyyy-MM-dd');
}
String bar(Date input)
{ // your second example
    Datetime output = input;
    // Type Coercion  ^^^^^
    return output.format('yyyy-MM-dd');
}
String baz(Date input)
{ // another approach
    return DateTime.newInstance(
        input, Time.newInstance(0,0,0,0)
    ).format('yyyy-MM-dd');
}

system.debug(foo(Date.today()));
system.debug(bar(Date.today()));
system.debug(baz(Date.today()));

In your first example, you use foo, but in your second, you use bar. What you do in bar is called Type Coercion where you assign a Date to a Datetime. That gives it a Time instance of (0,0,0,0), but a Time Zone of GMT. So you could also fix bar by using formatGmt:

String qux(Date input)
{ // your second example rewritten
    Datetime output = input;
    return output.formatGmt('yyyy-MM-dd');
    //                  ^^^
}

You could also think about your original bar as being equivalent to a slight change in baz:

String quux(Date input)
{
    Datetime output = Datetime.newInstanceGmt(input, Time.newInstance(0,0,0,0));
    // now output is the same as it was in `bar`
    return output.format('yyyy-MM-dd');
}

You have the Datetime in the GMT Timezone, so you need to use formatGmt:

String garply(Date input)
{
    Datetime output = Datetime.newInstanceGmt(input, Time.newInstance(0,0,0,0));
    // now output is the same as it was in `bar`
    return output.formatGmt('yyyy-MM-dd');
    //                  ^^^
}

* What's after baz?


To format a Date object to YYYY-MM-DD, you just need one line:

String.valueOf(dateObject);