Kalendarz, wyświetlanie dni od - do po podaniu dat w dialogu

0

Cześć, to jest treść zadania:

Zadanie 3. Kalendarz (max 5 punktów)

Napisać program który tworzy "kalendarz:". Użytkownik podaje w jednym dialogu showInputDialog datę "od" i datę "do" rozdzielone spacjami, a program wypisuje listę dat wraz ze skrótami nazw dni tygodnia w pokazanje dalej postaci.

Przykład:
po podaniu w dialogu napisu:
2010-12-17 2010-12-20
program wyprowadza:
17.12.2010 Pt
18.12.2010 So
19.12.2010 N
20.12.2010 Pn

Format wejścia i wyjścia (pokazany w przykładzie) jest obowiązkowy.

Należy obsłużyć niewłaściwe daty poprzez wyprowadzenie informacji o błędzie (jaki napis nie może być zinterpretowany jako włąsciwa data) i zakończenie programu.
Podpowiedź: zob. metodę setLenient z klasy Calendar, użyj Formattera, nie używaj wyrażeń regularnych (bo będzie łatwiej).

Tu rozwiązanie za które dostałem 0 punktów i o ile obsługa wyjątków to zwykłe przeoczenie (miałem ciężki miesiąc zapomniałem dokończyć) to nie mam pomysłu jak zrobić, żeby po podaniu daty w styczniu nie wywalało błędu. Ktoś ma jakiś pomysł?

KOD:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Scanner;

import javax.swing.JOptionPane;

public class Main {

	@SuppressWarnings("resource")
	public static void main(String[] args) {

		String setDates = JOptionPane.showInputDialog(null,
				"Podaj datę \"od\" i datę \"do\"");
		Scanner scan = null;
		scan = new Scanner(setDates).useDelimiter("[^0-9]+");
		int startDateYear = scan.nextInt();
		int startDateMonth = (scan.nextInt() - 1);
		int startDateDay = scan.nextInt();
		int endDateYear = scan.nextInt();
		int endDateMonth = (scan.nextInt() - 1);
		int endDateDay = scan.nextInt();
		scan.close();
		String startDateInString = startDateYear + "-" + startDateMonth + "-"
				+ startDateDay;
		String endDateInString = endDateYear + "-" + endDateMonth + "-"
				+ endDateDay;

		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		formatter.setLenient(false);
		try {
			formatter.parse(startDateInString);
			formatter.parse(endDateInString);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		Calendar startDate = Calendar.getInstance();
		startDate.set(startDateYear, startDateMonth, startDateDay);
		Calendar endDate = Calendar.getInstance();
		endDate.set(endDateYear, endDateMonth, endDateDay);

		SimpleDateFormat formatter2 = new SimpleDateFormat("dd.MM.yyyy EEE");
		for (int i = 0; !(startDate.equals(endDate)); i = 1) {
			startDate.add(Calendar.DAY_OF_MONTH, i);
			String formatted2 = formatter2.format(startDate.getTime());
			System.out.println(formatted2);
		}
	}
}
1

Moim zdaniem zupełnie nie zrozumiałeś zadania. Skoro format wejścia jest obowiązkowy, to użytkownik musi wprowadzić datę zgodnie z tym formatem, jeśli wprowadzi źle to komunikat i koniec programu.
Błąd w Twoim kodzie, bierze się stąd, że co prawda miesiące mają wewnętrznie numery 0-11, ale metody parsujące oczekują miesiąca od 1 do 12.

int startDateMonth = (scan.nextInt());
...
int endDateMonth = (scan.nextInt());
...
startDate.set(startDateYear, startDateMonth-1, startDateDay);
...
endDate.set(endDateYear, endDateMonth-1, endDateDay);
1

Sugeruję pisanie od początku - końcowy fragment może zostać:

        SimpleDateFormat formatter2 = new SimpleDateFormat("dd.MM.yyyy EE");
        for (int i = 0; !(startDate.equals(endDate)); i = 1) {
            startDate.add(Calendar.DAY_OF_MONTH, i);
            String formatted2 = formatter2.format(startDate.getTime());
            System.out.println(formatted2);
        }
1

Nie znam prostej konwersji z Date na Calendar, więc nie wykorzystuję wyniku parsowania. Parsowanie służy tylko do kontroli poprawności.

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        formatter.setLenient(false);
        boolean ok = true;
        String dateFrom = "";
        String dateTo = "";
        
        String setDates = JOptionPane.showInputDialog(null,"<html><center>Podaj daty \"od\" i \"do\" rozdzielone spacjami"+
                  "<br>Wymagany format daty: yyyy-mm-dd</center></html>");        
        Scanner scan = new Scanner(setDates);
        ok = scan.hasNext();     
        if(ok)
        {          
            dateFrom = scan.next();
            try
            {
                formatter.parse(dateFrom);
            }
            catch(Exception e)
            {
                ok = false;
            }
        }
        ok = ok && scan.hasNext();
        if(ok)
        {          
            dateTo = scan.next();
            try
            {
                formatter.parse(dateTo);
            }
            catch(Exception e)
            {
                ok = false;
            }
        }             
        

        if(!ok)
        {
            JOptionPane.showMessageDialog(null,"Niepoprawne dane wejściowe","",JOptionPane.ERROR_MESSAGE);             
            System.exit(0);
        }
        Calendar startDate = Calendar.getInstance();
        Calendar endDate = Calendar.getInstance();
        scan = new Scanner(dateFrom).useDelimiter("-");
        startDate.set(scan.nextInt(),scan.nextInt()-1,scan.nextInt());
        scan = new Scanner(dateTo).useDelimiter("-");
        endDate.set(scan.nextInt(),scan.nextInt()-1,scan.nextInt());
0

Witam,

chciałem odgrzebać powyższy wątek.
A jak się zabezpieczyć na sytuację aby pierwsza podana data nie była późniejsza niż druga?:)

Pozdrawiam,
Arek

0

Porównaj (używając metody compareTo(...)) podane daty.

0

A czy compareTo nie służy do porównywania stringów?
Jak uzyskam info, która data jest późniejsza?

0
bogdans napisał(a):

https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#compareTo-java.util.Calendar-

Dziękuję bardzo, dopiero się dowiaduje jak w Javie kryją się cuda:)

0

Mam jeszcze jedno pytanie do tego kodu.
Obsługujemy już daty podane w prawidłowym zakresie wcześniejsza-późniejsza, późniejsza-wcześniejsza, jednak dla dat jednakowych program nie wykonuje żadnej operacji. Wydaje mi się, że powinien zwrócić raz tę datę z dniem tygodnia. Gdzie tu jest pies pogrzebany?

1

Myślę, że w błędnym kodzie.

0

Próbuję to właśnie zrozumieć:)

Który fragment należy zmodyfikować aby otrzymać wynik również dla takich samych dat:

c3919dbbaa.png

0

Nie rozumiem po co Ci pętla do wyświetlenia jednej daty. Poniższy kod wyświetla wszystkie daty od startDate do endDate.

while(startDate.compareTo(endDate) <= 0){
    System.out.println(formatter2.format(startDate.getTime()));
    startDate.add(Calendar.DAY_OF_MONTH,1);
}
0

Teraz to ja się pogubiłem:)
Odnoszę się jedynie do kodu, który został wcześniej podany w tym wątku do zadania przedstawione przez innego użytkownika - ja jedynie chciałbym zadanie dobrze zrozumieć stąd moje dodatkowe pytania, które nie były poruszane wcześniej a które wydają się niezbędne aby kompletnie rozwiązaniu zadanie.

OK, potestuję potem to co napisałeś.
Bardzo dziękuję za pomoc.

Pozdrawiam,
Arek

0
bogdans napisał(a):

Nie rozumiem po co Ci pętla do wyświetlenia jednej daty. Poniższy kod wyświetla wszystkie daty od startDate do endDate.

while(startDate.compareTo(endDate) <= 0){
    System.out.println(formatter2.format(startDate.getTime()));
    startDate.add(Calendar.DAY_OF_MONTH,1);
}

a co w sytuacji jak startDate.compareTo(endDate) == 1 ?
System się zapląta.

0

zapląta się w sensie, że nie zareaguje.
Da się dodać do while instrukcję jak warunek nie jest spełniony?

0

OK, udało mi się ale z eleganckim kodem nie ma to wiele wspólnego...

SimpleDateFormat formatter2 = new SimpleDateFormat("dd.MM.yyyy EEE");
            if (startDate.compareTo(endDate) <= 0) {
        	for (int i = 0; (startDate.compareTo(endDate) <= 0); i = 1){
        		  System.out.println(formatter2.format(startDate.getTime()));
              	startDate.add(Calendar.DAY_OF_MONTH,1); }}
        	else System.out.println("Pierwsza podana data musi być wcześniejsza od drugiej podanej daty!");}

Jak to zapisać prościej?
Chodzi mi o to aby nie powtarzać dwa razy warunku:
(startDate.compareTo(endDate)

Będę wdzięczny za pomoc.

0

Użyj pętli while jak normalny człowiek a nie jakieś cuda na kiju.

0
Shalom napisał(a):

Użyj pętli while jak normalny człowiek a nie jakieś cuda na kiju.

Próbowałem, ale chcę mieć jeszcze komunikat gdy warunek z while nie jest spełniony i nie wiem jak to zrobić.

0
boolean ok = false;
while(startDate.compareTo(endDate) <= 0){
    ok = true;
    System.out.println(formatter2.format(startDate.getTime()));
    startDate.add(Calendar.DAY_OF_MONTH,1);
}
if(!ok){
    System.out.println("Pierwsza podana data nie może być późniejsza od drugiej podanej daty!");
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1