Android Open Source - mobilepower-android Simple Date






From Project

Back to project page mobilepower-android.

License

The source code is released under:

Apache License

If you think the Android project mobilepower-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2012-2013 Dario Scoppelletti, <http://www.scoppelletti.it/>.
 * // w  w w . j  a va2 s .  c om
 * Licensed 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 it.scoppelletti.mobilepower.types;

import java.text.*;
import java.util.*;
import android.os.*;
import org.apache.commons.lang3.*;

/**
 * Data.
 * 
 * <P>A differenza delle classi {@code Calendar} e {@code Date} di
 * <ACRONYM TITLE="Java Development Kit">JDK</ACRONYM>, la classe
 * {@code SimpleDate} include le sole componenti (anno, mese, giorno) e le
 * istanze sono immutabili.</P>
 * 
 * @since 1.0
 */
public final class SimpleDate implements Comparable<SimpleDate>, ValueType {
       
    /**
     * Data nulla.
     * 
     * @see #isEmpty
     */
    public static final SimpleDate NIL = new SimpleDate();
    
    /**
     * Servizio di creazione delle istanze.
     */    
    public static final Parcelable.Creator<SimpleDate> CREATOR =
            new Parcelable.Creator<SimpleDate>() {

                /**
                 * Legge un&rsquo;istanza.
                 * 
                 * @param  in Flusso di lettura. 
                 * @return    Oggetto.
                 */        
                public SimpleDate createFromParcel(Parcel in) {
                    return new SimpleDate(in);
                }

                /**
                 * Crea un vettore di istanze.
                 * 
                 * @param  size Dimensione.
                 * @return      Vettore.
                 */                
                public SimpleDate[] newArray(int size) {
                    return new SimpleDate[size];
                }
            };
            
    private final int myYear;        
    private final int myMonth;   
    private final int myDay;
    
    /**
     * Costruttore.
     */
    private SimpleDate() {
        myYear = TimeTools.NA;
        myMonth = TimeTools.NA;
        myDay = TimeTools.NA;
    }
        
    /**
     * Costruttore.
     * 
     * @param year  Anno.
     * @param month Mese.
     * @param day   Giorno.
     */
    public SimpleDate(int year, int month, int day) {
        int min, max;
        Calendar cal = Calendar.getInstance();
        
        min = cal.getMinimum(Calendar.YEAR);
        max = cal.getMaximum(Calendar.YEAR);        
        if (year < min || year > max) {
            throw new IllegalArgumentException(String.format(
                    "Argument year %1$d is ouf of range [%2$d, %3$d].", year,
                    min, max));            
        }
        cal.set(Calendar.YEAR, year);
        
        min = cal.getActualMinimum(Calendar.MONTH);
        max = cal.getActualMaximum(Calendar.MONTH);
        if (month < min || month > max) {
            throw new IllegalArgumentException(String.format(
                    "Argument month %1$d is ouf of range [%2$d, %3$d].", month,
                    min, max));                    
        }
        cal.set(Calendar.MONTH, month);
        
        min = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        if (day < min || day > max) {
            throw new IllegalArgumentException(String.format(
                    "Argument day %1$d is ouf of range [%2$d, %3$d].", day, min,
                    max));                        
        }
        
        myYear = year;
        myMonth = month;
        myDay = day;
    }

    /**
     * Costruttore.
     * 
     * @param value Calendario.
     */
    private SimpleDate(Calendar value) {
        myYear = value.get(Calendar.YEAR);
        myMonth = value.get(Calendar.MONTH);
        myDay = value.get(Calendar.DAY_OF_MONTH);
    }
    
    /**
     * Costruttore.
     * 
     * @param in Flusso di lettura.
     */
    private SimpleDate(Parcel in) {
        myYear = in.readInt();
        myMonth = in.readInt();
        myDay = in.readInt();
    }
    
    /**
     * Restituisce la data corrente.
     * 
     * @return Valore.
     */
    public static SimpleDate getToday() {
        return new SimpleDate(Calendar.getInstance());
    }
    
    /**
     * Restituisce la data corrispondente ad un calendario.
     * 
     * @param  value Calendario.
     * @return       Data. Se il calendario {@code value} &egrave; {@code null},
     *               restituisce la data nulla.
     * @see          #NIL               
     */
    public static SimpleDate toSimpleDate(Calendar value) {
        if (value == null) {
            return SimpleDate.NIL;
        }
        
        return new SimpleDate(value);
    }
    
    /**
     * Restituisce la data corrispondente ad un codice giorno.
     * 
     * @param  dayCode Codice giorno.
     * @return         Data.
     * @see            #calcDayCode
     */
    public static SimpleDate fromDayCode(long dayCode) {
        int year, month, day, delta, monthDays;
        Calendar cal;
        
        if (dayCode < 0) {
            throw new IllegalArgumentException(
                    "Argument dayCode is less than 0.");
        }
        if (dayCode == 0) {
            return SimpleDate.NIL;
        }
                
        // Calcolo l'anno year al quale appartiene la data ricercata per
        // approssimazioni successive basate sul concetto di codice anno: dato
        // infatti un numero di giorni, il minimo numero di anni che
        // intercorrono in quel periodo e' il rapporto tra quel numero di giorni
        // e 366 (durata massima in giorni di un anno).
        cal = Calendar.getInstance();
        year = (int) (dayCode / 366l);        
        while (true) {
            delta = (int) (dayCode - SimpleDate.calcYearCode(year));
            if (delta < 366) {
                break;
            }         
            
            year = year + delta / 366;      
        }
        
        if (delta == 0) {
            // Definizione di codice anno
            year--;
            cal.set(Calendar.YEAR, year);
            cal.set(Calendar.MONTH, Calendar.DECEMBER);            
            day = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
            return new SimpleDate(year, Calendar.DECEMBER, day);
        }        
        
        // delta corrisponde al numero progressivo del giorno ricercato
        // nell'anno:
        // Sottraendo progressivamente la durata in giorni dei mesi, si
        // determina il numero progressivo del mese nell'anno; il residuo finale
        // corrisponde al numero progressivo del giorno nel mese.
        cal.set(Calendar.YEAR, year);
        day = 0; // avoid warning
        for (month = 0; delta > 0; month++) {
            cal.set(Calendar.MONTH, month);
            monthDays = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
            if (delta <= monthDays) {
                day = delta;
                break;   
            }
            
            delta = delta - monthDays;
        }
        
        return new SimpleDate(year, month, day);
    }
    
    /**
     * Restituisce la data rappresentata da una stringa in formato ISO 8601
     * ({@code yyyy-MM-dd}).
     * 
     * @param  s Stringa.
     * @return   Data. Se la stringa {@code s} &egrave; nulla, restituisce la
     *           data nulla.
     * @see    #NIL
     * @see    #isEmpty
     */    
    public static SimpleDate fromISOString(String s) throws ParseException {
        Date value;
        SimpleDate date;
        SimpleDateFormat fmt;
        
        if (StringUtils.isBlank(s)) {
            return SimpleDate.NIL;
        }
        
        fmt = new SimpleDateFormat("yyyy-MM-dd");
        
        value = fmt.parse(s);
        date = new SimpleDate(1900 + value.getYear(), value.getMonth(),
                value.getDate());
        return date;
    }
    
    /**
     * Restituisce l&rsquo;anno.
     * 
     * @return Valore.
     * @see    #isEmpty
     * @see    it.scoppelletti.mobilepower.types.TimeTools#NA
     */
    public int getYear() {
        return myYear;
    }
    
    /**
     * Restituisce il mese.
     * 
     * @return Valore.
     * @see    #isEmpty
     * @see    it.scoppelletti.mobilepower.types.TimeTools#NA
     */
    public int getMonth() {
        return myMonth;
    }      
    
    /**
     * Restituisce il giorno.
     * 
     * @return Valore.
     * @see    #isEmpty
     * @see    it.scoppelletti.mobilepower.types.TimeTools#NA 
     */
    public int getDay() {
        return myDay;
    }
        
    /**
     * Rappresenta l&rsquo;oggetto con una stringa.
     * 
     * <P>Questa versione del metodo {@code toString} restituisce la data in
     * formato ISO 8601 ({@code yyyy-MM-dd}).</P>
     * 
     * @return Stringa. Se la data &egrave; nulla, restituisce la stringa vuota
     *         {@code ""}.
     * @see    #NIL
     * @see    #isEmpty
     */
    @Override
    public String toString() {
        if (isEmpty()) {
            return StringUtils.EMPTY;
        }
        
        return String.format("%1$4d-%2$02d-%3$02d", myYear, myMonth + 1, myDay);
    }   
     
    public boolean isEmpty() {
        return (myDay == TimeTools.NA);
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(myYear);
        out.writeInt(myMonth);
        out.writeInt(myDay);
    }
    
    public int describeContents() {
        return 0;
    }
    
    /**
     * Converte la data in un calendario.
     * 
     * @return Valore. Se la data &egrave; nulla, restituisce {@code null}.
     * @see    #NIL
     * @see    #isEmpty
     */
    public Calendar toCalendar() {
        if (isEmpty()) {
            return null;
        }
        
        Calendar value = TimeTools.getUTCNow();
        
        value.set(Calendar.YEAR, myYear);
        value.set(Calendar.MONTH, myMonth);
        value.set(Calendar.DAY_OF_MONTH, myDay);
        value.set(Calendar.HOUR_OF_DAY, 0);
        value.set(Calendar.MINUTE, 0);
        value.set(Calendar.SECOND, 0);
        value.set(Calendar.MILLISECOND, 0);
        
        return value;
    }
    
    /**
     * Verifica l&rsquo;uguaglianza con un altro oggetto.
     * 
     * @param  obj Oggetto di confronto.
     * @return     Esito della verifica. 
     */
    @Override
    public boolean equals(Object obj) {
        SimpleDate op;
        
        if (!(obj instanceof SimpleDate)) {
            return false;
        }
        
        op = (SimpleDate) obj;
        
        if (myYear != op.getYear() || myMonth != op.getMonth() ||
                myDay != op.getDay()) {
            return false;
        }
        
        return true;
    }
    
    /**
     * Calcola il codice hash dell&rsquo;oggetto.
     * 
     * @return Valore.
     */
    @Override
    public int hashCode() {
        int value = 17;
        
        value = 37 * value + myYear;
        value = 37 * value + myMonth;
        value = 37 * value + myDay;
        
        return value;
    }

    /**
     * Confronto con un altro oggetto.
     * 
     * @param  obj Oggetto di confronto.
     * @return     Risultato del confronto.
     */
    public int compareTo(SimpleDate obj) {
        if (obj == null) {
            throw new NullPointerException("Argument obj is null.");
        }        

        if (isEmpty() && obj.isEmpty()) {
            return 0;
        } else if (isEmpty()) {
            return -1;
        } else if (obj.isEmpty()) {
            return 1;
        }
        
        if (myYear < obj.getYear()) {
            return -1;
        }
        if (myYear > obj.getYear()) {
            return 1;
        }
        
        if (myMonth < obj.getMonth()) {
            return -1;
        }
        if (myMonth > obj.getMonth()) {
            return 1;
        }
        
        if (myDay < obj.getDay()) {
            return -1;
        }
        if (myDay > obj.getDay()) {
            return 1;
        }
        
        return 0;
    }               
    
    /**
     * Calcola il codice giorno della data.
     * 
     * <P>Il <DFN>codice giorno</DFN> corrisponde al numero di giorni che
     * intercorrono da un ipotetico anno 0 alla data presa in esame.</P>
     * 
     * @return Valore.
     */
    public long calcDayCode() {
        int month;
        long dayCode;
        Calendar cal;
        
        if (isEmpty()) {
            return 0;
        }
        
        cal = Calendar.getInstance();
        dayCode = SimpleDate.calcYearCode(myYear);
        cal.set(Calendar.YEAR, myYear);
        for (month = 0; month < myMonth; month++) {
            cal.set(Calendar.MONTH, month);
            dayCode += cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        
        return dayCode + myDay;
    }
    
    /**
     * Calcola il codice anno di un anno.
     * 
     * <P>Il <DFN>codice anno</DFN> di un anno coincide con il codice giorno del
     * 31 dicembre dell&rsquo;anno precedente.<BR>
     * L&rsquo;anno 0 &egrave;, per definizione, bisestile e il suo codice anno
     * &egrave;, per convenzione, 0.</P>
     * 
     * @param  year Anno.
     * @return      Codice anno.
     */
    private static long calcYearCode(long year) {
        long year4, year100, year400, year365, year366;
        
        // Somma ponderata del numero di anni bisestili e del numero di anni non
        // bisestili che intercorrono tra l'anno 0 e lanno considerato.    
        year4 = (year - (year % 4)) / 4;
        year100 = (year - year % 100) / 100;
        year400 = (year - year % 400) / 400;
        year365 = year - year4 + year100 - year400;
        year366 = year - year365;
        
        return year365 * 365 + year366 * 366;                            
    }
}




Java Source Code List

it.scoppelletti.mobilepower.app.AboutActivity.java
it.scoppelletti.mobilepower.app.AbstractActivity.java
it.scoppelletti.mobilepower.app.AbstractDialogFragment.java
it.scoppelletti.mobilepower.app.AbstractFragment.java
it.scoppelletti.mobilepower.app.AbstractPreferenceActivity.java
it.scoppelletti.mobilepower.app.ActionBarCompat.java
it.scoppelletti.mobilepower.app.ActionBarSupport.java
it.scoppelletti.mobilepower.app.ActivitySupport.java
it.scoppelletti.mobilepower.app.AppUtils.java
it.scoppelletti.mobilepower.app.CommonMenuFragment.java
it.scoppelletti.mobilepower.app.ConfirmDialogFragment.java
it.scoppelletti.mobilepower.app.DatePickerDialogFragment.java
it.scoppelletti.mobilepower.app.FragmentLayoutController.java
it.scoppelletti.mobilepower.app.FragmentSupport.java
it.scoppelletti.mobilepower.app.HelpActivity.java
it.scoppelletti.mobilepower.app.HelpDialogFragment.java
it.scoppelletti.mobilepower.app.MarketTagHandler.java
it.scoppelletti.mobilepower.app.ProgressDialogFragment.java
it.scoppelletti.mobilepower.app.ReleaseNoteActivity.java
it.scoppelletti.mobilepower.app.bluetooth.ActivityBTManager.java
it.scoppelletti.mobilepower.app.data.DatabaseConnectionManager.java
it.scoppelletti.mobilepower.app.data.DatabaseUpgradeTask.java
it.scoppelletti.mobilepower.app.security.ActivityLicenseClient.java
it.scoppelletti.mobilepower.app.security.LicenseBuyDialogFragment.java
it.scoppelletti.mobilepower.app.security.LicenseDemoDialogFragment.java
it.scoppelletti.mobilepower.app.security.LicenseRetryDialogFragment.java
it.scoppelletti.mobilepower.bluetooth.BTManager.java
it.scoppelletti.mobilepower.bluetooth.BTTask.java
it.scoppelletti.mobilepower.bluetooth.OnBTListener.java
it.scoppelletti.mobilepower.data.DatabaseUpgrader.java
it.scoppelletti.mobilepower.data.OnDatabaseConnectionListener.java
it.scoppelletti.mobilepower.graphics.GraphicTools.java
it.scoppelletti.mobilepower.graphics.SizeF.java
it.scoppelletti.mobilepower.io.IOTools.java
it.scoppelletti.mobilepower.media.DefaultOnScanCompletedListener.java
it.scoppelletti.mobilepower.os.AbstractAsyncTask.java
it.scoppelletti.mobilepower.os.AsyncTaskController.java
it.scoppelletti.mobilepower.os.AsyncTaskHost.java
it.scoppelletti.mobilepower.os.BuildCompat.java
it.scoppelletti.mobilepower.preference.AbstractDialogPreference.java
it.scoppelletti.mobilepower.preference.BTDevicePreference.java
it.scoppelletti.mobilepower.preference.ColorPreference.java
it.scoppelletti.mobilepower.preference.EditTextPreferenceEx.java
it.scoppelletti.mobilepower.preference.IntegerSpinnerPreference.java
it.scoppelletti.mobilepower.preference.PreferenceSavedState.java
it.scoppelletti.mobilepower.preference.SeekBarPreference.java
it.scoppelletti.mobilepower.provider.ContactsContractCompat.java
it.scoppelletti.mobilepower.reflect.MemberCache.java
it.scoppelletti.mobilepower.security.LicenseClient.java
it.scoppelletti.mobilepower.types.SimpleDate.java
it.scoppelletti.mobilepower.types.StringTools.java
it.scoppelletti.mobilepower.types.TimeTools.java
it.scoppelletti.mobilepower.types.ValueTools.java
it.scoppelletti.mobilepower.types.ValueType.java
it.scoppelletti.mobilepower.view.ViewSavedState.java
it.scoppelletti.mobilepower.widget.CompoundControl.java
it.scoppelletti.mobilepower.widget.DateControl.java
it.scoppelletti.mobilepower.widget.ImageButtonCompat.java
it.scoppelletti.mobilepower.widget.IntegerSpinner.java
it.scoppelletti.mobilepower.widget.IntegerTextWatcher.java
it.scoppelletti.mobilepower.widget.WidgetTools.java