web-dev-qa-db-fra.com

Réinitialisation de la partie temporelle d'un horodatage dans Java

En Java, étant donné un horodatage, comment réinitialiser la partie temporelle seule à 00:00:00 pour que l'horodatage représente le minuit de ce jour particulier?

En T-SQL, cette requête fera pour obtenir le même résultat, mais je ne sais pas comment faire cela en Java.

SELECT CAST( FLOOR( CAST(GETDATE() AS FLOAT ) ) AS DATETIME) AS 'DateTimeAtMidnight';

39
Vijay Dev

Vous pouvez aller Date-> Calendrier-> set-> Date:

Date date = new Date();                      // timestamp now
Calendar cal = Calendar.getInstance();       // get calendar instance
cal.setTime(date);                           // set cal to date
cal.set(Calendar.HOUR_OF_DAY, 0);            // set hour to midnight
cal.set(Calendar.MINUTE, 0);                 // set minute in hour
cal.set(Calendar.SECOND, 0);                 // set second in minute
cal.set(Calendar.MILLISECOND, 0);            // set millis in second
Date zeroedDate = cal.getTime();             // actually computes the new Date

J'adore Java dates.

Notez que si vous utilisez de vrais Java.sql.Timestamps, ils ont un champ nanos supplémentaire. Le calendrier, bien sûr, ne connaît rien aux nanos, donc l'ignorera aveuglément et le supprimera efficacement lors de la création de la date zéro à la fin, que vous pourrez ensuite utiliser pour créer un nouvel objet Timetamp.

Je dois également noter que Calendar n'est pas compatible avec les threads, alors ne pensez pas que vous pouvez créer une instance statique unique appelée à partir de plusieurs threads pour éviter de créer de nouvelles instances de Calendar.

76
Alex Miller

Si vous utilisez le langage commun, vous pouvez appeler DateUtils.truncate. Voici la documentation javadoc .

Cela fait la même chose que @Alex Miller a dit de faire.

19
ScArcher2

En supposant que votre "horodatage" est un Java.util.Date, qui est représenté par le nombre de millisecondes depuis le début de l'époque (1er janvier 1970), vous pouvez effectuer l'arithmétique suivante:

public static Date stripTimePortion(Date timestamp) {
    long msInDay = 1000 * 60 * 60 * 24; // Number of milliseconds in a day
    long msPortion = timestamp.getTime() % msInDay;
    return new Date(timestamp.getTime() - msPortion);
}
7
thoroughly

Faites ceci

import org.Apache.commons.lang.time.DateUtils;

Date myDate = new Date();
System.out.println(myDate);        
System.out.println(DateUtils.truncate(myDate, Calendar.DATE));

et la sortie est

Mer.19 mars 14:16:47 PDT 2014
Mer. Mars 19 00:00:00 PDT 2014

4
Ziya

Je préfère cette solution:

GregorianCalendar now = new GregorianCalendar();
GregorianCalendar calendar = new GregorianCalendar(
              now.get(GregorianCalendar.YEAR), now.get(GregorianCalendar.MONTH), 
              now.get(GregorianCalendar.DAY_OF_MONTH));
4
Torben Kohlmeier

Étant donné que je ne fais pas beaucoup de manipulation DateTime, ce n'est peut-être pas la meilleure façon de le faire. Je créerais un calendrier et utiliserais la date comme source. Réglez ensuite les heures, les minutes et les secondes sur 0 et reconvertissez-les en date. Ce serait bien de voir une meilleure façon, cependant.

1
Jan Gressmann

Trouvez ci-dessous une solution qui utilise Joda Time et prend en charge les fuseaux horaires. Ainsi, vous obtiendrez la date et l'heure actuelles (dans currentDate et currentTime) ou une date et l'heure que vous renseignerez (dans informedDate et informedTime) dans le fuseau horaire actuellement configuré dans la machine virtuelle Java.

Le code ci-dessous indique également si la date/heure indiquée est future (variable schedulable).

Veuillez noter que Joda Time ne prend pas en charge les secondes intercalaires . Ainsi, vous pouvez être à environ 26 ou 27 secondes de la vraie valeur. Cela ne sera probablement résolu que dans les 50 prochaines années, lorsque l'erreur accumulée sera plus proche de 1 minute et que les gens commenceront à s'en soucier.

Voir aussi: https://en.wikipedia.org/wiki/Leap_second

/**
 * This class splits the current date/time (now!) and an informed date/time into their components:
 * <lu>
 *     <li>schedulable: if the informed date/time is in the present (now!) or in future.</li>
 *     <li>informedDate: the date (only) part of the informed date/time</li>
 *     <li>informedTime: the time (only) part of the informed date/time</li>
 *     <li>currentDate: the date (only) part of the current date/time (now!)</li>
 *     <li>currentTime: the time (only) part of the current date/time (now!)</li>
 * </lu>
 */
public class ScheduleDateTime {
    public final boolean schedulable;
    public final long millis;
    public final Java.util.Date informedDate;
    public final Java.util.Date informedTime;
    public final Java.util.Date currentDate;
    public final Java.util.Date currentTime;

    public ScheduleDateTime(long millis) {
        final long now = System.currentTimeMillis();
        this.schedulable = (millis > -1L) && (millis >= now);

        final TimeZoneUtils tz = new TimeZoneUtils();

        final Java.util.Date          dmillis   = new Java.util.Date( (millis > -1L) ? millis : now );
        final Java.time.ZonedDateTime zdtmillis = Java.time.ZonedDateTime.ofInstant(dmillis.toInstant(), Java.time.ZoneId.systemDefault());
        final Java.util.Date          zdmillis  = Java.util.Date.from(tz.tzdate(zdtmillis));
        final Java.util.Date          ztmillis  = new Java.util.Date(tz.tztime(zdtmillis));

        final Java.util.Date          dnow   = new Java.util.Date(now);
        final Java.time.ZonedDateTime zdtnow = Java.time.ZonedDateTime.ofInstant(dnow.toInstant(), Java.time.ZoneId.systemDefault());
        final Java.util.Date          zdnow  = Java.util.Date.from(tz.tzdate(zdtnow));
        final Java.util.Date          ztnow  = new Java.util.Date(tz.tztime(zdtnow));

        this.millis       = millis;
        this.informedDate = zdmillis;
        this.informedTime = ztmillis;
        this.currentDate  = zdnow;
        this.currentTime  = ztnow;
    }
}



public class TimeZoneUtils {

    public Java.time.Instant tzdate() {
        final Java.time.ZonedDateTime zdtime = Java.time.ZonedDateTime.now();
        return tzdate(zdtime);
    }
    public Java.time.Instant tzdate(Java.time.ZonedDateTime zdtime) {
        final Java.time.ZonedDateTime zddate = zdtime.truncatedTo(Java.time.temporal.ChronoUnit.DAYS);
        final Java.time.Instant instant = zddate.toInstant();
        return instant;
    }

    public long tztime() {
        final Java.time.ZonedDateTime zdtime = Java.time.ZonedDateTime.now();
        return tztime(zdtime);
     }
    public long tztime(Java.time.ZonedDateTime zdtime) {
        final Java.time.ZonedDateTime zddate = zdtime.truncatedTo(Java.time.temporal.ChronoUnit.DAYS);
        final long millis = zddate.until(zdtime, Java.time.temporal.ChronoUnit.MILLIS);
        return millis;
    }
}
0
Richard Gomes

L'utilisation de Calendar.set () serait certes une solution "par le livre", mais vous pourriez également utiliser Java.sql.Date:

Java.util.Date originalDate = new Java.util.Date();
Java.sql.Date wantedDate = new Java.sql.Date(originalDate.getTime());

Cela ferait exactement ce que vous voulez puisque:

Pour se conformer à la définition de SQL DATE, les valeurs en millisecondes encapsulées par une instance Java.sql.Date doivent être "normalisées" en définissant les heures, minutes, secondes et millisecondes à zéro dans le fuseau horaire particulier auquel l'instance est associée .

Étant donné que Java.sql.Date étend Java.util.Date, vous pouvez l'utiliser librement en tant que tel. Sachez cependant que WantDate.getTime () récupérera l'horodatage d'origine - c'est pourquoi vous ne voulez pas créer un autre Java.util.Date à partir de Java.sql.Date!

0
Domchi

J'essaie simplement de mettre une réponse pour Java-8, bien que les réponses utilisant Calendar soient également valides, mais beaucoup de gens n'utilisent plus cette classe.

Reportez-vous SO réponses ceci & ceci pour comprendre les conversions entre Java.time.ZonedDateTime & Java.sql.Timestamp

alors vous pouvez simplement tronquer ZonedDateTime les jours et reconvertir en Timestamp

Timestamp.valueOf(ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS).toLocalDateTime())
0
Sabir Khan

Voici une fonction simple avec un exemple principal:

import Java.util.Calendar;
import Java.util.Date;
public class Util {
/**
 * Returns an imprecise date/timestamp. 
 * @param date
 * @return the timestamp with zeroized seconds/milliseconds
 */
public static Date getImpreciseDate(Date date) {
   Calendar cal = Calendar.getInstance(); // get calendar instance
   cal.setTime(date);// set cal to date
   cal.set(Calendar.SECOND, 0); // zeroize seconds 
   cal.set(Calendar.MILLISECOND, 0);   // zeroize milliseconds
   return cal.getTime();
}

public static void main(String[] args){
   Date now = new Date();
   now.setTime(System.currentTimeMillis()); // set time to now
   System.out.println("Precise date:  " + Util.getImpreciseDate(now));
   System.out.println("Imprecise date:  " + Util.getImpreciseDate(now));
}
}
0
MAbraham1