EN VI

Java - Execute Date arithmetic without daylight saving adjustment?

2024-03-12 06:30:06
How to Java - Execute Date arithmetic without daylight saving adjustment

I want to parse a Date from a String in NYC timezone, add 1 day and then output string.

like:

  1. parse to date
  2. add 1 day
  3. output

The problem is, that when I parse a date during the adjustment for daylight saving, the day in step 1 already will have extra hour and when I add 1 day, the next day will have that extra hour which is wrong for the next day, due next Day is not the day when daylight saving adjustment happens.

example:

input date March 10 2am

parsed date: March 10 3am

add 1 day => March 11 3am // has to be March 11 2am

But if you parse directly March 11 2am, then it's correct:

input date March 11 2am

parsed date => March 11 2am

So, I need to parse a Date, add 1 day and only after that execute that smart adjustment:

input date March 10 2am

parsed date: March 10 2am //do not be smart here, still 2 am

add 1 day => March 11 2am // here you can be smart and adjust for daylight saving if needed

this code is incorrect and shows 7am March 11 instead of 6am

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class MainApp {

    public static void main(String[] args) {
        try {
            SimpleDateFormat in = new SimpleDateFormat("yyyyMMdd-HH.mm");
            in.setTimeZone(TimeZone.getTimeZone("America/New_York"));
            

            Date date = in.parse("20240310-02.00");
            
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_YEAR, 1);
            date = calendar.getTime();
            
            System.out.println(in.format(date)); // prints 20240311-03.00, but has to be 20240311-02.00
            
            //parse 11 march directly, works ok
            Date date2 = in.parse("20240311-02.00");
            System.out.println(in.format(date2)); // prints 20240311-02.00
            
            
        } catch (ParseException e) {e.printStackTrace();}       
    }
}

Solution:

java.time

I recommend you avoid using the outdated and error-prone java.util date/time API and do it using the modern date/time API, java.time.

Your given date-time string does not have time zone information. Therefore, you should parse it to a LocalDateTime instance.

Demo:

public class Main {
    public static void main(String[] args) {
        String strDateTime = "20240310-02.00";
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMdd-HH.mm", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
        LocalDateTime nextDate = ldt.plusDays(1);
        System.out.println(ldt);
        System.out.println(nextDate);

        // In case you need to format nextDate in the input format
        System.out.println(nextDate.format(dtf));
    }
}

Output:

2024-03-10T02:00
2024-03-11T02:00
20240311-02.00

Online Demo

You can convert a LocalDateTime into a ZonedDateTime by applying a ZoneId.

ZoneId zoneId = ZoneId.of("America/New_York");
ZonedDateTime zdt = ZonedDateTime.of(nextDate, zoneId);
System.out.println(zdt);

Output:

2024-03-11T02:00-04:00[America/New_York]

Learn about the modern date-time API from Trail: Date Time

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login