CalendarDate

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen

Die Klasse CalendarDate basiert auf den Algoritmen, die hier vorgestellt werden: http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html .

Die weiter unten stehende Klasse CalendarDateDemo zeigt ein Anwendungsbeispiel.

<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 */
   public 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>

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 immer in der Form JJJJ.MM.TT (=Jahr.Monat.Tag) angegeben.

<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>