org.apache.jackrabbit.rmi.value.DateValue Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jackrabbit.rmi.value;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import javax.jcr.PropertyType;
import javax.jcr.ValueFormatException;
/**
* Date value.
*/
class DateValue extends AbstractValue {
/**
* Serial version UID
*/
private static final long serialVersionUID = -2382837055824423966L;
// misc. numeric formats used in formatting
private static final DecimalFormat XX_FORMAT = new DecimalFormat("00");
private static final DecimalFormat XXX_FORMAT = new DecimalFormat("000");
private static final DecimalFormat XXXX_FORMAT = new DecimalFormat("0000");
/**
* The date value
*/
private final Calendar value;
/**
* Creates an instance for the given date value.
*
* @param value the date value
*/
public DateValue(Calendar value) {
this.value = value;
}
/**
* Returns {@link PropertyType#DATE}.
*/
public int getType() {
return PropertyType.DATE;
}
/**
* Returns a copy of this Calendar
value. Modifying the
* returned Calendar
does not change the value of this
* instance.
*/
@Override
public Calendar getDate() {
return (Calendar) value.clone();
}
/**
* The date is converted to the number of milliseconds since
* 00:00 (UTC) 1 January 1970 (1970-01-01T00:00:00.000Z).
*/
@Override
public BigDecimal getDecimal() {
return new BigDecimal(value.getTimeInMillis());
}
/**
* The date is converted to the number of milliseconds since
* 00:00 (UTC) 1 January 1970 (1970-01-01T00:00:00.000Z). If this number
* is out-of-range for a double, a ValueFormatException is thrown.
*/
@Override
public double getDouble() {
return value.getTimeInMillis();
}
/**
* The date is converted to the number of milliseconds since
* 00:00 (UTC) 1 January 1970 (1970-01-01T00:00:00.000Z). If this number
* is out-of-range for a long, a ValueFormatException is thrown.
*/
@Override
public long getLong() {
return value.getTimeInMillis();
}
/**
* The date is converted to the following format:
* sYYYY-MM-DDThh:mm:ss.sssTZD
* where:
*
* - sYYYY
* -
* Four-digit year with optional leading positive (‘+’) or
* negative (‘-’) sign. 0000 , -0000 and +0000 all indicate
* the year 1 BCE. –YYYY where YYYY is the number y indicates
* the year (y+1) BCE. The absence of a sign or the presence
* of a positive sign indicates a year CE. For example, -0054
* would indicate the year 55 BCE, while +1969 and 1969
* indicate the year 1969 CE.
*
* - MM
* -
* Two-digit month (01 = January, etc.)
*
* - DD
* -
* Two-digit day of month (01 through 31)
*
* - hh
* -
* Two digits of hour (00 through 23, or 24 if mm is 00 and
* ss.sss is 00.000)
*
* - mm
* -
* Two digits of minute (00 through 59)
*
* - ss.sss
* -
* Seconds, to three decimal places (00.000 through 59.999 or
* 60.999 in the case of leap seconds)
*
* - TZD
* -
* Time zone designator (either Z for Zulu, i.e. UTC, or +hh:mm or
* -hh:mm, i.e. an offset from UTC)
*
*
*
* Note that the “T” separating the date from the time and the
* separators “-”and “:” appear literally in the string.
*
* This format is a subset of the format defined by ISO 8601:2004.
* If the DATE value cannot be represented in this format a
* {@link ValueFormatException} is thrown.
*/
public String getString() {
// determine era and adjust year if necessary
int year = value.get(Calendar.YEAR);
if (value.isSet(Calendar.ERA)
&& value.get(Calendar.ERA) == GregorianCalendar.BC) {
// calculate year using astronomical system:
// year n BCE => astronomical year - n + 1
year = 0 - year + 1;
}
// note that we cannot use java.text.SimpleDateFormat for
// formatting because it can't handle years <= 0 and TZD's
StringBuilder buf = new StringBuilder(32);
// year ([-]YYYY)
buf.append(XXXX_FORMAT.format(year));
buf.append('-');
// month (MM)
buf.append(XX_FORMAT.format(value.get(Calendar.MONTH) + 1));
buf.append('-');
// day (DD)
buf.append(XX_FORMAT.format(value.get(Calendar.DAY_OF_MONTH)));
buf.append('T');
// hour (hh)
buf.append(XX_FORMAT.format(value.get(Calendar.HOUR_OF_DAY)));
buf.append(':');
// minute (mm)
buf.append(XX_FORMAT.format(value.get(Calendar.MINUTE)));
buf.append(':');
// second (ss)
buf.append(XX_FORMAT.format(value.get(Calendar.SECOND)));
buf.append('.');
// millisecond (SSS)
buf.append(XXX_FORMAT.format(value.get(Calendar.MILLISECOND)));
// time zone designator (Z or +00:00 or -00:00)
TimeZone tz = value.getTimeZone();
// time zone offset (in minutes) from UTC (including daylight saving)
int offset = tz.getOffset(value.getTimeInMillis()) / 1000 / 60;
if (offset != 0) {
int hours = Math.abs(offset / 60);
int minutes = Math.abs(offset % 60);
buf.append(offset < 0 ? '-' : '+');
buf.append(XX_FORMAT.format(hours));
buf.append(':');
buf.append(XX_FORMAT.format(minutes));
} else {
buf.append('Z');
}
return buf.toString();
}
}