Bonjour à tous,

j'ai un problème lié au formatage de date au format Année / Semaine.

Je suis obligé de faire fonctionner SimpleDateFormat pour cela (ETL Talend qui génère du code Java).

Le problème est assez simple : je me suis aperçu d'un souci de formatage de date au format Année / Semaine ; en creusant, je pense avoir identifié qu'il s'agit d'un souci de locale, mais je n'arrive pas à mettre le doigt sur un élément du problème final.

J'ai reproduit le souci avec un petit code Java assez simple que voici :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.sql.Date;
import java.util.Locale;
import java.util.Calendar;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;
 
import java.time.LocalDate;
import java.time.temporal.WeekFields;
 
public class TestDate {
    public static void main(String args[]) throws ParseException {
        Locale currentLocale = Locale.getDefault();
 
        System.out.println(System.getProperty("java.vendor"));
        System.out.println(System.getProperty("java.version"));
        System.out.println("==============");
        System.out.printf("%20s = %s%n", "getDisplayLanguage", currentLocale.getDisplayLanguage());
        System.out.printf("%20s = %s%n", "getDisplayCountry", currentLocale.getDisplayCountry());
 
        System.out.printf("%20s = %s%n", "getLanguage", currentLocale.getLanguage());
        System.out.printf("%20s = %s%n", "getCountry", currentLocale.getCountry());
 
        System.out.printf("%20s = %s%n", "user.country", System.getProperty("user.country"));
        System.out.printf("%20s = %s%n", "user.language", System.getProperty("user.language"));
        System.out.printf("%20s = %s%n", "user.variant", System.getProperty("user.variant"));
 
        System.out.println("==============");
 
        Calendar c = Calendar.getInstance();
        System.out.println("1st day of week / minimal days in 1st week : " + c.getFirstDayOfWeek() + " / " + c.getMinimalDaysInFirstWeek());
 
        System.out.println("==============");
 
        LocalDate date1 = LocalDate.of(2020, 12, 31);
        LocalDate date2 = LocalDate.of(2021, 1, 1);
 
        DateFormat df_date = new java.text.SimpleDateFormat("dd/MM/yyyy");
        DateFormat df_week = new java.text.SimpleDateFormat("YYYY-ww");
 
        System.out.printf("%20s | %10s | %10s%n", "", df_date.format(java.sql.Date.valueOf(date1)), df_date.format(java.sql.Date.valueOf(date2)));
        System.out.printf("%20s | %10s | %10s%n", "SimpleDateFormat", df_week.format(java.sql.Date.valueOf(date1)), df_week.format(java.sql.Date.valueOf(date2)));
 
        System.out.printf("%20s | %7d-%02d | %7d-%02d%n", "WeekFields",
                                        date1.get(WeekFields.ISO.weekBasedYear()), date1.get(WeekFields.ISO.weekOfWeekBasedYear()),
                                        date2.get(WeekFields.ISO.weekBasedYear()), date2.get(WeekFields.ISO.weekOfWeekBasedYear()));
 
    }
}
Je le lance 2 fois avec des paramètres JVM différents (je force les arguments -Duser.language=en -Duser.country=US -Duser.variant= dans le second lancement pour reproduire le premier) mais sur la même machine (un serveur Windows configuré en US) et voici le résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
>java TestDate
Azul Systems, Inc.
1.8.0_282
==============
  getDisplayLanguage = English
   getDisplayCountry = United States
   getDisplayVariant =
         getLanguage = en
          getCountry = US
        user.country = US
       user.language = en
        user.variant =
==============
1st day of week / minimal days in 1st week : 2 / 4
==============
                     | 31/12/2020 | 01/01/2021
    SimpleDateFormat |    2020-53 |    2020-53
          WeekFields |    2020-53 |    2020-53
 
>java -Duser.language=en -Duser.country=US -Duser.variant= TestDate
Azul Systems, Inc.
1.8.0_282
==============
  getDisplayLanguage = English
   getDisplayCountry = United States
   getDisplayVariant =
         getLanguage = en
          getCountry = US
        user.country = US
       user.language = en
        user.variant =
==============
1st day of week / minimal days in 1st week : 1 / 1
==============
                     | 31/12/2020 | 01/01/2021
    SimpleDateFormat |    2021-01 |    2021-01
          WeekFields |    2020-53 |    2020-53
D'après la première partie des logs et ce que j'ai pu glaner dans mes recherches sur le net, les locales des deux exécutions semblent strictement identiques.

Pourtant, le résultat de l'affichage de la date au format année-semaine diffère entre les 2 lancements :
2020-53 pour le premier contre 2021-01 pour le second
Techniquement parlant, le résultat attendu pour une locale en_US serait d'après moi 2021-01.
C'est d'ailleurs ce que j'obtiens dans les 2 exécutions du même programme sous Linux.

Pourquoi, dans l'un des cas sous Windows, j'ai un calcul ISO de la semaine et pas dans l'autre cas ?
Quelle est le paramétrage (et le log) manquant qui expliquerait cela svp ?

Merci pour votre aide !