Convert string to day of week (not exact date) - java

I'm receiving a String which is a spelled out day of the week, e.g. Monday. Now I want to get the constant integer representation of that day, which is used in java.util.Calendar.
Do I really have to do if(day.equalsIgnoreCase("Monday")){...}else if(...){...} on my own? Is there some neat method? If I dig up the SimpleDateFormat and mix that with the Calendar I produce nearly as many lines as typing the ugly if-else-to-infitity statetment.

java.time
For anyone interested in Java 8 solution, this can be achieved with something similar to this:
import static java.util.Locale.forLanguageTag;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.time.DayOfWeek;
import org.junit.Test;
public class sarasa {
#Test
public void test() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE", forLanguageTag("es"));
TemporalAccessor accessor = formatter.parse("martes"); // Spanish for Tuesday.
System.out.println(DayOfWeek.from(accessor));
}
}
Output for this is:
TUESDAY

You can use SimpleDateFormat it can also parse the day for a specific Locale
public class Main {
private static int parseDayOfWeek(String day, Locale locale)
throws ParseException {
SimpleDateFormat dayFormat = new SimpleDateFormat("E", locale);
Date date = dayFormat.parse(day);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
return dayOfWeek;
}
public static void main(String[] args) throws ParseException {
int dayOfWeek = parseDayOfWeek("Sunday", Locale.US);
System.out.println(dayOfWeek);
dayOfWeek = parseDayOfWeek("Tue", Locale.US);
System.out.println(dayOfWeek);
dayOfWeek = parseDayOfWeek("Sonntag", Locale.GERMANY);
System.out.println(dayOfWeek);
}
}

For non-English day-of-week names, see Answer by tete.
tl;dr
DayOfWeek.valueOf( "Monday".toUppercase() ) // `DayOfWeek` object. Works only for English language.
.getValue() // 1
java.time
If your day-of-week names happen to be the full-length name in English (Monday, Tuesday, etc.), that happens to coincide with the names of the enum objects defined in the DayOfWeek enum.
Convert your inputs to all uppercase, and parse to get a constant object for that day-of-week.
String input = "Monday" ;
String inputUppercase = input.toUppercase() ; // MONDAY
DayOfWeek dow = DayOfWeek.valueOf( inputUppercase ); // Object, neither a string nor a number.
Now that we have a full-feature object rather than a string, ask for the integer number of that day-of-week where Monday is 1 and Sunday is 7 (standard ISO 8601 definition).
int dayOfWeekNumber = dow.getValue() ;
Use DayOfWeek objects rather than strings
I urge you to minimize the use of either the name or number of day-of-week. Instead, use DayOfWeek objects whenever possible.
By the way, you can localize the day-of-week name automatically.
String output = DayOfWeek.MONDAY.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH );
That localization is one-way only through the DayOfWeek class. To go the other direction in languages other than English, see the Answer by tete.
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.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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.

I generally use an enum, though in this case your input has to be in proper case.
public enum DayOfWeek {
Sunday(1),Monday(2),Tuesday(3),Wednesday(4),Thursday(5),Friday(6),Saturday(7);
private final int value;
DayOfWeek(int value) {
this.value = value;
}
public int getValue() {
return value;
}
#Override
public String toString() {
return value + "";
}
}
Now, you can get the day of the week as follows:
String sunday = "Sunday";
System.out.println(DayOfWeek.valueOf(sunday));
This would give you following output:
1

You could do something like this:
private static String getDayOfWeek(final Calendar calendar){
assert calendar != null;
final String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
return days[calendar.get(Calendar.DAY_OF_WEEK)-1];
}
Although it would probably be a good idea to declare the days of the week so you don't have to keep declaring them each time the method is called.
For the other way around, something like this:
private static int getDayOfWeek(final String day){
assert day != null;
final String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
for(int i = 0; i < days.length; i++)
if(days[i].equalsIgnoreCase(day))
return i+1;
return -1;
}

Consider using a helper method like
public static int getDayOfWeekAsInt(String day) {
if (day == null) {
return -1;
}
switch (day.toLowerCase()) {
case "monday":
return Calendar.MONDAY;
case "tuesday":
return Calendar.TUESDAY;
case "wednesday":
return Calendar.WEDNESDAY;
case "thursday":
return Calendar.THURSDAY;
case "friday":
return Calendar.FRIDAY;
case "saturday":
return Calendar.SATURDAY;
case "sunday":
return Calendar.SUNDAY;
default:
return -1;
}
}
Please, note that using Strings with switch-case is only supported Java 7 onwards.

Why not initialize what you want once?
private static final Map<String, Integer> weekDays;
static
{
weekDays= new HashMap<String, Integer>();
weekDays.put("Monday", Calendar.MONDAY);
weekDays.put("Tuesday", Calendar.TUESDAY);
// etc
}

Why not declare a Map:
Map<String, Integer> daysMap = new HashMap<String, Integer>();
daysMap.add("monday", 0);
daysMap.add("tuesday", 1);
//etc.
Then, when you need to search:
int dayId = daysMap.get(day.toLowerCase());
This should do what you need. You could even load the data from some file / database, etc.

If you are using java 8 :
import java.time.DayOfWeek;
Then simply use: DayOfWeek.[DAY].getValue()
System.out.println(DayOfWeek.MONDAY.getValue());
System.out.println(DayOfWeek.TUESDAY);
System.out.println(DayOfWeek.FRIDAY.getValue());
For older version check this answer:
Convert string to day of week (not exact date)

Use the names built into the DateFormatSymbols class as follows. This returns 0 for Sunday, 6 for Saturday, and -2 for any invalid day. Add your own error handling as you see fit.
private static final List dayNames = Arrays.asList(new DateFormatSymbols().getWeekdays());
public int dayNameToInteger(String dayName) {
return dayNames.indexOf(dayName) - 1;
}

Related

Instead of multiple if statements Java date

Is there a better way to write this instead of writing multiple if statements?
I'm parsing through a document to find the instances of date and incrementing the int if an instance occurs.
public class OrganisingData {
static int jan16=0;
static int feb16=0;
static int mar16=0;//... static int dec18
public static void Months(String dates) {
if (dates.substring(2, 4).equals("16") &&
dates.substring(5,7).equals("01")) {
jan16++;
}
if (dates.substring(2, 4).equals("16") &&
dates.substring(5,7).equals("02")) {
feb16++;...
}
if (dates.substring(2, 4).equals("18") &&
dates.substring(5,7).equals("12")) {
dec18++;
}
}
}
I am trying to build a bar chart and jan16 feb16 etc represent the month and the year and each time i find an insistence of that date (eg. 2016-01-15) i would increment jan16. so instead of writing multiple if statements for each month + year (total of 32 if statements)is there a better way to write this?
Basically a mix of what #John T and #Zachary said, but with proper syntax and type conversion.
// [Years] and [Months], where [0][0] is jan 2000. May need to adjust for previous years.
int[][] days = new int[30][12];
void month(String dates) {
int year = Integer.parseInt(dates.substring(2, 4));
int month = Integer.parseInt(dates.substring(5,7)) - 1;
days[year][month]++;
}
You could use a switch statement to reduce the clunky logic, though this wouldn't necessarily condense greatly. You will either need to use Strings with the Switch or convert the day/month values to an integer.
String day = dates.substring(2, 4);
String month = dates.substring(5, 7);
switch (month) {
case "01" : {
if (day.equals("16"))
jan16++;
break;
}
}
If there is some pattern behind what you are wanting to do, there may be a better solution. For example, the following would count 16th of each month
int count[] = new int[12];
...
int day = Integer.parseInt(dates.substring(2, 4));
int month = Integer.parseInt(dates.substring(5, 7));
if (day == 16)
count[month - 1]++;
YearMonth
Apparently you want to track year-month values. There's a class for that, named, well, YearMonth. Find this class in the java.time package that supplants the terribly troublesome old date-time classes bundled with the earliest versions of Java.
MonthDay
Or maybe you are shooting for month-day values; your Question is convoluted so I am not sure of your goal. But if this is your goal, again, there’s a class for that: MonthDay.
Month
Or maybe you want just the month regardless of year or day-of-month, in which case you can use the Month class.
LocalDate
If your inputs strings represent a year and month and day-of-month, parse as a LocalDate. This class has no time-of-day and no time zone.
LocalDate ld = LocalDate.parse( "2016-01-15" ) ;
Extract a YearMonth, MonthDay, or Month.
YearMonth ym = YearMonth.from( ld ) ;
Create a collection. Perhaps you want to keep all a distinct set of the LocalDate objects in a particular year-month. If so, make a Map where each YearMonth object owns a Set of LocalDate objects.
Map < YearMonth, Set < LocalDate > > map = new HashMap <>();
As you process each input date, check to see if the map has a Set yet created for the particular YearMonth of the input. If not, instantiate a TreeSet. The TreeSet class is a SortedSet, meaning it maintains a sorted order as you add values.
Set < LocalDate > set = map.get( ym );
if ( null == set ) {
set = new TreeSet <>(); // A `TreeSet` is a `SortedSet`, maintains a sorted order. You may or may not need this behavior.
map.put( ym , set );
}
With a Set in hand, add your LocalDate.
set.add( ld );
After processing, you can get a collection of the YearMonth keys from your Map. And for each of those, you can retrieve the Set it owns, and get a count of the elements contained.
Lamba & Streams
For shorter code, you might be able to use Lambda syntax & Streams with Map::computeIfAbsent. I've seen this kind of code but have not yet tried it.
map.computeIfAbsent( key , k -> new TreeSet< LocalDate >() ).add( ld ) ;
Count only
If you want only the count, and don't care about the LocalDate values, replace Set as the “value” or you Map with a Integer object. Instead of retrieving the Set and adding to it, retrieve the Integer and increment it by adding one. Personally, in this kind of situation I find it best to collect the LocalDate values to be examined for debugging/testing and/or for further use in other business logic.
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?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
Using appropriate data structures, you can greatly reduce this code.
The idea is to have a data structure that for each year you're interested in, holds an array of ints: one for each month.
Then, converting the substrings from the dates String to numbers, you can use those numbers to index the data structure.
import java.util.Map;
import java.util.HashMap;
private static Map<Integer, int[]> years = new HashMap<>();
private static String[] monthNames = new String[] {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
static {
for(int year = 16; year <= 18; year++) {
years.put(year, new int[12]);
}
}
public static void months(String dates) { // method names should start with lower case
int year = Integer.parseInt(dates.substring(2, 4));
int month = Integer.parseInt(dates.substring(5, 7)) - 1; // date String is one-based, array-index is zero-based
years.get(year)[month]++;
}
public static void print() {
for(int year = 16; year <= 18; year++) {
int[] monthCounts = years.get(year);
for(int month = 0; month < 12; month++) {
System.out.println(monthNames[month] + " " + year + ": " + monthCounts[month]);
}
}
}
You can see the code in action here.
Loop through your document with this:
// 18 years(more needed?), 12 months
String[][] yearsAndMonths = new String[18][12];
yearsAndMonths[dates.substring(5,7)][dates.substring(2, 4)]++;
Then print the results.
I'm not a java expert. Code just provided to give you the logic.

java - Get the last date of input day of week

I am searching for a method to find the last date of a input day of week from now on? For example: If today is Monday, the 5th march 2018 the results should look like this:
Input Output
Monday 05.03.2018
Tuesday 27.02.2018
Wednesday 28.02.2018
Thursday 01.03.2018
Friday 02.03.2018
Saturday 03.03.2018
Sunday 04.03.2018
I hope you get the idee. I couldn't really find a post with something similar, so any help would be much appreciated
As posted in comments, this is the code I have atm:
private String getLastDateOfDayOfWeek(String day, String returnDateFormat) throws ParseException {
int dayOfWeek = parseDayOfWeek(day, Locale.ENGLISH);
Calendar cal = Calendar.getInstance(); // Today, now
if (cal.get(Calendar.DAY_OF_WEEK) != dayOfWeek) {
// ...
}
return new SimpleDateFormat(returnDateFormat).format(cal.getTime());
}
private static int parseDayOfWeek(String day, Locale locale)
throws ParseException {
SimpleDateFormat dayFormat = new SimpleDateFormat("EEEE", locale);
Date date = dayFormat.parse(day);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
return dayOfWeek;
}
Atm I have two functions: one that can convert a string to a Calender dayOfWeek number and another one, which is the method i am searching for. Currently it only handles todays day of week correct, the part that should do the work for every other day of the week is missing(comment with ...)
tl;dr
LocalDate.now().with( // Get today’s date, then move to another date.
TemporalAdjusters.previousOrSame( // An implementation of `TemporalAdjuster` interface, used for algorithms to move to another date.
DayOfWeek.valueOf( “Monday”.toUpperCase() ) // Get the enum Object with te corresponding hard-coded name in English such as `DayOfWeek.MONDAY`.
)
)
DayOfWeek
The DayOfWeek enum holds seven objects, one for each day of the week.
English
The names of these seven objects are in English, all uppercase. So you can get the Object from the English word.
String input = “Monday”.toUpperCase() ;
DayOfWeek dow = DayOfWeek.valueOf( input ) ;
Other languages
For languages other than English, define a List populated with the name of each day-of-week. Use the name generated from DayOfWeek::getDisplayName, a method that automatically localizes. Start the list with Monday, per the ISO 8601 standard. Search that list to find a match with your input. Get the ordinal number of your match, 1-7 (not the index number 0-6). Pass that number to DayOfWeek.valueOf to get a DayOfWeek object. In some languages you’ll need a pair of such lists to be searched, as an alternate spelling may be invoked for a “standalone” use of the day-of-week without the context of a date.
Here is an example of such a class. Beware: I just whipped up this class without much thought and without any serious testing. Use at your own risk. Usage: DayOfWeekDelocalizer.of( Locale.CANADA_FRENCH ).parse( "lundi" ) → DayOfWeek.MONDAY
package com.basilbourque.example;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.DayOfWeek;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
// For a given name of day-of-week in some language, determine the matching `java.time.DayOfWeek` enum object.
// This class is the opposite of `DayOfWeek.getDisplayName` which generates a localized string for a given `DayOfWeek` object.
// Usage… DayOfWeekDelocalizer.of( Locale.CANADA_FRENCH ).parse( "lundi" ) → DayOfWeek.MONDAY
// Assumes `FormatStyle.FULL`, for day-of-week names without abbreviation.
// USE AT YOUR OWN RISK. Rough draft, quickly written. No serious testing.
public class DayOfWeekDelocalizer
{
#NotNull
private Locale locale;
#NotNull
private List < String > dayOfWeekNames, dayOfWeekNamesStandalone; // Some languages use an alternate spelling for a “standalone” day-of-week used without the context of a date.
// Constructor. Private, for static factory method.
private DayOfWeekDelocalizer ( #NotNull Locale locale )
{
this.locale = locale;
// Populate the pair of arrays, each having the translated day-of-week names.
int daysInWeek = 7; // Seven days in the week.
this.dayOfWeekNames = new ArrayList <>( daysInWeek );
this.dayOfWeekNamesStandalone = new ArrayList <>( daysInWeek );
for ( int i = 1 ; i <= daysInWeek ; i++ )
{
this.dayOfWeekNames.add( DayOfWeek.of( i ).getDisplayName( TextStyle.FULL , this.locale ) );
this.dayOfWeekNamesStandalone.add( DayOfWeek.of( i ).getDisplayName( TextStyle.FULL_STANDALONE , this.locale ) );
}
// System.out.println( this.dayOfWeekNames );
// System.out.println( this.dayOfWeekNamesStandalone );
}
// Constructor. Private, for static factory method.
// Personally, I think it unwise to default implicitly to a `Locale`. But I included this in case you disagree with me, and to follow the lead of the *java.time* classes. --Basil Bourque
private DayOfWeekDelocalizer ( )
{
this( Locale.getDefault() );
}
// static factory method, instead of constructors.
// See article by Dr. Joshua Bloch. http://www.informit.com/articles/article.aspx?p=1216151
// The `Locale` argument determines the human language and cultural norms used in de-localizing input strings.
synchronized static public DayOfWeekDelocalizer of ( #NotNull Locale localeArg )
{
DayOfWeekDelocalizer x = new DayOfWeekDelocalizer( localeArg ); // This class could be optimized by caching this object.
return x;
}
// Attempt to translate the name of a day-of-week to look-up a matching `DayOfWeek` enum object.
// Returns NULL if the passed String value is not found to be a valid name of day-of-week for the human language and cultural norms of the `Locale` specified when constructing this parent object, `DayOfWeekDelocalizer`.
#Nullable
public DayOfWeek parse ( #NotNull String input )
{
int index = this.dayOfWeekNames.indexOf( input );
if ( - 1 == index )
{ // If no hit in the contextual names, try the standalone names.
index = this.dayOfWeekNamesStandalone.indexOf( input );
}
int ordinal = ( index + 1 );
DayOfWeek dow = ( ordinal > 0 ) ? DayOfWeek.of( ordinal ) : null; // If we have a hit, determine the DayOfWeek. Else return null.
return dow;
}
// `Object` overrides.
#Override
public boolean equals ( Object o )
{
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
DayOfWeekDelocalizer that = ( DayOfWeekDelocalizer ) o;
return locale.equals( that.locale );
}
#Override
public int hashCode ( )
{
return locale.hashCode();
}
public static void main ( String[] args )
{
// Quick testing.
// DayOfWeekDelocalizer x = DayOfWeekDelocalizer.of( Locale.JAPAN );
if ( DayOfWeekDelocalizer.of( Locale.CANADA_FRENCH ).parse( "lundi" ).equals( DayOfWeek.MONDAY ) )
{
System.out.println( "GOOD - Canada French 'lundi' is parsing to DayOfWeek.MONDAY." );
} else
{
System.out.println( "BAD - Canada French 'lundi' is NOT parsing to DayOfWeek.MONDAY." );
}
}
}
Tip: Using a String to represent a DayOfWeek is clumsy. Your code should instead be passing around a DayOfWeek enum object.
LocalDate
Next we need the current date.
LocalDate today = LocalDate.now() ;
Better to explicitly state your desired/expected time zone than rely implicitly on the JVM’s current default time zone.
ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
LocalDate today = LocalDate.now( z ) ;
TemporalAdjuster
Move to another date by applying a TemporalAdjuster. The TemporalAdjusters class offers the implementation we need.
TemporalAdjuster ta = TemporalAdjusters.previousOrSame( dow ) ;
LocalDate ld = today.with( ta ) ;
Note that java.time uses Immutable Objects. So rather than modify an object, methods produce a new distinct object with altered values based on the original.
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?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

How can I get Date list from year and month name

How can I get (java.util.Date) date list from specific year and month
Example : I have a year like as '2017' and month name like as 'February' I want to get date list of February or any other months.
such as
2017-02-01,
2017-02-02,
2017-02-03,
2017-02-04,
2017-02-05,
2017-02-06,
2017-02-07
....
2017-02-28.
Please help me sample code, Thanks
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
List<LocalDate> getDateList(int year, String monthname) {
int month = Month.valueOf(monthname.toUpperCase()).getValue();
return IntStream
.rangeClosed(1, YearMonth.of(year, month).lengthOfMonth())
.mapToObj(i -> LocalDate.of(year, month, i))
.collect(Collectors.toList());
}
Demo:
import java.time.LocalDate;
import java.time.Month;
import java.time.YearMonth;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
// Test
getDateList(2017, "February").forEach(System.out::println);
System.out.println("=*==*==*=*=");
getDateList(2016, "February").forEach(System.out::println);
}
static List<LocalDate> getDateList(int year, String monthname) {
int month = Month.valueOf(monthname.toUpperCase()).getValue();
return IntStream
.rangeClosed(1, YearMonth.of(year, month).lengthOfMonth())
.mapToObj(i -> LocalDate.of(year, month, i))
.collect(Collectors.toList());
}
}
Output:
2017-02-01
2017-02-02
...
...
...
2017-02-27
2017-02-28
=*==*==*=*=
2016-02-01
2016-02-02
...
...
...
2016-02-28
2016-02-29
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
java.time
Use the modern date-time classes, in the java.time package.
String input = "2017 February" ;
Parse as a YearMonth object. Define a formatting pattern to match your input.
String input = "2017 February";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "uuuu MMMM" , Locale.US );
YearMonth ym = YearMonth.parse ( input , f );
Loop for the number of days in that month. For each day-of-month, get a LocalDate object.
System.out.println ( "===== Days of " + ym + " =====" );
for ( int i = 1 ; i <= ym.lengthOfMonth () ; i ++ ) {
LocalDate localDate = ym.atDay ( i );
System.out.println ( localDate ); // Uses standard ISO 8601 format by default when generating a string.
}
System.out.println ( "=================" );
===== Days of 2017-02 =====
2017-02-01
2017-02-02
2017-02-03
…
You can see that code run live at IdeOne.com.
If you want to see this kind of code written using Java Streams, see my Question: Use Java streams to collect objects generated in a for loop
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.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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.
First, you need to find the number of days you can get for a specific month, this is easy with Calendar.getActualMaximum(int field)
Returns the maximum value that the specified calendar field could have, given the time value of this Calendar. For example, the actual maximum value of the MONTH field is 12 in some years, and 13 in other years in the Hebrew calendar system.
From this, just use a loop to create every value (or might be easier with Stream API, but I am not good with it...).
Here is a simple example of the usage of this method (not the answer at all):
Calendar c = Calendar.getInstance();
for(int i = 0; i <= c.getActualMaximum(Calendar.MONTH); ++i){
c.set(Calendar.MONTH, i);
System.out.format("There is %d days in %d\n", c.getActualMaximum(Calendar.DAY_OF_MONTH), c.get(Calendar.MONTH));
}
Output :
There is 31 days in 0
There is 28 days in 1
There is 31 days in 2
There is 30 days in 3
There is 31 days in 4
There is 30 days in 5
There is 31 days in 6
There is 31 days in 7
There is 30 days in 8
There is 31 days in 9
There is 30 days in 10
There is 31 days in 11
You can use this :
First you should to get the first day from date from your input year and month 2017/February
Second you should to get the number of days of this month
Third you should to loop until the number to your days in your case from 1 to 28 and add a day to your date
public static void main(String[] args) throws ParseException {
int year = 2017;
String month = "February";
SimpleDateFormat format = new SimpleDateFormat("yyyy/MMMM", Locale.US);
Date utilDate = format.parse(year + "/" + month);
//get first day of your month
System.out.println(new SimpleDateFormat("yyyy/MM/dd").format(utilDate));
//get days of months
Calendar cal = Calendar.getInstance();
cal.setTime(utilDate);
int monthMaxDays = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
//loop and add a day to your date
for (int i = 0; i < monthMaxDays - 1; i++) {
cal.add(Calendar.DATE, 1);
System.out.println(new SimpleDateFormat("yyyy/MM/dd").format(cal.getTime()));
}
}
See this code run live at IdeOne.com.
Good luck
As part of solution I created this high order property to get an array of dates from current month. This was for Android below API level 26.
val daysOfMonth: List<Date>
get() {
val cal = Calendar.getInstance()
val start = cal.getActualMinimum(Calendar.DAY_OF_MONTH)
val ends = cal.getActualMaximum(Calendar.DAY_OF_MONTH)
val days = mutableListOf<Date>()
for (i in start..ends) {
cal.set(Calendar.DAY_OF_MONTH, i)
days.add(cal.time)
}
return days
}
I have used JODA-data time to make my life easier and here is the solution:
package com.github.dibyaranjan.service;
import org.joda.time.DateTime;
public class Test {
public static void main(String[] args) {
DateTime dateTime = new DateTime();
dateTime = dateTime.withDate(2017, 02, 01); // Used the date and time mentioned in your question
int currentMonth = dateTime.getMonthOfYear();
boolean isCurrentMonth = true;
while (isCurrentMonth) {
isCurrentMonth = (dateTime.getMonthOfYear() == currentMonth);
if (isCurrentMonth) {
String dateTimeFormatter = "yyyy-MM-dd";
System.out.println(dateTime.toString(dateTimeFormatter));
}
dateTime = dateTime.plusDays(1);
}
}
}

Create a custom collection of days-of-the-week in JAVA

I want a custom calendar like this:
enum TradingDays {Monday, Tuesday, Wednesday, Thursday, Friday};
Then I need to iterate over it and check if a particular enum element is the day of week TODAY. The problem is that the JAVA calendar does not match to days of week from my calendar. So:
Calendar now = Calendar.getInstance();
TradingDays.Monday is not equal to any of now.get(Calendar.DAY_OF_WEEK);
So how do I assign Monday, Tuesday etc from my calendar TradingDays the same type (in this case an integer value) from the JAVA calendar?
P.S. I need to have that calendar TradingDays like that because it is then shown to the user so he/she chooses on which days to trade.
tl;dr
Set<DayOfWeek> tradingDays = EnumSet.range( DayOfWeek.MONDAY , DayOfWeek.FRIDAY ) ; // Mon, Tue, Wed, Thu, & Fri.
Boolean todayIsTradingDay = tradingDays.contains( LocalDate.now( ZoneId.of( "America/Montreal" ) ).getDayOfWeek() ) ;
Details
This functionality is built into Java.
java.time.DayOfWeek enum
Java includes the java.time.DayOfWeek enum.
Pass around objects of this enum rather than mere integers 1-7 to make your code more self-documenting, provide type-safety, and ensure a range of valid values.
invoices.printReportForDayOfWeek( DayOfWeek.MONDAY );
Numbering is 1-7 for Monday to Sunday, per ISO 8601 standard.
Get a localized name of the day by calling getDisplayName.
String output = DayOfWeek.MONDAY.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; // Or Locale.US, etc.
Collection of day-of-week objects
To track multiple days of the week, use an EnumSet (implementation of Set) or EnumMap (implementation of Map).
Set<DayOfWeek> weekend = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY ) ;
…
DayOfWeek dowToday =
LocalDate
.now( ZoneId.of( "America/Montreal" ) )
.getDayOfWeek() ;
Boolean todayIsWeekend = weekend.contains( dowToday ) ;
Or in the case of this Question specifically, a collection of the weekdays. Perhaps define as a static final constant if the definition does not change during execution of the app.
static final Set<DayOfWeek> tradingDays = EnumSet.of( DayOfWeek.MONDAY , DayOfWeek.TUESDAY , DayOfWeek.WEDNESDAY , DayOfWeek.THURSDAY , DayOfWeek.FRIDAY ) ;
Or make that even shorter by defining an EnumSet as a range of enum objects defined in a sequential order. Specify MONDAY & FRIDAY and let EnumSet fill in the values in between. Use EnumSet.range.
static final Set<DayOfWeek> tradingDays = EnumSet.range( DayOfWeek.MONDAY , DayOfWeek.FRIDAY ) ; // Mon, Tue, Wed, Thu, & Fri.
Then test for today. Note that a time zone is crucial in determining the current date. For any given moment the date varies around the globe by zone.
ZoneId zoneId = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( zoneId ) ;
DayOfWeek dowToday = today.getDayOfWeek() ;
Boolean todayIsTradingDay = tradingDays.contains( dowToday ).getDayOfWeek() ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
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.
You can try using a constructor inside your enum, like in this example:
public enum Currency {
PENNY(1),
NICKLE(5),
DIME(10),
QUARTER(25);
private final int value;
private Currency(int value) {
this.value=value;
}
}
While iterating you can use coin.value like this:
for(Currency coin: Currency.values()){
System.out.println(coin+" "+coin.value);
if(coin.value==1){
System.out.println("THIS is the PENNY");
}
}
Which output is:
PENNY 1
THIS is the PENNY
NICKLE 5
DIME 10
QUARTER 25
With enums you can do a lot of things that probably are familiar to you:
File TradingDays.java:
public enum TradingDays {
Monday(Calendar.MONDAY),
Tuesday(Calendar.TUESDAY),
Wednesday(Calendar.WEDNESDAY),
Thursday(Calendar.THURSDAY),
Friday(Calendar.FRIDAY);
private int calendarValue;
TradingDays(int calendarValue) {
this.calendarValue = calendarValue;
}
public static TradingDays today() {
return fromCalendarValue(Calendar.getInstance().get(Calendar.DAY_OF_WEEK));
}
public static TradingDays fromCalendarValue(int calendarValue) {
for(TradingDays td : TradingDays.values()) {
if(td.calendarValue == calendarValue) {
return td;
}
}
throw new IllegalArgumentException(calendarValue + " is not a valid TradingDays calendarValue");
// or simply return null
}
};
Create a constructor inside your enum which takes an int value:
public class CalendarMain {
enum TradingDays {
Monday(2), Tuesday(3), Wednesday(4), Thursday(5), Friday(6);
private int value;
private TradingDays(int value) {
this.value = value;
}
};
public static void main(String[] args) {
Calendar now = Calendar.getInstance();
if (now.get(Calendar.DAY_OF_WEEK) == TradingDays.Tuesday.value) {
// Chose Wednesday as the day to trade
System.out.println(now.get(Calendar.DAY_OF_WEEK));
System.out.println(TradingDays.Tuesday.value);
}
}
}

Failure to initialize GregorianCalendar Object

I'm a complete beginner with Java, and I've been making simple test-programs to review some of the material I read. The following block of code works incorrectly. It's supposed to accept a Year, Month, and Date from the user, and then create a GregorianCalendar object initialized with the year, month and date. However, when I try to return the GregorianCalendar variable's month, it always gives back the month I initialized the month variable with. I'm not sure why.
import java.util.*;
public class Prac {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("Enter Year: ");
int YEAR = input.nextInt();
System.out.print("Enter Month: ");
String MONTH_STRING = input.next();
System.out.print("Enter Date: ");
int DATE = input.nextInt();
int MONTH = 10;
String mon = MONTH_STRING.toLowerCase();
if (mon == "january") {
MONTH = 0;
} else if (mon == "february") {
MONTH = 1;
} else if (mon == "march") {
MONTH = 2;
} else if (mon == "april") {
MONTH =3;
} else if (mon == "may"){
MONTH =4;
} else if (mon == "june"){
MONTH =5;
} else if (mon == "july"){
MONTH =6;
} else if (mon == "august"){
MONTH=7;
} else if (mon == "september"){
MONTH=8;
} else if (mon == "october"){
MONTH=9;
} else if (mon == "november"){
MONTH=10;
} else if (mon == "december"){
MONTH =11;
}
GregorianCalendar entDate = new GregorianCalendar(YEAR,MONTH,DATE);
System.out.println(entDate.get(Calendar.MONTH));
}
}
Also, I'm aware I could have used a switch block, but it gave me strange errors somehow.
String.equals
You're comparing Strings incorrectly.
The == operator checks to see if the Objects are the same -- meaning same memory location and everything.
What you want to do is the String::equals method.
if(mon.equals("january") {
...
} else if(mon.equals("feburary") {
...
} ...
This will check only to see if the value of the string is equal.
Also, unless you're using java 1.7+ you wouldn't be able to use a switch case for Strings. Not really a part of the question, but still good to know.
The Answer by Shaded is correct and should be accepted. You should generally avoid using == comparison with objects, and instead call a method such as equals or isEqual.
Furthermore, you could call String::equalsIgnoreCase method rather than changing the string to be lowercase.
boolean sameIgnoringCase = thisString.equalsIgnoreCase( thatString ) ;
java.time
The modern approach uses the modern java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Compare months by using the Month enum rather than mere numbers or text. That class offers a dozen instances, one for each month of the year.
Month month = ld.getMonth() ; // Get `Month` enum object.
You can switch on an enum.
switch( month ) {
case JANUARY:
…
case FEBRUARY:
…
default:
…
}
Note that a quirk in Java means you cannot prefix the JANUARY with Month (that is, Month.JANUARY) inside a switch. As a habit, I routinely use the enum class name with the object name, except in a switch where it is forbidden.
Also, you may find the EnumSet and EnumMap handy.
Set< Month > winter = EnumSet.of( Month.DECEMBER , Month.JANUARY , Month.FEBRUARY ) ;
boolean isWinter = winter.contains( myLocalDate.getMonth() ) ;
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

Categories

Resources