web-dev-qa-db-fra.com

Réglez l'heure à 00:00:00

J'ai un problème de réinitialisation des heures en Java. Pour une date donnée, je souhaite régler les heures sur 00:00:00.

Ceci est mon code: 

/**
     * Resets milliseconds, seconds, minutes and hours from the provided date
     *
     * @param date
     * @return
     */
    public static Date trim(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR, 0);

        return calendar.getTime();
    }

Le problème est que parfois, le temps est 12:00:00 et parfois, il s'agit de 00:00:00 et lorsque je demande à la base de données une entité enregistrée sur 07.02.2013 00:00:00 et que le temps réel de l'entité, stocké, est 12:00:00, la requête échoue. 

Je sais que 12:00:00 == 00:00:00

J'utilise AppEngine. Est-ce un bug d'appariement, un problème ou un autre problème? Ou cela dépend-il de quelque chose d'autre?

99
Adelin

Utilisez une autre constante au lieu de Calendar.HOUR, utilisez Calendar.HOUR_OF_DAY .

calendar.set(Calendar.HOUR_OF_DAY, 0);

Calendar.HOUR utilise 0-11 (pour une utilisation avec AM/PM), et Calendar.HOUR_OF_DAY utilise 0-23.

Pour citer les Javadocs:

public statique final int HEURE

Numéro de champ pour get et set indiquant l'heure du matin ou de l'après-midi. HEURE est utilisé pour les 12 heures horloge (0 - 11). Midi et minuit sont représentés par 0 et non par 12 . Par exemple, à 10: 04: 15,250 PM l’HEURE est 10.

et

finale publique statique int HOUR_OF_DAY

Numéro de champ pour get et set indiquant l'heure du jour. HOUR_OF_DAY est utilisé pour les 24 heures l'horloge. Par exemple, à 10: 04: 15,250 PM HOUR_OF_DAY a 22 ans.

Tests ("maintenant" est actuellement environ 23h53 le 23 juillet 2013, heure avancée du Pacifique):

public class Main
{
   static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args)
    {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.HOUR, 0);
        now.set(Calendar.MINUTE, 0);
        now.set(Calendar.SECOND, 0);
        System.out.println(sdf.format(now.getTime()));
        now.set(Calendar.HOUR_OF_DAY, 0);
        System.out.println(sdf.format(now.getTime()));
    }
}

Sortie:

$ javac Main.Java
$ Java Main
2013-07-23 12:00:00
2013-07-23 00:00:00
166
rgettman

Java.time

Utilisation de Java.time framework intégré à Java 8 et versions ultérieures. Voir Tutoriel .

import Java.time.LocalTime;
import Java.time.LocalDateTime;

LocalDateTime now = LocalDateTime.now(); # 2015-11-19T19:42:19.224
# start of a day
now.with(LocalTime.MIN); # 2015-11-19T00:00
now.with(LocalTime.MIDNIGHT); # 2015-11-19T00:00

Si vous n'avez pas besoin de l'heure, envisagez d'utiliser LocalDate class.

LocalDate.now(); # 2015-11-19
18
Przemek

Voici quelques fonctions d’utilité que j’utilise précisément pour cela.

/**
 * sets all the time related fields to ZERO!
 *
 * @param date
 *
 * @return Date with hours, minutes, seconds and ms set to ZERO!
 */
public static Date zeroTime( final Date date )
{
    return DateTimeUtil.setTime( date, 0, 0, 0, 0 );
}

/**
 * Set the time of the given Date
 *
 * @param date
 * @param hourOfDay
 * @param minute
 * @param second
 * @param ms
 *
 * @return new instance of Java.util.Date with the time set
 */
public static Date setTime( final Date date, final int hourOfDay, final int minute, final int second, final int ms )
{
    final GregorianCalendar gc = new GregorianCalendar();
    gc.setTime( date );
    gc.set( Calendar.HOUR_OF_DAY, hourOfDay );
    gc.set( Calendar.MINUTE, minute );
    gc.set( Calendar.SECOND, second );
    gc.set( Calendar.MILLISECOND, ms );
    return gc.getTime();
}
11
user177800

Vous feriez mieux de définir principalement le fuseau horaire sur le composant DateFormat comme ceci:

DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));

Ensuite, vous pouvez obtenir l'heure "00:00:00" en passant 0 millisecondes au formateur:

String time = dateFormat.format(0);

ou vous pouvez créer un objet Date:

Date date = new Date(0); // also pass milliseconds
String time = dateFormat.foramt(date);

ou vous pouvez avoir plus de possibilités en utilisant le composant Calendrier mais vous devez également définir le fuseau horaire GMT comme instance de calendrier

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US);
calendar.set(Calendar.HOUR_OF_DAY, 5);
calendar.set(Calendar.MINUTE, 37);
calendar.set(Calendar.SECOND, 27);

dateFormat.format(calendar.getTime());
3

Une autre façon Java 8:

LocalDateTime localDateTime = LocalDateTime.now().truncatedTo(ChronoUnit.HOURS);

Mais il est beaucoup plus utile d’éditer la date existante.

2
thorinkor

tl; dr

myJavaUtilDate                                 // The terrible `Java.util.Date` class is now legacy. Use *Java.time* instead.
.toInstant()                                   // Convert this moment in UTC from the legacy class `Date` to the modern class `Instant`.
.atZone( ZoneId.of( "Africa/Tunis" ) )         // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
.toLocalDate()                                 // Extract the date-only portion.
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) )   // Determine the first moment of that date in that zone. The day does *not* always start at 00:00:00.

Java.time

Vous utilisez d'anciennes classes de date-heure terribles qui ont été supplantées il y a des années par les classes modernes Java.time définies dans JSR 310.

DateInstant

Un Java.util.Date représente un moment en UTC. Son remplacement est Instant. Appelez les nouvelles méthodes de conversion ajoutées aux anciennes classes.

Instant instant = myJavaUtilDate.toInstant() ;

Fuseau horaire

Spécifiez le fuseau horaire dans lequel vous souhaitez donner un sens à votre nouvelle heure.

Spécifiez un nom de fuseau horaire correct au format Continent/Region, tel que America/Montreal, Africa/Casablanca ou Pacific/Auckland. N'utilisez jamais les abréviations de 2 à 4 lettres telles que EST ou IST, car elles sont et non , sans fuseaux horaires normaux. et même pas unique (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;

ZonedDateTime

Appliquez le ZoneId au Instant pour obtenir un ZonedDateTime. Même moment, même point sur la ligne de temps, mais heure différente.

ZonedDateTime zdt = instant.atZone( z ) ;

Changement d'heure

Vous avez demandé de changer l'heure. Appliquez un LocalTime pour modifier toutes les parties de l'heure: heure, minute, seconde, fraction de seconde. Un nouveau ZonedDateTime est instancié, avec des valeurs basées sur l'original. Les classes Java.time utilisent ce modèle objets immuables pour fournir sécurité du thread .

LocalTime lt = LocalTime.of( 15 , 30 ) ;  // 3:30 PM.
ZonedDateTime zdtAtThreeThirty = zdt.with( lt ) ; 

Premier moment de la journée

Mais vous avez spécifiquement demandé 00:00. Donc, apparemment, vous voulez le premier moment de la journée. Attention, certains jours dans certaines zones ne commencent pas à 00:00:00. Ils peuvent commencer à une autre heure, telle que 01:00:00, en raison d'anomalies telles que l'heure d'été (DST).

Laissons Java.time déterminer le premier moment. Extrayez la partie date uniquement. Puis passez le fuseau horaire pour obtenir le premier moment.

LocalDate ld = zdt.toLocalDate() ;
ZonedDateTime zdtFirstMomentOfDay = ld.atStartOfDay( z ) ;

Ajuster à UTC

Si vous devez revenir en UTC, extrayez un Instant.

Instant instant = zdtFirstMomentOfDay.toInstant() ;

InstantDate

Si vous avez besoin d'un Java.util.Date pour interagir avec un ancien code non encore mis à jour, convertissez Java.time .

Java.util.Date d = Java.util.Date.from( instant ) ;
1
Basil Bourque

Nous pouvons définir Java.util.Date time part sur 00:00:00 en utilisant la classe LocalDate de Java 8/api Joda-datetime :

Date datewithTime = new Date() ; // ex: Sat Apr 21 01:30:44 IST 2018
LocalDate localDate = LocalDate.fromDateFields(datewithTime);
Date datewithoutTime = localDate.toDate(); // Sat Apr 21 00:00:00 IST 2018
1
Atishay

Cela pourrait être plus facile (en Java 8) 

LocalTime.ofNanoOfDay(0)
1
meszias

Comme Java8 ajoute de nouvelles fonctions Date, nous pouvons le faire facilement.


    // If you have instant, then:
    Instant instant1 = Instant.now();
    Instant day1 = instant1.truncatedTo(ChronoUnit.DAYS);
    System.out.println(day1); //2019-01-14T00:00:00Z

    // If you have Date, then:
    Date date = new Date();
    Instant instant2 = date.toInstant();
    Instant day2 = instant2.truncatedTo(ChronoUnit.DAYS);
    System.out.println(day2); //2019-01-14T00:00:00Z

    // If you have LocalDateTime, then:
    LocalDateTime dateTime = LocalDateTime.now();
    LocalDateTime day3 = dateTime.truncatedTo(ChronoUnit.DAYS);
    System.out.println(day3); //2019-01-14T00:00
    String format = day3.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    System.out.println(format);//2019-01-14T00:00:00


0
Chao Jiang

Si vous avez besoin du format 00:00:00 en chaîne, vous devez utiliser SimpleDateFormat comme ci-dessous. Utiliser "H" à la place de "h".

Date today = new Date();
SimpleDateFormat ft = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); 
//not SimpleDateFormat("dd-MM-yyyy hh:mm:ss")
Calendar calendarDM = Calendar.getInstance();
calendarDM.setTime(today);
calendarDM.set(Calendar.HOUR, 0);
calendarDM.set(Calendar.MINUTE, 0);
calendarDM.set(Calendar.SECOND, 0);
System.out.println("Current Date: " + ft.format(calendarDM.getTime()));

//Result is: Current Date: 29-10-2018 00:00:00
0
Ngô Ngọc Quang

Vous pouvez le faire avec les éléments suivants:

Calendar cal = Calendar.getInstance();
cal.set(year, month, dayOfMonth, 0, 0, 0);
Date date = cal.getTime();

Une autre façon de faire serait d'utiliser un DateFormat sans secondes:

public static Date trim(Date date) {
    DateFormat format = new SimpleDateFormat("dd.MM.yyyy");
    Date trimmed = null;
    try {
        trimmed = format.parse(format.format(date));
    } catch (ParseException e) {} // will never happen
    return trimmed;
}
0
MMKopp