简体   繁体   中英

get day of week as a string for a particular date in Java using Calendar class

I want to do this simple thing in Java. The correct answer is supposed to be 'WEDNESDAY'. What is wrong with this? I took the example from the documentation for the Calendar class.

import java.util.*;
import java.lang.Integer;

class Dumb {
  public static List<String> dows = Collections.unmodifiableList(Arrays.asList("SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"));

  public static String getDay(String day, String month, String year) {
   // get the supported ids for GMT-08:00 (Pacific Standard Time)
   String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000);
   // if no ids were returned, something is wrong. get out.
   if (ids.length == 0)
       System.exit(0);
   // create a Pacific Standard Time time zone
   SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]);
   // set up rules for Daylight Saving Time
   pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
   pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);

   // create a GregorianCalendar with the Pacific Daylight time zone
   // and the desired date and time
   Calendar calendar = new GregorianCalendar(pdt);
   calendar.set(Calendar.MONTH, Integer.valueOf(month));
   calendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(day));
   calendar.set(Calendar.YEAR, Integer.valueOf(year)); 

   // print out a bunch of interesting things
   System.out.println("SUNDAY: " + calendar.SUNDAY);
   System.out.println("MONDAY: " + calendar.MONDAY);
   System.out.println("TUESDAY: " + calendar.TUESDAY);
   System.out.println("WEDNESDAY: " + calendar.WEDNESDAY);
   System.out.println("THURSDAY: " + calendar.THURSDAY);
   System.out.println("FRIDAY: " + calendar.FRIDAY);
   System.out.println("SATURDAY: " + calendar.SATURDAY);
   System.out.println("YEAR: " + calendar.get(Calendar.YEAR));
   System.out.println("MONTH: " + calendar.get(Calendar.MONTH));
   System.out.println("DATE: " + calendar.get(Calendar.DATE));
   System.out.println("DAY_OF_WEEK: " + calendar.get(Calendar.DAY_OF_WEEK));
  int dow = calendar.get(Calendar.DAY_OF_WEEK);
  return dows.get(dow-1);
    }
}

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    String month = in.next();
    String day = in.next();
    String year = in.next();

    System.out.println(getDay(day, month, year));
}

}

This code produces the following output:

SUNDAY: 1 
MONDAY: 2
TUESDAY: 3
WEDNESDAY: 4
THURSDAY: 5
FRIDAY: 6
SATURDAY: 7
YEAR: 2015
MONTH: 8
DATE: 5
DAY_OF_WEEK: 7
SATURDAY

Because the month is zero based.

I should have subtracted 1 from the month.

argh

tl;dr

get day of week as a string for a particular date

  • You are working too hard.
  • You are using the wrong classes.

We can reduce your code to a one-liner:

LocalDate.of(                    // A date-only value, without time-of-day, without time zone.
    Integer.valueOf( "2018" ) ,  // Sane numbering. Ex: number `2018` is year 2018.
    Integer.valueOf( "1" ) ,     // Sane numbering. Months 1-12 are January-December.
    Integer.valueOf( "23" ) 
)                                // Returns a `LocalDate` object.
.getDayOfWeek()                  // Returns a `DayOfWeek` enum object.
.getDisplayName(                 // Calls a method on the enum object to automatically localize the name of the day-of-week.
    TextStyle.FULL ,             // Specify how long or abbreviated.
    Locale.US                    // Locale determines the human language and cultural norms used in localization.
)

See this code run live at IdeOne.com .

Tuesday

I suggest searching Stack Overflow before struggling with such code. This topic has been asked and answered many times already.

java.time

You are using terribly troublesome classes that were supplanted years ago by the java.time classes. Never again touch those legacy classes.

Parse your input strings as a date-only value, without time-of-day, without time zone. That would be a LocalDate object.

LocalDate ld = LocalDate.of(
    Integer.valueOf( y ) ,    // Sane numbering. Ex: number `2018` is year 2018.
    Integer.valueOf( m ) ,    // Sane numbering. Months 1-12 are January-December.
    Integer.valueOf( d ) 
) ;

Get the day-of-week using the handy DayOfWeek enum. This class pre-defines seven objects, one for each day of the week. You will find some handy methods on that class as well, such as the localization feature used below.

Java has an extraordinarily powerful and flexible enum facility. If unfamiliar, study the Oracle Tutorial .

DayOfWeek dow = ld.getDayOfWeek() ; 

Generate a String with the name of the day of the week. No need to hard-code English. Let java.time automatically localize for you.

To localize, specify:

  • TextStyle to determine how long or abbreviated should the string be.
  • Locale to determine:
    • The human language for translation of name of day, name of month, and such.
    • The cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.

Example:

Locale l = Locale.CANADA_FRENCH ;  // Or, Locale.UK, Locale.US, etc.
String output = dow.getDisplayName( TextStyle.FULL , l ) ;

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat .

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.

To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations. Specification is JSR 310 .

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more .

Get a look at LocalDate and Try this:

Scanner in = new Scanner(System.in);
String month = in.next();
String day = in.next();
String year = in.next();
LocalDate ld = LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day));
System.out.println(ld.getDayOfWeek());

There are nice classes in java.time package.

Java date time issue fixed in java8 DateTime. use below code. your problem will be fixed.

public static String getDay(String day, String month, String year) {
    return LocalDate.parse(day+"-"+month+"-"+year , DateTimeFormatter.ofPattern( "dd-MM-yyyy" ))
            .getDayOfWeek()
            .getDisplayName(TextStyle.FULL_STANDALONE , Locale.ENGLISH);
}

Edit : Based on the latest comment from Ole VV There is no error in the program. Just re-tried it in my workstation and it is due to the month numbering scheme is 0-based instead of 1 as highlighted by slashdottir .

I think there is probably a logical error in the program.

 // create a GregorianCalendar with the Pacific Daylight time zone // and the desired date and time Calendar calendar = new GregorianCalendar(pdt); calendar.set(Calendar.MONTH, Integer.valueOf(month)); calendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(day)); calendar.set(Calendar.YEAR, Integer.valueOf(year)); 

In this portion of the code, the DAY_OF_WEEK or DAY_OF_WEEK_IN_MONTH is not set but...

towards the end of the method, we are trying to retrieve it anyway:

  System.out.println("DAY_OF_WEEK: " + calendar.get(Calendar.DAY_OF_WEEK)); int dow = calendar.get(Calendar.DAY_OF_WEEK); return dows.get(dow-1); 

So, you are essentially getting the default value of DAY_OF_WEEK which is 7 ( reference ) - also the value of dow variable, therefore dow - 1 will always be 6 and dows.get(6) will always return SATURDAY .

Trying to set DAY_OF_WEEK_IN_MONTH with Calendar class may turn out to be tricky. It would be best to use the features in java.time package as suggested by Ruben DG and sajib .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM