CalendarDate: Unterschied zwischen den Versionen

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen
K
K
Zeile 1: Zeile 1:
Die Klasse CalendarDate basiert auf den Algoritmen, die hier vorgestellt werden: http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html .
+
Die Klasse '''CalendarDate''' basiert auf den '''[http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html Date calculation algorithms]'''.
  
 +
Sie ermöglicht die Berechnung der Anzahl von Tagen zwischen zwei Daten, sowie die Addition einer Anzahl von Tagen auf ein Datum.
 +
 +
Die Konstruktoren der Klasse '''CalendarDate''' sind:
 +
 +
    <code=java>public CalendarDate()</code=java>
 +
 +
    <code=java>public CalendarDate(final long year, final long month, final long day)</code=java>
 +
 +
Das Herzstück der Klasse sind folgende zwei statische Methoden '''toCalendarDate''' und '''days''' zur Konvertierung von und nach CalendarDate:
 +
 +
    <code=java>/* convert day number to CalendarDate (year,month,day)*/
 +
    public static CalendarDate toCalendarDate(final long dayNumber)</code=java>
 +
 +
    <code=java>/* return day number, or throw IllegalArgumentException if bad date */
 +
    public static long days(final CalendarDate date)</code=java>
 +
 
Die weiter unten stehende Klasse CalendarDateDemo zeigt ein Anwendungsbeispiel:
 
Die weiter unten stehende Klasse CalendarDateDemo zeigt ein Anwendungsbeispiel:
  
Zeile 14: Zeile 30:
 
<code=java>
 
<code=java>
 
import java.util.Calendar;
 
import java.util.Calendar;
 
+
 
public class CalendarDate {
 
public class CalendarDate {
 
+
 
     private long year;
 
     private long year;
 
     private long month;
 
     private long month;
Zeile 23: Zeile 39:
 
     private static long calstart = days(new CalendarDate(1582, 10, 1));
 
     private static long calstart = days(new CalendarDate(1582, 10, 1));
 
     final static Calendar NOW = Calendar.getInstance();
 
     final static Calendar NOW = Calendar.getInstance();
 
+
 
     public CalendarDate() {
 
     public CalendarDate() {
 
         this(NOW.get(Calendar.YEAR), NOW.get(Calendar.MONTH) + 1, NOW.get(Calendar.DAY_OF_MONTH));
 
         this(NOW.get(Calendar.YEAR), NOW.get(Calendar.MONTH) + 1, NOW.get(Calendar.DAY_OF_MONTH));
 
     }
 
     }
 
+
 
     public CalendarDate(final long year, final long month, final long day) {
 
     public CalendarDate(final long year, final long month, final long day) {
 
         this.year = year;
 
         this.year = year;
Zeile 33: Zeile 49:
 
         this.day = day;
 
         this.day = day;
 
     }
 
     }
 
+
 
     /* convert day number to CalendarDate (year,month,day)*/
 
     /* convert day number to CalendarDate (year,month,day)*/
 
     public static CalendarDate toCalendarDate(final long dayNumber) {
 
     public static CalendarDate toCalendarDate(final long dayNumber) {
Zeile 47: Zeile 63:
 
                 day - (month * 306 + 5) / 10 + 1);
 
                 day - (month * 306 + 5) / 10 + 1);
 
     }
 
     }
 
+
 
     /* return day number, or throw IllegalArgumentException if bad date */
 
     /* return day number, or throw IllegalArgumentException if bad date */
 
     public static long days(final CalendarDate date) {
 
     public static long days(final CalendarDate date) {
Zeile 59: Zeile 75:
 
         return dayNumber;
 
         return dayNumber;
 
     }
 
     }
 
+
 
     /* convert date to day number */
 
     /* convert date to day number */
     public static long toDay(final CalendarDate d) {
+
     private static long toDay(final CalendarDate d) {
 
         long month = (d.getMonth() + 9) % 12; //mar=0, feb=11
 
         long month = (d.getMonth() + 9) % 12; //mar=0, feb=11
 
         long year = d.getYear() - month / 10;  //if Jan/Feb, year--
 
         long year = d.getYear() - month / 10;  //if Jan/Feb, year--
Zeile 67: Zeile 83:
 
                 + (month * 306 + 5) / 10 + (d.getDay() - 1);
 
                 + (month * 306 + 5) / 10 + (d.getDay() - 1);
 
     }
 
     }
 
+
 
     @Override
 
     @Override
 
     public String toString() {
 
     public String toString() {
 
         return getYear() + "." + getMonth() + "." + getDay();
 
         return getYear() + "." + getMonth() + "." + getDay();
 
     }
 
     }
 
+
 
     public long getYear() {
 
     public long getYear() {
 
         return year;
 
         return year;
 
     }
 
     }
 
+
 
     public long getMonth() {
 
     public long getMonth() {
 
         return month;
 
         return month;
 
     }
 
     }
 
+
 
     public long getDay() {
 
     public long getDay() {
 
         return day;
 
         return day;
 
     }
 
     }
 
+
 
     public static long getCalstart() {
 
     public static long getCalstart() {
 
         return calstart;
 
         return calstart;
 
     }
 
     }
 
+
 
     @Override
 
     @Override
 
     @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")
 
     @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")
Zeile 110: Zeile 126:
 
         return true;
 
         return true;
 
     }
 
     }
 
+
 
     @Override
 
     @Override
 
     public int hashCode() {
 
     public int hashCode() {

Version vom 6. September 2011, 14:38 Uhr

Die Klasse CalendarDate basiert auf den Date calculation algorithms.

Sie ermöglicht die Berechnung der Anzahl von Tagen zwischen zwei Daten, sowie die Addition einer Anzahl von Tagen auf ein Datum.

Die Konstruktoren der Klasse CalendarDate sind:

   <code=java>public CalendarDate()</code=java>
   <code=java>public CalendarDate(final long year, final long month, final long day)</code=java>

Das Herzstück der Klasse sind folgende zwei statische Methoden toCalendarDate und days zur Konvertierung von und nach CalendarDate:

   <code=java>/* convert day number to CalendarDate (year,month,day)*/
   public static CalendarDate toCalendarDate(final long dayNumber)</code=java>

   <code=java>/* return day number, or throw IllegalArgumentException if bad date */
   public static long days(final CalendarDate date)</code=java>

Die weiter unten stehende Klasse CalendarDateDemo zeigt ein Anwendungsbeispiel:

CalendarDateDemo.jpg

In die beiden weißen Textfelder (oben) kann man folgendes eingeben: erstes Feld: ein Datum, zweites Feld: leer (in diesem Fall wird dort das aktuelle Datum angenommen) oder erstes Feld: ein Datum, zweites Feld: eine Anzahl von Tagen (ein Minus vor der Zahl ist erlaubt) oder erstes Feld: ein Datum, zweites Feld: ein anderes Datum.

Das grau hinterlegte Feld zeigt das Resultat der Berechnung, d.h. die Anzahl der Tage zwischen den beiden Daten, bzw. das neue Datum nach Addition der Anzahl von Tagen aus dem zweiten Feld.

Ein Datum wird in diesem Beispiel immer in der Form JJJJ.MM.TT (=Jahr.Monat.Tag) angegeben.

<code=java> import java.util.Calendar;

public class CalendarDate {

   private long year;
   private long month;
   private long day;
   //Earliest date on Gregorian calendar:
   private static long calstart = days(new CalendarDate(1582, 10, 1));
   final static Calendar NOW = Calendar.getInstance();

   public CalendarDate() {
       this(NOW.get(Calendar.YEAR), NOW.get(Calendar.MONTH) + 1, NOW.get(Calendar.DAY_OF_MONTH));
   }

   public CalendarDate(final long year, final long month, final long day) {
       this.year = year;
       this.month = month;
       this.day = day;
   }

   /* convert day number to CalendarDate (year,month,day)*/
   public static CalendarDate toCalendarDate(final long dayNumber) {
       long year = (10000 * dayNumber + 14780) / 3652425;
       long day = dayNumber - (year * 365 + year / 4 - year / 100 + year / 400);
       if (day < 0) {
           year--;
           day = dayNumber - (year * 365 + year / 4 - year / 100 + year / 400);
       }
       long month = (52 + 100 * day) / 3060;
       return new CalendarDate(year + (month + 2) / 12,
               (month + 2) % 12 + 1,
               day - (month * 306 + 5) / 10 + 1);
   }

   /* return day number, or throw IllegalArgumentException if bad date */
   public static long days(final CalendarDate date) {
       long dayNumber = toDay(date);
       if (dayNumber < calstart) {
           throw new IllegalArgumentException("WARNING: Dates before Oct. 1582 are inaccurate.");
       }
       if (!date.equals(toCalendarDate(dayNumber))) {
           throw new IllegalArgumentException("Illegal date " + date);
       }
       return dayNumber;
   }

   /* convert date to day number */
   private static long toDay(final CalendarDate d) {
       long month = (d.getMonth() + 9) % 12; //mar=0, feb=11
       long year = d.getYear() - month / 10;   //if Jan/Feb, year--
       return year * 365 + year / 4 - year / 100 + year / 400
               + (month * 306 + 5) / 10 + (d.getDay() - 1);
   }

   @Override
   public String toString() {
       return getYear() + "." + getMonth() + "." + getDay();
   }

   public long getYear() {
       return year;
   }

   public long getMonth() {
       return month;
   }

   public long getDay() {
       return day;
   }

   public static long getCalstart() {
       return calstart;
   }

   @Override
   @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")
   public boolean equals(final Object obj) {
       if (obj == null) {
           return false;
       }
       if (getClass() != obj.getClass()) {
           return false;
       }
       final CalendarDate other = (CalendarDate) obj;
       if (this.year != other.year) {
           return false;
       }
       if (this.month != other.month) {
           return false;
       }
       if (this.day != other.day) {
           return false;
       }
       return true;
   }

   @Override
   public int hashCode() {
       int hash = 3;
       hash = 59 * hash + (int) (this.year ^ (this.year >>> 32));
       hash = 59 * hash + (int) (this.month ^ (this.month >>> 32));
       hash = 59 * hash + (int) (this.day ^ (this.day >>> 32));
       return hash;
   }

} </code=java>

<code=java> import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*;

public class CalendarDateDemo {

   private CalendarDate dateResult;
   private String message;
   private long resultDays;
   public static final String USAGE = "Usage: y.m.d | y.m.d + n | y.m.d + y.m.d\n";
   public CalendarDateDemo(final String[] args) {
       if (args.length == 3 || args.length == 4 || args.length == 6) {
           message = "";
       } else {
           message = USAGE;//wrong number of arguments
       }
       long[] i = new long[args.length];
       /* Convert args to long integer */
       for (int j = 0; j < args.length; j++) {
           String string = args[j];
           try {
               i[j] = Long.parseLong(string);
           } catch (final NumberFormatException numberFormatException) {
               message += "Argument conversion error.\n";
           }
       }
       long base = 0;
       if (args.length > 3) { // arguments with base date
           try {
               base = CalendarDate.days(new CalendarDate(i[0], i[1], i[2]));
           } catch (IllegalArgumentException e) {
               message += e.getMessage() + "\n";
           }
       } else if (args.length == 3) {// no base date -> set current date as base:
           final Calendar NOW = Calendar.getInstance();
           CalendarDate date = new CalendarDate(NOW.get(Calendar.YEAR),
                   NOW.get(Calendar.MONTH) + 1, NOW.get(Calendar.DAY_OF_MONTH));
           base = CalendarDate.days(date);
       }
       //
       if ((args.length) % 3 == 1) { // Compute new date from offset
           CalendarDate date = CalendarDate.toCalendarDate(base + i[args.length - 1]);
           dateResult = date;
           resultDays = 0;
           if (base + i[args.length - 1] < CalendarDate.getCalstart()) {
               message += "WARNING: Dates before Oct. 1582 are inaccurate.\n";
           }
       } else if (args.length > 0 && args.length % 3 == 0) { // Compute days between dates
           CalendarDate date = new CalendarDate(i[args.length - 3],
                   i[args.length - 2], i[args.length - 1]);
           long days = 0;
           try {
               days = CalendarDate.days(date);
           } catch (IllegalArgumentException e) {
               message += e.getMessage() + "\n";
           }
           resultDays = days - base;
           dateResult = null;
       }
   }
   public CalendarDate getDateResult() {
       return dateResult;
   }
   public String getMessage() {
       return message;
   }
   public long getResultDays() {
       return resultDays;
   }
   private static void createAndShowGui() {
       final JFrame window = new JFrame(CalendarDateDemo.USAGE.replace("\n", ""));
       window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       window.setSize(400, 300);
       window.setLocationRelativeTo(null);
       final JTextField input1 = new JTextField(10);
       final JTextField input2 = new JTextField(10);
       final JLabel labelResult = new JLabel();
       final JTextArea labelMessage = new JTextArea();
       labelMessage.setEditable(false);
       labelMessage.setBackground(new Color(255, 255, 204));
       input1.setText(new CalendarDate().toString());
       input2.setText("2011.4.10");
       window.setLayout(new GridLayout(0, 1));
       window.add(input1);
       window.add(input2);
       window.add(labelResult);
       window.add(labelMessage);
       KeyListener listener = new KeyAdapter() {
           @Override
           public void keyReleased(final KeyEvent e) {
               String text1 = input1.getText();
               String text2 = input2.getText();
               String[] split = (text1 + "." + text2).split("\\.");
               CalendarDateDemo demo = new CalendarDateDemo(split);
               if (demo.getDateResult() != null) {
                   labelResult.setText(demo.getDateResult().toString());
               } else {
                   labelResult.setText(demo.getResultDays() + " days");
               }
               labelMessage.setText(demo.getMessage());
           }
       };
       input1.addKeyListener(listener);
       input2.addKeyListener(listener);
       window.setVisible(true);
       listener.keyReleased(null);
   }
   public static void main(final String... args) {
       Runnable gui = new Runnable() {
           public void run() {
               createAndShowGui();
           }
       };
       SwingUtilities.invokeLater(gui);
   }

} </code=java>