CalendarDate
Die Klasse CalendarDate stellt ein Datum dar in Form von nur drei Feldern: year, month, day.
Die Konstruktoren der Klasse CalendarDate sind:
public CalendarDate()
public CalendarDate(final long year, final long month, final long day)
Zusätzlich hat die Klasse folgende zwei statische Methoden days und toCalendarDate zur Konvertierung von CalendarDate nach Tagen und von Tagen nach CalendarDate:
/* return day number, or throw IllegalArgumentException if bad date */
public static long days(final CalendarDate date)
/* convert day number to CalendarDate (year,month,day)*/
public static CalendarDate toCalendarDate(final long dayNumber)
Diese Methoden basieren auf den Date calculation algorithms und ermöglichen die Berechnung der Anzahl von Tagen zwischen zwei Daten, sowie die Addition einer Anzahl von Tagen auf ein Datum.
Die weiter unten stehende Klasse CalendarDateDemo zeigt ein Anwendungsbeispiel:
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.
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;
}
}
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);
}
}