0

Currently using the java.time.format.DateTimeFormatter to format an instant into a different zone, and when the zone override crosses backwards overtime to the previous year all date parts change except year. Examples:

import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;

public class Example {

    final static ZoneId NYC = ZoneId.of("America/New_York");
    final static ZoneId CHI = ZoneId.of("America/Chicago");
    
    final static DateTimeFormatter FMT_YEAR = DateTimeFormatter.ofPattern("YYYY");
    final static DateTimeFormatter FMT_YEAR_NYC = FMT_YEAR.withZone(NYC);
    final static DateTimeFormatter FMT_YEAR_CHI = FMT_YEAR.withZone(CHI);

    final static DateTimeFormatter FMT_YEAR_MONTH = DateTimeFormatter.ofPattern("YYYY-MM");
    final static DateTimeFormatter FMT_YEAR_MONTH_NYC = FMT_YEAR_MONTH.withZone(NYC);
    final static DateTimeFormatter FMT_YEAR_MONTH_CHI = FMT_YEAR_MONTH.withZone(CHI);

    final static DateTimeFormatter FMT_YEAR_MONTH_DAY = DateTimeFormatter.ofPattern("YYYY-MM-dd");
    final static DateTimeFormatter FMT_YEAR_MONTH_DAY_NYC = FMT_YEAR_MONTH_DAY.withZone(NYC);
    final static DateTimeFormatter FMT_YEAR_MONTH_DAY_CHI = FMT_YEAR_MONTH_DAY.withZone(CHI);

    public static void main(String[] args) {
        // Starting point at midnight on January 1, 2021
        ZonedDateTime pit = ZonedDateTime.of(2021,1,1,0,0,0,0,NYC);
        System.out.println("ZonedDateTime Constructed :");
        formatAndPrint("Year", pit, FMT_YEAR, FMT_YEAR_NYC, FMT_YEAR_CHI);
        formatAndPrint("YearMonth", pit, FMT_YEAR_MONTH, FMT_YEAR_MONTH_NYC, FMT_YEAR_MONTH_CHI);
        formatAndPrint("YearMonthDay", pit, FMT_YEAR_MONTH_DAY, FMT_YEAR_MONTH_DAY_NYC, FMT_YEAR_MONTH_DAY_CHI);
        
        pit = ZonedDateTime.parse("2021-01-01T00:00:00.000-05:00");
        System.out.println();
        System.out.println("ZonedDateTime Parsed :");
        formatAndPrint("Year", pit, FMT_YEAR, FMT_YEAR_NYC, FMT_YEAR_CHI);
        formatAndPrint("YearMonth", pit, FMT_YEAR_MONTH, FMT_YEAR_MONTH_NYC, FMT_YEAR_MONTH_CHI);
        formatAndPrint("YearMonthDay", pit, FMT_YEAR_MONTH_DAY, FMT_YEAR_MONTH_DAY_NYC, FMT_YEAR_MONTH_DAY_CHI);
        
        OffsetDateTime off = OffsetDateTime.parse("2021-01-01T00:00:00.000-05:00");
        System.out.println();
        System.out.println("OffsetDateTime Parsed :");
        formatAndPrint("Year", off, FMT_YEAR, FMT_YEAR_NYC, FMT_YEAR_CHI);
        formatAndPrint("YearMonth", off, FMT_YEAR_MONTH, FMT_YEAR_MONTH_NYC, FMT_YEAR_MONTH_CHI);
        formatAndPrint("YearMonthDay", off, FMT_YEAR_MONTH_DAY, FMT_YEAR_MONTH_DAY_NYC, FMT_YEAR_MONTH_DAY_CHI);
    }
    
    public static void formatAndPrint(String header, TemporalAccessor pit, 
            DateTimeFormatter fmt, DateTimeFormatter fmt_nyc, DateTimeFormatter fmt_chi){
        System.out.println(header + " - Default: " + fmt.format(pit));
        System.out.println(header + " - NYC: " + fmt_nyc.format(pit));
        System.out.println(header + " - CHI: " + fmt_chi.format(pit));
    }
}

produces:

ZonedDateTime Constructed :
Year - Default: 2021
Year - NYC: 2021
Year - CHI: 2021
YearMonth - Default: 2021-01
YearMonth - NYC: 2021-01
YearMonth - CHI: 2021-12
YearMonthDay - Default: 2021-01-01
YearMonthDay - NYC: 2021-01-01
YearMonthDay - CHI: 2021-12-31

ZonedDateTime Parsed :
Year - Default: 2021
Year - NYC: 2021
Year - CHI: 2021
YearMonth - Default: 2021-01
YearMonth - NYC: 2021-01
YearMonth - CHI: 2021-12
YearMonthDay - Default: 2021-01-01
YearMonthDay - NYC: 2021-01-01
YearMonthDay - CHI: 2021-12-31

OffsetDateTime Parsed :
Year - Default: 2021
Year - NYC: 2021
Year - CHI: 2021
YearMonth - Default: 2021-01
YearMonth - NYC: 2021-01
YearMonth - CHI: 2021-12
YearMonthDay - Default: 2021-01-01
YearMonthDay - NYC: 2021-01-01
YearMonthDay - CHI: 2021-12-31

Is my understanding/expectations off in thinking that Chicago should be represented in year 2020?

Running JVM 11.0.3+12-LTS

dfrugg
  • 26
  • 1

1 Answers1

0

YYYY is week based year. If you don't know what that means, I'll summarize: "The thing you never want".

You want uuuu. maybe yyyy, But probably uuuu. See javadoc of DTF.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • Thanks @rzwitserloot. That just made me question what I've been doing the last 20 years of working in Java. Fixed my zone problems. – dfrugg Feb 03 '21 at 17:00