Réinitialisation de la partie heure d'un horodatage en Java
Question
En Java, à partir d’un horodatage, comment réinitialiser la partie heure à 00:00:00 afin que l’horodatage représente le minuit de ce jour particulier?
En T-SQL, cette requête fera de même, mais je ne sais pas comment faire cela en Java.
SELECT CAST (FLOOR (CAST (GETDATE () AS FLOAT)) AS DATETIME) AS 'DateTimeAtMidnight';
La solution
Vous pouvez aller Date- > Calendrier- > définir- > 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'aime les rendez-vous Java.
Notez que si vous utilisez des fichiers java.sql.Timestamps réels, ils ont un champ nanos supplémentaire. Bien sûr, Calendar ne connaît rien à nanos, il sera ignoré aveuglément et supprimé de manière efficace lors de la création de zeroedDate à la fin, que vous pourrez ensuite utiliser pour créer un nouvel objet Timetamp.
Je dois également noter que Calendar n'est pas sécurisé pour les threads. Ne pensez donc pas qu'une seule instance statique fixe appelle à partir de plusieurs threads afin d'éviter de créer de nouvelles instances de Calendar.
Autres conseils
Si vous utilisez commons lang, vous pouvez appeler DateUtils.truncate
. Voici le documentation javadoc .
C’est ce que @ Alex Miller a dit de faire.
En supposant que votre " horodatage " est un java.util.Date, représenté par le nombre de millisecondes écoulées 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);
}
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));
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 HAP 2014
Comme je ne fais pas beaucoup de manipulations 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. Définissez ensuite les heures, les minutes et les secondes sur 0 et reconvertissez-les en Date. Ce serait bien de voir un meilleur moyen, cependant.
Utiliser Calendar.set () serait certainement "du livre". mais vous pouvez aussi 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 depuis:
Pour être conforme à la définition de SQL DATE, les valeurs millisecondes entourées par une instance java.sql.Date doivent être "normalisées" en définissant les heures, les minutes, les secondes et les millisecondes à zéro dans le fuseau horaire l'instance est associée.
Comme java.sql.Date étend java.util.Date, vous pouvez l’utiliser librement en tant que tel. Sachez que wantedDate.getTime () récupérera l’horodatage original, c’est pourquoi vous ne souhaitez pas créer un autre fichier java.util.Date à partir de java.sql.Date!
Recherchez 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 une heure que vous indiquez (dans averti
et averti
) dans le fuseau horaire actuellement configuré dans la machine virtuelle.
Le code ci-dessous indique également si la date / heure informée est future (variable programmable
).
Notez que Joda Time ne prend pas en charge les secondes intercalaires . Ainsi, vous pouvez être environ 26 ou 27 secondes sur la valeur réelle. 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 vont commencer à 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;
}
}
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));
}
}