1

I am trying to get the date of Monday or Thurday in this format YYYYMMDD

For Monday it should give me this - 20130224 (as an example)

For Thursday it should give me this - 20130227 (as an example)

  • Now, if I am running my program after Thursday or on Thursday, it should print date for Thursday in this format YYYYMMDD which can be 20130227 (coming thursday in this week).
  • And If I am running my program after Monday or on Monday, then it should print date for Monday in the same format YYYYMMMDD which can be 20130224 (yesterday Monday date as an example)

How would I do this in Java?

Below is what I have tried -

Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("EEE");
String text = formatter.format(cal.getTime());
System.out.println(text);

// but how do I check if it is Tuesday but less than Thursday
if(text.equalsIgnoreCase("Tue")) {
    // get previous Monday date in YYYYMMDD
} 

// and how do I check if it is thursday or greater than Thursday?
else if(text.equalsIgnoreCase("Thur")) {
 // get previous Thursday date in YYYYMMDD
}

Update:-

In a particular week, if I am running my program on Thursday or after Thursday then it should return me date for Thursday in the same week in YYYYMMDD format, but if I am running my program on Monday or after Monday, then it should return me date for Monday in the same week in YYYYMMDD format.

For example, In this week, if I am running my program on Thursday or after Thursday, then it should return date for Thursday. But if I am running my program on Monday or Tuesday or Wednesday in this same week, then it should return me date for Monday.

Code:-

Below is my code -

public static void main(String[] args) {

try {
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat toDateFormat = new SimpleDateFormat("yyyyMMdd");

    int dow = cal.get(Calendar.DAY_OF_WEEK);
    switch (dow) {
    case Calendar.THURSDAY:
    case Calendar.FRIDAY:
    case Calendar.SATURDAY:
    case Calendar.SUNDAY:
    while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.THURSDAY) {
        cal.add(Calendar.DATE, -1);
    }
    break;
    case Calendar.MONDAY:
    case Calendar.TUESDAY:
    case Calendar.WEDNESDAY:
    while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
        cal.add(Calendar.DATE, -1);
    }
    break;
    }

    System.out.println(date);
    System.out.println(cal.getTime());
    System.out.println(toDateFormat.format(cal.getTime()));

} catch (ParseException exp) {
    exp.printStackTrace();
}
}
  • 1
    What are you asking? How to get the name of the day of the week from a String representation of a date in YYYYMMDD? What is the relevance of yesterday and the day after tomorrow? – Elliott Frisch Feb 26 '14 at 02:14
  • Are you asking to print out the date of the most recent Monday and Thursday? – ErstwhileIII Feb 26 '14 at 02:16
  • I just updated my question.. Take a look and let me know if there is anything unclear.. –  Feb 26 '14 at 02:17
  • Ok, so you want DAY IF DAY >= TODAY ELSE MONDAY? – Sebastian Höffner Feb 26 '14 at 03:57
  • Let's say - In this week, if I am running my program on Thursday or after Thursday, then it should return date for Thursday in `YYYYMMDD` format. But if I am running my program on Monday or Tuesday or Wednesday in this same week, then it should return me date for Monday in the YYYYMMDD format. –  Feb 26 '14 at 04:01

6 Answers6

0

What? Moving to a new question with the same contents?

  String[] weeks = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
  DateFormat df = new SimpleDateFormat("yyyyMMdd");
  Calendar c = Calendar.getInstance();
  c.setTime(new Date()); // Now use today date.
  int dayOfWeek = c.get(Calendar.DAY_OF_WEEK); // Sun=1, Mon=2, ... Sat=7
  System.out.println("Today " + df.format(c.getTime()) + " is " + weeks[dayOfWeek-1]);
  c.add(Calendar.DATE, 7); // Adding 7 days
  System.out.println("Next " + weeks[dayOfWeek-1] + " is " + df.format(c.getTime()));
  // Should display:
  // Today 20140225 is Tuesday
  // Next Tuesday is 20140304
TA Nguyen
  • 453
  • 1
  • 3
  • 8
  • So, you have dayOfWeek that tell you what day of week you are at. Use that to detect the current date and add, or minus to the next values. Example, today is Tuesday so dayOfWeek=3, and you want Monday is 2, 2-3=-1, add -1 to your calendar c.add(Calendar.DATE, -1) will give you Monday. – TA Nguyen Feb 26 '14 at 02:34
0

Start by parsing the text value to a Date value...

String dateText = "20130224";
SimpleDateFormat toDateFormat = new SimpleDateFormat("yyyyMMdd");
Date date = toDateFormat.parse(dateText);

This gives you the starting point. Next you need to use a Calendar which will allow you move backwards and forwards, automatically rolling the date internally for you (so if you roll over week, month or year boundaries)

For example...

try {
    String dateText = "20130227";
    SimpleDateFormat toDateFormat = new SimpleDateFormat("yyyyMMdd");
    Date date = toDateFormat.parse(dateText);

    Calendar cal = Calendar.getInstance();
    cal.setTime(date);

    int dow = cal.get(Calendar.DAY_OF_WEEK);
    switch (dow) {
        case Calendar.THURSDAY:
        case Calendar.FRIDAY:
        case Calendar.SATURDAY:
        case Calendar.SUNDAY:
            while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.THURSDAY) {
                cal.add(Calendar.DATE, -1);
            }
            break;
        case Calendar.MONDAY:
        case Calendar.TUESDAY:
        case Calendar.WEDNESDAY:
            while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
                cal.add(Calendar.DATE, -1);
            }
            break;
    }

    System.out.println(date);
    System.out.println(cal.getTime());

} catch (ParseException exp) {
    exp.printStackTrace();
}

So, based on this example, it would output...

Wed Feb 27 00:00:00 EST 2013
Mon Feb 25 00:00:00 EST 2013

For 20130224 (which is a Sunday) it will give

Sun Feb 24 00:00:00 EST 2013
Thu Feb 21 00:00:00 EST 2013

I should also add, there's probably a much easier way to do this with JodaTime, but this is what I was able to wipe up quickly. Yes, I know the case statement is little winded, but SUNDAY is equal to 0, which is a little annoying ;)

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thanks MadProgrammer.. In your example you have `dateText` as hardcoded.. How do I get that when I will be actually running my program? And also I need to get Thursday and Monday date in YYYYMMDD format.. –  Feb 26 '14 at 04:03
  • Replace it (dateText) with what ever variable you want...The use the original date formatter that parsed the `String` value to `Date` to format it back again...`dateText = toDateFormat.format(cal.getTime())` – MadProgrammer Feb 26 '14 at 04:08
  • Make sense now.. I updated my question with the code example.. Can you take a look and let me know if that's what you meant and it is correct? –  Feb 26 '14 at 04:20
  • `Calendar.getInstance()` returns an instance of `Calendar` the current date and time, so you don't need to format it and parse it, just use it... – MadProgrammer Feb 26 '14 at 04:22
  • Sure.. got it now.. Basically you provided an example for me to understand.. I don;t need those parse and format at all.. –  Feb 26 '14 at 04:28
  • I didn't realise you were using a `Date` and assumed you had a `String` value – MadProgrammer Feb 26 '14 at 04:29
  • Yeah.. I was dealing with date as I need to identify date at runtime.. I updated my code again with your suggestion.. Take a look and it should be in the way you were suggesting me.. –  Feb 26 '14 at 04:34
  • So long as it's giving you the results you expect, that would be the right direction – MadProgrammer Feb 26 '14 at 04:39
0

I would use the calendar class day to get the day of the week. Calendar.DAY_OF_WEEK function returns 1 - 7 for Sunday - Saturday. This way you can do numeric comparison and not mess around with comparing the strings for the weekdays (which would be a mess if your app needs to support multiple languages).

See:

http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html

Kenny Drobnack
  • 171
  • 2
  • 12
0

If I understood what you're after, then this should work

private static final java.text.SimpleDateFormat sdf = 
  new java.text.SimpleDateFormat("yyyyMMdd");
public static String calculateCorrectDate(
    java.util.Date d) {
  java.util.Calendar cal = java.util.Calendar
      .getInstance();
  cal.setTime(d);
  int dayOfWeek = cal
      .get(java.util.Calendar.DAY_OF_WEEK);
  if (dayOfWeek >= java.util.Calendar.MONDAY
      && dayOfWeek < java.util.Calendar.THURSDAY) {
    cal.set(java.util.Calendar.DAY_OF_WEEK,
        java.util.Calendar.MONDAY);
  } else {
    cal.set(java.util.Calendar.DAY_OF_WEEK,
        java.util.Calendar.THURSDAY);
  }
  return sdf.format(cal.getTime());
}
public static void main(String[] args) {
  java.util.List<java.util.Date> dates = new java.util.ArrayList<java.util.Date>();
  java.util.Calendar cal = java.util.Calendar
      .getInstance();
  String today = sdf.format(cal.getTime());

  cal.add(java.util.Calendar.DAY_OF_WEEK, -10);
  for (int i = 0; i < 20; i++) {
    dates.add(cal.getTime());
    cal.add(java.util.Calendar.DAY_OF_WEEK, 1);
  }
  for (java.util.Date d : dates) {
    if (sdf.format(d).equals(today)) {
      System.out.println("TODAY!");
    }
    System.out.println(calculateCorrectDate(d));
  }
}

Which gives the output

20140213
20140220
20140217
20140217
20140217
20140220
20140220
20140220
20140227
20140224
TODAY!
20140224
20140224
20140227
20140227
20140227
20140306
20140303
20140303
20140303
20140306

or with a few import(s),

// Import Static
// This simplifies accessing the Calendar fields. Use sparingly.
import static java.util.Calendar.DAY_OF_WEEK;
import static java.util.Calendar.MONDAY;
import static java.util.Calendar.THURSDAY;

// The other imports.
import java.util.Calendar;
import java.util.Date;

Then you can use,

public static String calculateCorrectDate(Date d) {
  Calendar cal = Calendar.getInstance();
  cal.setTime(d);
  // By using import static this remains concise and correct.
  int dayOfWeek = cal.get(DAY_OF_WEEK);
  if (dayOfWeek >= MONDAY && dayOfWeek < THURSDAY) {
    cal.set(DAY_OF_WEEK, MONDAY);
  } else {
    cal.set(DAY_OF_WEEK, THURSDAY);
  }
  return sdf.format(cal.getTime());
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • What do you have against imports? – Obicere Feb 26 '14 at 02:51
  • @Obicere Nothing, but in this case you should then also use import static. Also, OP didn't specify a class name so ... – Elliott Frisch Feb 26 '14 at 03:09
  • @ElliottFrisch: Thanks for suggestion.. In your example what is `sdf`, how do you initialize `SimpleDateFormat`? –  Feb 26 '14 at 04:00
  • @SSH Edited to include that. – Elliott Frisch Feb 26 '14 at 04:07
  • Thanks.. Quick question.. Do I need these for loop which you have in your example? Basically, I would like to get date for THURSDAY or MONDAY depending on when I am running my program and certain conditions which I have mentioned in my question. –  Feb 26 '14 at 04:10
  • @SSH My example was to demonstrate correctness. For your program, `System.out.println(calculateCorrectDate(new java.util.Date()));` – Elliott Frisch Feb 26 '14 at 04:13
0

Joda-Time


UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This Answer is left intact as history. See my modern Answer instead.


Yes, Joda-Time is the solution.

Or the new java.time package in Java 8. Inspired by Joda-Time but re-architected. Defined by JSR 310.

Next Monday/Thursday

Search StackOverflow for getting first or last day of week. That will show you how to get next monday or thursday. I won't cover that part of your question here.

Testing Day Of Week

Testing for the day of week by the English word is prone to break if you ever happen to run where English is not the default locale. Instead, get day of week by number. Joda-Time uses ISO 8601 as its defaults, so Monday = 1, Sunday = 7. Constants are provided, so you needn't memorize the numbers.

Date Without Time

If you truly don't care about time-of-day, only date, then we can use LocalDate rather than DateTime.

Example Code

Some code to get you started, using Joda-Time 2.3.

String input = "20130224";
DateTimeFormatter formatterInput = DateTimeFormat.forPattern( "yyyyMMdd" );
LocalDate localDate = formatterInput.parseLocalDate( input );
int dayOfWeek = localDate.getDayOfWeek();
boolean isMonday = ( localDate.getDayOfWeek() == DateTimeConstants.MONDAY );
boolean isThursday = ( localDate.getDayOfWeek() == DateTimeConstants.THURSDAY );

Dump to console…

System.out.println( "localDate: " + localDate );
System.out.println( "dayOfWeek: " + dayOfWeek );
System.out.println( "isMonday: " + isMonday );
System.out.println( "isThursday: " + isThursday );

When run…

localDate: 2013-02-24
dayOfWeek: 7
isMonday: false
isThursday: false
Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

tl;dr

If:

EnumSet.range( DayOfWeek.MONDAY , DayOfWeek.WEDNESDAY )  // Monday, Tuesday, & Wednesday.
    contains( LocalDate.now().getDayOfWeek() )           // If today’s date is a day-of-week that happens to be a member of that `Set`.

…then, apply:

 TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY )    // Adjust into an earlier `LocalDate` that is a Monday, unless today already is Monday.

…else apply:

 TemporalAdjusters.previousOrSame( DayOfWeek.THURSDAY )  // Otherwise move to a Thursday.

java.time

The modern approach uses the java.time classes. So much easier to solve this Question.

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Or specify a date. 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.

Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

DayOfWeek enum

The DayOfWeek enum defines a set of seven objects, one for each day of the week.

An EnumSet is a highly-optimized implementation of Set for collecting enum objects. So we can make a pair of EnumSet objects to hold a collection of DayOfWeek objects to define your two conditions: (Monday & Tuesday) versus (Thursday…Sunday).

Despite mysteriously failing to implement SortedSet, an EnumSet is indeed sorted in the natural order (declared order) of the enum. For DayOfWeek that would be Monday-Sunday, numbered 1-7 though you may never need those numbers.

Set < DayOfWeek > mondayDays = EnumSet.range( DayOfWeek.MONDAY , DayOfWeek.WEDNESDAY );  // Monday, Tuesday, & Wednesday.
Set < DayOfWeek > thursdayDays = EnumSet.range( DayOfWeek.THURSDAY , DayOfWeek.SUNDAY );  // Thursday, Friday, Saturday, Sunday.

Get the day-of-week for our source date. Prepare to match that against our enum sets.

LocalDate ld = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ;  // Get today’s current date in a particular time zone.
DayOfWeek dow = ld.getDayOfWeek();
LocalDate target = LocalDate.EPOCH;  // Or null. The `LocalDate.EPOCH` is first moment of 1970 in UTC, 1970-01-01T00:00:00Z.

See which Set has the day-of-week of our date. From there, adjust into a previous or same date for the desired day-of-week (Monday or Thursday).

if ( mondayDays.contains( dow ) )
{
    target = ld.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) );
} else if ( thursdayDays.contains( dow ) )
{
    target = ld.with( TemporalAdjusters.previousOrSame( DayOfWeek.THURSDAY ) );
} else
{
    System.out.println( "ERROR - Unexpectedly reached IF-ELSE. " );
}

Generate string in your desired format. Your chosen format happens to be the “basic” version of standard ISO 8601 format where the use of delimiters is minimized.

String output = target.format( DateTimeFormatter.BASIC_ISO_DATE ) ;  // YYYY-MM-DD

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?

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154