How to get a weekday name in a given language in Java using Locale and GregorianCalendar?

Viewed 5213

I am facing some serious difficulties with an exercise where I am to write a simple program which would give a weekday name (not an int value) as an output. What`s more, it should be a weekday 90 days in the future from current date and it should be displayed in a local language (Danish).

I am a beginner and am seeking hints on how I should do this.

The important part of the exercise is that I cannot use more classes, than those imported (see below code).

What I found by myself is how to get the current date and present it as a weekday (I know it starts counting from 1 since Sunday), but I have no clue how to force it to show this integer as a weekday name in local language.

    package days01;

import java.text.SimpleDateFormat;
import java.util.Scanner;
import java.util.Locale;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Calendar;

public class Dates {
   public static void main(String[] argv) {
      Calendar one = new GregorianCalendar();
      int day = one.get(Calendar.DAY_OF_WEEK);
      System.out.println(day);
   }
}

The expected output should be a single weekday name 90 in future from current date.

3 Answers

If you must use the old-style API then DateFormatSymbols is useful to retrieve the day names.

import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;

public class DayNameExample {

   public static String getDayName(int day, Locale locale) {
      DateFormatSymbols symbols = new DateFormatSymbols(locale);
      String[] dayNames = symbols.getWeekdays();
      return dayNames[day];
    }

   public static void main(String[] args) {
      Calendar c = new GregorianCalendar();
      c.add(Calendar.DAY_OF_MONTH, 90);
      int dow = c.get(Calendar.DAY_OF_WEEK);

      System.out.println (DayNameExample.getDayName(dow, new Locale("da", "DK") ));

   }
}

This is an obsolete API; you should be using java.time instead. If your course material enforces this, that.. just makes it bad course material. The exercise is clearly meant to teach you familiarity with this specific API.

One of the many reasons this API has been obsoleted is because it is confusing and hard to use. So, that doesn't help.

In the new style API, this is very, very simple:

void go() {
    LocalDate today = LocalDate.now();
    LocalDate ninetyDaysLater = today.plusDays(90);
    DayOfWeek dayOfWeek = ninetyDaysLater.getDayOfWeek();
    Locale danish = new Locale("da", "DK");
    System.out.println(dayOfWeek.getDisplayName(TextStyle.FULL, danish));
}

In the old one, oof. Let's see:

void go() {
    Calendar c = new GregorianCalendar();
    c.add(Calendar.DAY_OF_MONTH, 90); // Why day of month? Just cuz. I mentioned this API is bad, right?
    int dow = c.get(Calendar.DAY_OF_WEEK);
    System.out.println(weekDayInDanish(dow));
}

static String weekDayInDanish(int dow) {
    switch (dow) {
        case Calendar.MONDAY: return "Mandag";
        case Calendar.TUESDAY: return "Tirsdag";
        // the rest of the cases here
        default: throw new IllegalArgumentException("Unexpected day: " + dow);
    }
}

Without using the new API, you have to do your own translate and can't rely on the system doing it for you. It's also all int based, so trying to debug is mostly an exercise of trying to figure out what all the arbitrary numbers mean.

Stick to the new API, the top snippet. Much cleaner.

Recommended solution: java.time

Use the first snippet in the answer by rzwitserloot.

Discouraged solution: Do what the teacher says

Even if we’re restricted to using the poorly designed and long outdated classes from Java 1.0 and 1.1, it can IMHO be done slightly more elegantly than in the other answers. I am using the notoriously troublesome SimpleDateFormat class. Those who know me on Stack Overflow may hate me for posting an example of using this class, and I accept any downvotes!

    TimeZone denmark = TimeZone.getTimeZone("Europe/Copenhagen");
    Locale danish = Locale.forLanguageTag("da-DK");
    DateFormat dayOfWeekFormatter = new SimpleDateFormat("EEEE", danish);
    Calendar one = new GregorianCalendar(denmark, danish);
    one.add(Calendar.DATE, 90);
    String dayOfWeekString = dayOfWeekFormatter.format(one.getTime());
    System.out.println(dayOfWeekString);

Output when running today (Wednesday October 30):

tirsdag

(It means Tuesday.)

Passing a time zone to the GregorianCalendar makes sure we get today’s date in that time zone. It is never the same date in all time zones. We hadn’t needed to specify a locale in this case, it controls on which day of the week a new week begins (Monday in Denmark since we follow the international standard), which we don’t use here, so I just did it for good measure.

I repeat: Don’t use this in production code. Today we have so much better in java.time, the modern Java date and time API.

Related