net.time4j.engine.EpochDays Maven / Gradle / Ivy
/*
* -----------------------------------------------------------------------
* Copyright © 2013-2014 Meno Hochschild,
* -----------------------------------------------------------------------
* This file (EpochDays.java) is part of project Time4J.
*
* Time4J is free software: You can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* Time4J is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Time4J. If not, see .
* -----------------------------------------------------------------------
*/
package net.time4j.engine;
import net.time4j.base.MathUtils;
/**
* Defines elements based on different epoch-related day numbers.
*
* Some day number procedures really use decimal fractions in order to
* represent wall time fractions in calendar dates (for example julian days).
* This enum only supports pure date types of type {@code Calendrical} and
* always uses the largest integer which is still smaller than or equal to
* the decimal fraction in question (mathematically a
* {@code floor()}-function.
*
* Instances of this element class will be automatically registered in
* any chronology which is compatible to {@code Calendrical}.
*
* @author Meno Hochschild
* @see Calendrical
*/
/*[deutsch]
* Definiert Elemente auf der Basis von verschiedenen epochenbezogenen
* Tagesnummern.
*
* Einige Tagesnummerierungsverfahren benutzen real Dezimalbrüche
* zur Darstellung von Uhrzeitanteilen in Datumsangaben. Dieses Enum
* unterstützt nur reine Datumstypen vom Typ {@code Calendrical}
* und benutzt immer die größte Integer-Zahl, die noch kleiner
* oder gleich dem jeweiligen Dezimalbruch ist (mathematisch eine
* {@code floor()}-Funktion.
*
* Instanzen dieser Elementklasse werden in einer zur Klasse
* {@code Calendrical} kompatiblen Chronologie automatisch registriert.
*
* @author Meno Hochschild
* @see Calendrical
*/
public enum EpochDays
implements ChronoElement {
//~ Statische Felder/Initialisierungen --------------------------------
/**
* Reference point is the introduction of UTC on date [1972-01-01]
* at midnight as day zero.
*/
/*[deutsch]
* Bezugspunkt ist die Einführung von UTC zum Datum [1972-01-01]
* zu Mitternacht als Tag 0.
*/
UTC(2441317),
/**
* Reference point is the first of January 1970 at midnight as
* day zero.
*
* Example:
*
*
* import static net.time4j.Month.FEBRUARY;
*
* PlainDate date = PlainDate.of(1970, FEBRUARY, 4);
* System.out.println(date.get(EpochDays.UNIX)); // output: 34
*
*
* Strictly spoken, the UNIX time is counted in seconds. This element
* counts in days based on the relation "1 day = 86400 seconds".
*
*/
/**
* Bezugspunkt ist der erste Januar 1970 Mitternacht als Tag 0.
*
* Beispiel:
*
*
* import static net.time4j.Month.FEBRUARY;
*
* PlainDate date = PlainDate.of(1970, FEBRUARY, 4);
* System.out.println(date.get(EpochDays.UNIX)); // Ausgabe: 34
*
*
* Streng genommen wird die UNIX-Zeit in Sekunden gezählt. Dieses
* Element benutzt für den Zweck der Datumsumrechnung die Zählung
* in ganzen Tagen auf der Basis "1 Tag = 86400 Sekunden".
*/
UNIX(2440587),
/**
* Count of days relative to the ISO-date [1858-11-17] as day zero.
*
* Used by astronomers for example.
*/
/*[deutsch]
* Anzahl der Tage relativ zum ISO-Datum [1858-11-17] als Tag 0.
*
* Wird u.a. von Astronomen verwendet.
*/
@FormattableElement(format = "g")
MODIFIED_JULIAN_DATE(2400000),
/**
* Count of days relative to the ISO-date [1900-01-01] as day 1.
*
* Used by MS-Excel in Windows operating systems.
*/
/*[deutsch]
* Anzahl der Tage relativ zum ISO-Datum [1900-01-01] als Tag 1.
*
* Wird von MS-Excel in Windows-Betriebssystemen verwendet.
*/
EXCEL(2415019),
/**
* Count of days relative to the ISO-date [1601-01-01] as day 1.
*
* Used by COBOL for example.
*/
/*[deutsch]
* Anzahl der Tage relativ zum ISO-Datum [1601-01-01] als Tag 1.
*
* Wird u.a. von COBOL verwendet.
*/
ANSI(2305812),
/**
* Count of days relative to the ISO-date [0001-01-01] as day 1.
*
* Used by the autors Nachum Dershowitz and Edward M. Reingold in
* their standard work "CalendarDate Calculations".
*/
/*[deutsch]
* Anzahl der Tage relativ zum ISO-Datum [0001-01-01] als Tag 1.
*
* Wird im Standard-Werk "CalendarDate Calculations" von den
* Autoren Nachum Dershowitz und Edward M. Reingold benutzt.
*/
RATA_DIE(1721424),
/**
* Count of julian days relative to the the julian calendar date
* [1st of January 4713 BC] at noon [12:00] as day zero.
*
* The julian epoch date corresponds to the proleptic ISO-date
* [-4713-11-24]. The ISO-day centered around noon will be taken into
* account whose associated julian day starts at noon.
*/
/*[deutsch]
* Anzahl der julianischen Tage relativ zum julianischen Datum
* [1 Januar 4713 BC] zur Mittagszeit [12:00] als Tag 0.
*
* Das julianische Epochendatum entspricht im proleptischen
* gregorianischen Kalender (ISO) dem Datum [-4713-11-24]. Als Tag
* wird der zentrisch um 12 Uhr Mittag angeordnete Tag gezählt,
* dessen zugeordneter julianischer Tag erst ab Mittag beginnt.
*/
// eigentlich -0.5, Umrechnung zur Mittagszeit
JULIAN_DAY_NUMBER(-1),
/**
* Count of days relative to gregorian cut-over date
* [1582-10-15] as day 1.
*/
/*[deutsch]
* Anzahl der Tage relativ zum gregorianischen Umstellungsdatum
* [1582-10-15] als Tag 1.
*/
LILIAN_DAY_NUMBER(2299159);
//~ Instanzvariablen --------------------------------------------------
private final int offset;
//~ Konstruktoren -----------------------------------------------------
private EpochDays(int julianDays) {
this.offset = julianDays - 2440587 - 2 * 365;
}
//~ Methoden ----------------------------------------------------------
/**
* Converts given day number to a day number based on this epoch
* at reference time of midnight.
*
* @param amount count of days relative to given epoch at noon
* @param epoch epoch reference
* @return count of days relative to this epoch
*/
/*[deutsch]
* Rechnet die angegebene Tageszahl in eine Tageszahl auf der
* Nummerierungsbasis dieser Instanz zur Mittagszeit um.
*
* @param amount count of days relative to given epoch at noon
* @param epoch epoch reference
* @return count of days relative to this epoch
*/
public long transform(
long amount,
EpochDays epoch
) {
return MathUtils.safeAdd(
amount,
(epoch.offset - this.offset)
);
}
@Override
public Class getType() {
return Long.class;
}
/**
* Defines the format symbol.
*
* @return "g" if MODIFIED_JULIAN_DATE else ASCII-0
*/
/*[deutsch]
* Definiert das Formatsymbol.
*
* @return "g" if MODIFIED_JULIAN_DATE else ASCII-0
*/
@Override
public char getSymbol() {
return ((this == MODIFIED_JULIAN_DATE) ? 'g' : '\u0000');
}
@Override
public int compare(
ChronoDisplay o1,
ChronoDisplay o2
) {
return o1.get(this).compareTo(o2.get(this));
}
@Override
public Long getDefaultMinimum() {
// PlainTime.MIN.get(EpochDays.UTC) - offset
return Long.valueOf(-365243219892L - this.offset);
}
@Override
public Long getDefaultMaximum() {
// PlainTime.MAX.get(EpochDays.UTC) - offset
return Long.valueOf(365241779741L - this.offset);
}
/**
* This element is a date element.
*
* @return {@code true}
*/
/*[deutsch]
* Dieses Element ist ein Datumselement.
*
* @return {@code true}
*/
@Override
public boolean isDateElement() {
return true;
}
/**
* This element is no wall time element.
*
* @return {@code false}
*/
/*[deutsch]
* Dieses Element ist kein Uhrzeitelement.
*
* @return {@code false}
*/
@Override
public boolean isTimeElement() {
return false;
}
@Override
public boolean isLenient() {
return false;
}
/**
* Leitet eine Regel ab.
*
* @param generic chronology type
* @param calsys calendar system
* @return new element rule for this epoch reference
*/
>
ElementRule derive(CalendarSystem calsys) {
return new Rule(this, calsys);
}
//~ Innere Klassen ----------------------------------------------------
private static class Rule>
implements ElementRule {
//~ Statische Felder/Initialisierungen ----------------------------
private static final int UTC_OFFSET = 2 * 365;
//~ Instanzvariablen ----------------------------------------------
private final EpochDays element;
private final CalendarSystem calsys;
//~ Konstruktoren -------------------------------------------------
Rule(
EpochDays element,
CalendarSystem calsys
) {
super();
this.element = element;
this.calsys = calsys;
}
//~ Methoden ------------------------------------------------------
@Override
public Long getValue(D context) {
long days =
this.element.transform(
this.calsys.transform(context) + UTC_OFFSET,
EpochDays.UNIX);
return Long.valueOf(days);
}
@Override
public boolean isValid(
D context,
Long value
) {
long days =
MathUtils.safeSubtract(
EpochDays.UNIX.transform(value.longValue(), this.element),
UTC_OFFSET
);
return (
(days <= this.calsys.getMaximumSinceUTC())
&& (days >= this.calsys.getMinimumSinceUTC())
);
}
@Override
public D withValue(
D context,
Long value,
boolean lenient
) {
long utcDays =
MathUtils.safeSubtract(
EpochDays.UNIX.transform(value.longValue(), this.element),
UTC_OFFSET
);
return this.calsys.transform(utcDays);
}
@Override
public Long getMinimum(D context) {
long days =
this.element.transform(
this.calsys.getMinimumSinceUTC() + UTC_OFFSET,
EpochDays.UNIX
);
return Long.valueOf(days);
}
@Override
public Long getMaximum(D context) {
long days =
this.element.transform(
this.calsys.getMaximumSinceUTC() + UTC_OFFSET,
EpochDays.UNIX
);
return Long.valueOf(days);
}
@Override
public ChronoElement> getChildAtFloor(D context) {
return null;
}
@Override
public ChronoElement> getChildAtCeiling(D context) {
return null;
}
}
}