0

I'm replacing a placeholder in my Word template with a date range like this

//...getting from and to dates
String format = "%1$-3tb %1$tY - %2$-3tb %2$tY";
dateString = String.format(format, from, to);
//...retrieving the Text object...
textElement.setValue(dateString);

The console output looks nice:

Nov 2016 - Nov 2016
Jan 2016 - Jan 2016
Jul 2012 - Mär 2005

But the Word file is ugly:
enter image description here

Two questions:

  1. (Side question) How can I make the months to have a dot if they're not fully written out: So "May" should stay like that but "Nov" should turn into "Nov."
  2. (Main question) How can I fix the horizontal spacing issue?
Cold_Class
  • 3,214
  • 4
  • 39
  • 82
  • What would you want the horizontal spacing to be like? It may be just me, but I didn’t notice it was very ugly. – Ole V.V. Sep 17 '18 at 12:58
  • A bit related: [SimpleDateFormat with German Locale - Java 8 vs Java 10](https://stackoverflow.com/questions/50411064/simpledateformat-with-german-locale-java-8-vs-java-10) – Ole V.V. Sep 17 '18 at 20:09
  • 2
    Use a fixed width font (eg Courier or Consolas)? – JasonPlutext Sep 17 '18 at 20:42
  • A great step forward, @JasonPlutext. It still won’t make `Mai` (no dot) and `Nov.` (with dot) the same width, though. – Ole V.V. Sep 18 '18 at 06:54

1 Answers1

1

The easy answer to the side question is: upgrade to Java 9 or later.

    YearMonth from = YearMonth.of(2012, Month.MAY);
    YearMonth to = YearMonth.of(2013, Month.NOVEMBER);

    String format = "%1$-3tb %1$tY - %2$-3tb %2$tY";
    String dateString = String.format(Locale.GERMAN, format, from, to);

    System.out.println(dateString);

Mai 2012 - Nov. 2013

Java gets its locale data — including the month abbreviations used in different languages — from up to four sources. Up to and including Java 8 the default was Java’s own, but at least in Java 8 Unicode’s Common Locale Data Repository, CLDR, are distributed with Java too (not sure about Java 7). From Java 9 CLDR data are the default, but Java’s own are avaiable as COMPAT. The system property java.locale.providers controls which locale data to use. So I had expected that setting this property to CLDR or CLDR,JRE would work on Java 8, but on my Java 8 it doesn’t, Seems CLDR data are not the same in both Java versions.

In any case, while Java’s own German month abbreviations are without dots, in CLDR German month abbreviations in Java 9 are with dot. Month names up to four letters (Mai, Juni and Juli) are written in full without dot.

Java 8 answer to the side question: java.time, the modern Java date and time API allows us to define our own texts. For example:

    Map<Long, String> monthTexts = new HashMap<>(16);
    monthTexts.put(1L, "Jan.");
    monthTexts.put(2L, "Feb.");
    monthTexts.put(3L, "Mär.");
    monthTexts.put(4L, "Apr.");
    monthTexts.put(5L, "Mai");
    monthTexts.put(6L, "Jun.");
    monthTexts.put(7L, "Jul.");
    monthTexts.put(8L, "Aug.");
    monthTexts.put(9L, "Sep.");
    monthTexts.put(10L, "Okt");
    monthTexts.put(11L, "Nov.");
    monthTexts.put(12L, "Dez.");
    DateTimeFormatter monthFormatter = new DateTimeFormatterBuilder()
            .appendText(ChronoField.MONTH_OF_YEAR, monthTexts)
            .appendPattern(" u")
            .toFormatter();

    String dateString = from.format(monthFormatter) + " – " + to.format(monthFormatter);

    System.out.println(dateString);

Mai 2012 – Nov. 2013

Java 6 and 7 answer to the side question: get the ThreeTen Backport Library and do as in Java 8 (link at the bottom).

For the main question I don’t think I understood it. If what you want is that the ‘to’ months line up vertically, I think you need two columns in your docx document rather than one. You may specify that no vertical line be drawn between those two specific columns so the reader will see it as one.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • What type should `from` and `to` be of in your example? Thanks, this is very helpful - I'm on Java 8 and now I'm eager to upgrade, but it'll take some time so for now I'll have to go with your Java 8 solution. – Cold_Class Sep 18 '18 at 09:06
  • 1
    When I tested, I used `YearMonth` as in the Java 9 snippet (that class is in Java 8 too), but any java.time class that holds a year and a month will do (`LocalDate`, `LocalDateTime`, `OffsetDateTime`, `ZonedDateTime`; pick the one that matches best what you need it to represent). – Ole V.V. Sep 18 '18 at 09:13
  • Thanks, I tried Date and DateTime unsuccessfully before - that was my problem, now it works :) – Cold_Class Sep 18 '18 at 10:56