import java.time.*;
import java.util.Locale;

public class Test {

    private static final ZoneId ZONE_ID_EUROPE_BERLIN = ZoneId.of("Europe/Berlin");

    public static void main(final String[] args) {
// No Leap year
        final LocalDate date1 = LocalDate.of(2017, 03, 01);
        final Instant date1AsInstant = date1.atStartOfDay(ZONE_ID_EUROPE_BERLIN).toInstant();
        System.out.println(date1AsInstant.toString()); // Expected 2017-03-01T00:00:00Z but was 2017-02-28T23:00:00Z

        final Instant zonedDateTime1 = ZonedDateTime.of(2017, 03, 01, 00, 00, 00, 00, ZONE_ID_EUROPE_BERLIN)
                .toInstant();
        System.out.println(zonedDateTime1.atZone(ZONE_ID_EUROPE_BERLIN).toString()); // Expected 2017-03-01T00:00:00Z but was 2017-02-28T23:00:00Z

// Leap year
        final LocalDate date2 = LocalDate.of(2020, 03, 01);
        final Instant date2AsInstant = date2.atStartOfDay(ZONE_ID_EUROPE_BERLIN).toInstant();
        System.out.println(date2AsInstant.atZone(ZONE_ID_EUROPE_BERLIN)); // Expected 2020-03-01T00:00:00Z but was 2020-02-29T23:00:00Z

        final Instant zonedDateTime2 = ZonedDateTime.of(2020, 03, 01, 00, 00, 00, 00, ZONE_ID_EUROPE_BERLIN)
                .toInstant();
        System.out.println(zonedDateTime2); // Expected 2020-03-01T00:00:00Z but was 2020-02-29T23:00:00Z
    }

} 