Saati 00:00:00 olarak ayarlayın


121

Java'da saatleri sıfırlarken sorun yaşıyorum. Belirli bir tarih için saatleri 00:00:00 olarak ayarlamak istiyorum.

Bu benim kodum:

/**
     * 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();
    }

Sorun, zamanın 12:00:00bazen ve bazen de olmasıdır 00:00:00ve veritabanını kaydedilmiş bir varlık için sorguladığımda 07.02.2013 00:00:00ve depolanan gerçek varlık zamanı, 12:00:00sorgunun başarısız olmasıdır.

Bunu biliyorum 12:00:00 == 00:00:00!

AppEngine kullanıyorum. Bu bir uygulama motoru hatası mı, sorunu mu yoksa başka bir sorun mu? Yoksa başka bir şeye mi bağlı?


Bunun farklı yerel ayarlarla bir ilgisi olabilir mi yoksa bu her zaman aynı bilgisayardan mı oluyor?
LostBoy

appengine üzerinde konuşlandırdığımda oluyor.
Adelin

Zamanı
kısaltmak

Bilginize, gibi zahmetli eski tarih-saat sınıfları java.util.Date, java.util.Calendarve java.text.SimpleDateFormatşimdi mirası supplanted, java.time Java 8 ve Java 9. Bkz yerleşik sınıflara Oracle tarafından Öğreticisi .
Basil Bourque

1
Amacım için kullandım calendar.set(Calendar.HOUR_OF_DAY, 0);, iyi çalışıyor.
hariprasad

Yanıtlar:


209

Kullanmak yerine başka bir sabit Calendar.HOURkullanın Calendar.HOUR_OF_DAY.

calendar.set(Calendar.HOUR_OF_DAY, 0);

Calendar.HOUR0-11 kullanır (AM / PM ile kullanım için) ve Calendar.HOUR_OF_DAY0-23 kullanır.

Javadocs'tan alıntı yapmak için:

public static final int HOUR

Sabah veya öğleden sonra saatini gösteren almak ve ayarlamak için alan numarası. HOUR, 12 saatlik zaman biçimi için kullanılır (0 - 11). Öğlen ve gece yarısı 12 ile değil, 0 ile temsil edilir. Örneğin, 10: 04: 15.250'de SAAT 10'dur.

ve

genel statik final int HOUR_OF_DAY

Günün saatini gösteren get ve set için alan numarası. HOUR_OF_DAY, 24 saatlik zaman biçimi için kullanılır. Örneğin, 10: 04: 15.250 PM'de HOUR_OF_DAY 22'dir.

Test ("şimdi" şu anda 23 Temmuz 2013 Pasifik Yaz Saati, c. 14:55):

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()));
    }
}

Çıktı:

$ javac Main.java
$ java Main
2013-07-23 12:00:00
2013-07-23 00:00:00

3
@JarrodRoberson Ancak kullanmak Calendar.HOUR, Öğleden Sonra Öğleden Sonra'yı ayarlamaz, öğlen 12:00 olarak bırakır.
rgettman

Lütfen bir LocalDate'i saat, dakika ve saniye ile oluşturmama yardım eder misiniz? Bir seçeneğin DateTime'ı takip etmek olduğunu biliyorum.
Woody

11
HOUR ve HOUR_OF_DAY alanını oluşturan kişi kırbaçlanmalı ve tayın almalıydı.
AndroidDev

1
@AndroidDev, am / pm icat edenler aynı şeyi hak ediyor ... Bu aynı zamanda metrik olmayan standartlar için de geçerli
Dediqated

1
Bilginize, gibi zahmetli eski tarih-saat sınıfları java.util.Date, java.util.Calendarve java.text.SimpleDateFormatşimdi mirası supplanted, java.time Java 8 ve Java 9. Bkz yerleşik sınıflara Oracle tarafından Öğreticisi .
Basil Bourque

29

java.time

java.timeJava 8 ve sonraki sürümlerde yerleşik çerçeveyi kullanma . Öğreticiye bakın .

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

Günün saatine (saat, dakika, saniye vb. Bölümler) ihtiyacınız yoksa LocalDatesınıfı kullanmayı düşünün .

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

Bu soru ilk sorulduğundan beri Java 1.8 piyasaya sürüldüğünden beri kabul edilen yeni cevap bu olmalıdır.
matt forsythe

LocalDateTimetam olarak bunun için kullanılacak yanlış sınıftır . Herhangi bir zaman dilimi kavramı veya UTC'den uzaklıktan yoksun olduğu için bir anı temsil edemez. Telefon etmek LocalDateTime.nowneredeyse hiç mantıklı değil. ZonedDateTimeBunun yerine kullanın . Aksi takdirde, önemli saat dilimi sorunlarını görmezden gelirsiniz. Bir kere, bazı bölgelerde bazı tarihler do not 00.00'da başlayacak!
Basil Bourque

12

İşte sadece bunu yapmak için kullandığım birkaç yardımcı fonksiyon.

/**
 * 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();
}

6

Bir JAVA 8 yolu daha:

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

Ancak zaten var olan tarihi düzenlemek çok daha kullanışlıdır.


1
LocalDateTimeHerhangi bir zaman dilimi kavramı veya UTC'den uzaklıktan yoksun olduğu için bir anı temsil edemez. Telefon etmek LocalDateTime.nowneredeyse hiç mantıklı değil. Bunun ZonedDateTimeyerine kullanmalısın.
Basil Bourque

3

Öncelikle DateFormat bileşenine saat dilimini şu şekilde ayarlamanız daha iyi olur:

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

Ardından, biçimlendiriciye 0 milisaniyeyi geçerek "00:00:00" süresi elde edebilirsiniz:

String time = dateFormat.format(0);

veya Date nesnesi oluşturabilirsiniz:

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

veya Takvim bileşenini kullanarak daha fazla olanağa sahip olabilirsiniz, ancak saat dilimini takvim örneği için GMT olarak ayarlamalısınız:

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());

2

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

Yıllar önce JSR 310'da tanımlanan modern java.time sınıfları tarafından değiştirilen korkunç eski tarih-saat sınıflarını kullanıyorsunuz .

DateInstant

A java.util.Date, UTC'de bir anı temsil eder. Onun yerini alır Instant. Eski sınıflara eklenen yeni dönüştürme yöntemlerini çağırın.

Instant instant = myJavaUtilDate.toInstant() ;

Saat dilimi

Yeni günün saatinin anlamlı olmasını istediğiniz saat dilimini belirtin.

Bir belirtme uygun bir zaman dilimi adı biçiminde Continent/Regiongibi America/Montreal, Africa/Casablancaya da Pacific/Auckland. Hiçbir zaman gibi 2-4 harfli bir kısaltma kullanın ESTveya ISToldukları gibi değil , gerçek zaman dilimleri, değil standardize ve hatta benzersiz değil (!).

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

ZonedDateTime

Uygula ZoneIdiçin Instantbir olsun ZonedDateTime. Aynı an, zaman çizelgesinde aynı nokta, ancak farklı duvar saati zamanı.

ZonedDateTime zdt = instant.atZone( z ) ;

Günün saatini değiştirme

Günün saatini değiştirmek istedin. LocalTimeGünün tüm zaman bölümlerini değiştirmek için a uygulayın : saat, dakika, saniye, kesirli saniye. ZonedDateTimeOrijinali temel alan değerlerle yeni bir örnek oluşturulur . Java.time sınıfları bu kullanımı Değişken olmayan objeler sağlamak için model iplik güvenlik .

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

Günün ilk anı

Ama özellikle 00: 00'ı istedin. Görünüşe göre günün ilk anını istiyorsun. Dikkat: Bazı bölgelerdeki bazı günler 00: 00: 00'da başlamaz. Yaz Saati Uygulaması (DST) gibi anormallikler nedeniyle 01:00:00 gibi başka bir saatte başlayabilirler.

Bırakın java.time ilk anı belirlesin . Yalnızca tarih bölümünü çıkarın. Ardından, ilk anı almak için saat dilimini geçin.

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

UTC'ye ayarlayın

UTC'ye geri dönmeniz gerekiyorsa, bir Instant.

Instant instant = zdtFirstMomentOfDay.toInstant() ;

InstantDate

java.util.DateHenüz java.time olarak güncellenmemiş eski kodla birlikte çalışmanız gerekiyorsa ,.

java.util.Date d = java.util.Date.from( instant ) ;

1

Bunu yapmak daha kolay olabilir (Java 8'de)

LocalTime.ofNanoOfDay(0)

Teşekkürler, son 2 yılda başka şeylerle ve ondan önce Java 6/7 ile çalıştım. Şimdi Java'ya geri döndüm (Groovy'de birkaç şeyle çalıştıktan sonra) ve Java 8 farklılıklarını sevdim.
meszias

1

Java 8 / Joda-datetime api LocalDate sınıfını kullanarak java.util.Date zaman bölümünü 00:00:00 olarak ayarlayabiliriz :

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

Dize olarak 00:00:00 biçimine ihtiyacınız varsa, aşağıdaki gibi SimpleDateFormat kullanmalısınız. "H" yerine "H" kullanılması.

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

Bunu yapmanın başka bir yolu da DateFormat'ı saniye olmadan kullanmaktır:

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

Bunu aşağıdakilerle yapabilirsiniz:

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

0

Java8 yeni Tarih fonksiyonları eklediğinden bunu kolaylıkla yapabiliriz.


    // 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


LocalDateTimeHerhangi bir zaman dilimi kavramı veya UTC'den uzaklıktan yoksun olduğu için bir anı temsil edemez. Telefon etmek LocalDateTime.nowneredeyse hiç mantıklı değil. Bunun ZonedDateTimeyerine kullanmalısın.
Basil Bourque
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.