web-dev-qa-db-ja.com

Javaで時間なしで日付を取得するにはどうすればよいですか?

スタックオーバーフローの質問からの続き タイムスタンプなしで現在の日付を取得するJavaプログラム

時間なしでDateオブジェクトを取得する最も効率的な方法は何ですか?これら2つ以外の方法はありますか?

// Method 1
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dateWithoutTime = sdf.parse(sdf.format(new Date()));

// Method 2
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
dateWithoutTime = cal.getTime();

更新

  1. Joda-Time ;について知っていました私はそのような単純な(私が思うに)タスクのために追加のライブラリを避けようとしています。しかし、これまでの回答に基づいて、Joda-Timeは非常に人気があるように思えるので、検討するかもしれません。

  2. efficientとは、method 1で使用される一時オブジェクトStringの作成を避けたいことを意味します。一方、method 2は、解決策。

219
Rosdi Kasim

あなたは絶対にJava.util.Dateを使うべきがありますか?私は徹底的に代わりに Joda Time またはJava 8のJava.timeパッケージを使用することをお勧めします。特に、DateとCalendarは常には特定の瞬間を表しますが、 "単なる日付"などの概念はありませんが、Joda Timeこれを表す型を持っています(LocalDate)。あなたが実際にやろうとしていることを表す型を使うことができれば、あなたのコードはずっと明確になるでしょう。

組み込みのJava.time型の代わりにJoda TimeやJava.utilを使う理由は他にもたくさんあります - それらは一般的にはるかに優れたAPIです。必要ならば、あなた自身のコードの境界でいつでもJava.util.Dateに/から変換することができます。データベースインタラクション用。

103
Jon Skeet

今日の日付を00:00:00に設定したものです。

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");

Date today = new Date();

Date todayWithZeroTime = formatter.parse(formatter.format(today));
59
Shobbi

Apache Commonsライブラリの DateUtils.truncate を使用できます。

例:

DateUtils.truncate(new Date(), Java.util.Calendar.DAY_OF_MONTH)
52
JoGo

この2つ以外の方法はありますか?

はいあります。

LocalDate.now( 
    ZoneId.of( "Pacific/Auckland" ) 
)

Java.time

Java 8以降には、新しい Java.timeパッケージ が組み込まれています。 チュートリアル を参照してください。 Java.timeの機能の多くは、 ThreeTen-Backport でJava 6と7にバックポートされ、さらに ThreeTenABP でAndroidに適応されています。

Joda-Time と同様に、Java.timeは LocalDatename__ クラスを提供して、時刻なしおよびタイムゾーンなしの日付のみの値を表します。

タイムゾーンは特定の日付を決定するのに重要です。たとえば、パリの真夜中になると、モントリオールの日付はまだ「昨日」です。

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;

デフォルトでは、Java.timeは ISO 8601 標準を使用して、日付または日時値のストリング表現を生成します。 (Joda-Timeとのもう1つの類似点です。)2015-05-21のようなテキストを生成するには、単純に toString() を呼び出します。

String output = today.toString() ; 

Java.timeについて

Java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、 Java.util.DateCalendarname__ 、& SimpleDateFormatname__ などの厄介な古い レガシー 日時クラスに代わるものです。

Joda-Time プロジェクトは メンテナンスモード になり、 Java.time クラスへの移行を推奨します。

詳細については、 Oracleチュートリアル を参照してください。そして多くの例と説明についてはStack Overflowを検索してください。指定は JSR 310 です。

Java.timeクラスはどこで入手できますか?

  • Java SE 8Java SE 9 、およびそれ以降
    • ビルトイン。
    • バンドル実装の標準Java APIの一部。
    • Java 9では、いくつかのマイナーな機能と修正が追加されています。
  • Java SE 6 および Java SE 7
    • Java.time機能の多くは、 ThreeTen-Backport でJava 6および7にバックポートされています。
  • Android
    • Java.timeクラスのAndroidバンドル実装の最新バージョン。
    • 以前のAndroidでは、 ThreeTenABP プロジェクトに適応していますThreeTen-Backport(前述) 。 ThreeTenABPの使い方… を参照してください。

ThreeTen-Extra プロジェクトは、追加クラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明するものです。 Intervalname__YearWeekname__YearQuartername__more など、便利なクラスがいくつかあります。

32
Basil Bourque

最も簡単な方法:

long millisInDay = 60 * 60 * 24 * 1000;
long currentTime = new Date().getTime();
long dateOnly = (currentTime / millisInDay) * millisInDay;
Date clearDate = new Date(dateOnly);
22
Roman

これらの質問に対する標準的な答えは、 Joda Time を使用することです。 APIが優れていて、フォーマッタやパーサを使用している場合は、SimpleDateFormatのスレッドセーフ性の直感的でない欠如を回避できます。

Jodaを使うということは、単純にできることを意味します。

LocalDate d = new LocalDate();

Update ::Java 8を使うとこれを実現できます

LocalDate date = LocalDate.now();
21
Brian Agnew

これは簡単な方法です。

Calendar cal = Calendar.getInstance();
SimpleDateFormat dateOnly = new SimpleDateFormat("MM/dd/yyyy");
System.out.println(dateOnly.format(cal.getTime()));
8
Glen

標準のJavaランタイムのDateルーチンに関しては、タイムスタンプなしで日付について話すことは意味がありません。それは本質的に日付ではなく特定のミリ秒にマップされるからです。このミリ秒には本質的に時刻が関連付けられているため、夏時間やその他のカレンダー調整などのタイムゾーンの問題に対して脆弱です。興味深い例として、 これらの2回(1927年)を引いた結果が奇妙な結果になるのはなぜですか?

ミリ秒ではなく日付を使用したい場合は、他のものを使用する必要があります。 Java 8では、あなたが望むものを正確に提供する新しいメソッドのセットがあります。 Java 7以前の場合は http://www.joda.org/joda-time/ を使用してください。

間違いなく最も正確な方法ではありませんが、時間なしで日付を取得するための迅速な解決策が必要で、サードパーティのライブラリを使用したくない場合は、これを実行する必要があります。

    Date db = db.substring(0, 10) + db.substring(23,28);

私は視覚的な目的のためだけに日付を必要とし、Jodaはできなかったので、私は引き締めました。

4
Bamz

あなたが望んでいるのが、他のすべての雑然とせずにそのように "YYYY-MM-DD"のような日付を見ることであるならば。 "Thu May 21 12:08:18 EDT 2015"そしてJava.sql.Dateを使うだけです。この例は現在の日付を取得します。

new Java.sql.Date(System.currentTimeMillis());

またJava.sql.DateJava.util.Dateのサブクラスです。

3
BigMac66
// 09/28/2015
System.out.println(new SimpleDateFormat("MM/dd/yyyy").format(Calendar.getInstance().getTime()));

// Mon Sep 28
System.out.println( new Date().toString().substring(0, 10) );

// 2015-09-28
System.out.println(new Java.sql.Date(System.currentTimeMillis()));

// 2015-09-28
// Java 8
System.out.println( LocalDate.now(ZoneId.of("Europe/Paris")) ); // rest zones id in ZoneId class
3
blueberry0xff

私が知っている限りでは、標準のJDKのみを使用する場合、これを達成する簡単な方法はありません。

もちろん、method2のロジックを、done here toBeginningOfTheDay-method のように、ヘルパークラスの静的関数に入れることができます。

次に、2番目の方法を次のように短縮できます。

Calendar cal = Calendar.getInstance();
Calendars.toBeginningOfTheDay(cal);
dateWithoutTime = cal.getTime();

または、この形式で現在の日付を本当に頻繁に必要とする場合は、別の静的ヘルパーメソッドでそれをまとめて、1日のライナーにすることができます。

3
Enduriel

時間なしで現在の日付だけが必要な場合は、別の選択肢があります。

DateTime.now().withTimeAtStartOfDay()
2
user3037726

以下のようにLocalDate.now()を使用してDateに変換します。

Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
2
Sahil Chhabra

あなたが単にエコー目的のために日付部分を必要とするならば、そして

Date d = new Date(); 
String dateWithoutTime = d.toString().substring(0, 10);
2
manish_s

Veyder-time を調べてください。これは、Java.utilとJoda-timeの両方に代わるシンプルで効率的な方法です。直感的なAPIと、タイムスタンプなしで日付のみを表すクラスがあります。

1
lonerook

これはどうですか?

public static Date formatStrictDate(int year, int month, int dayOfMonth) {
    Calendar calendar = Calendar.getInstance();
    calendar.set(year, month, dayOfMonth, 0, 0, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
}
1

これは、文字列への変換やその逆の変換を行わないクリーンな解決策です。また、時間の各要素をゼロにリセットしても数回は時間を再計算しません。二重演算を避けるために、除算とそれに続く乗算ではなく%(係数)も使用します。

サードパーティの依存関係を必要とせず、渡されたCalenderオブジェクトのタイムゾーンを尊重します。この関数は、渡された日付(カレンダー)のタイムゾーンの午前12時の時刻を返します。

public static Calendar date_only(Calendar datetime) {
    final long LENGTH_OF_DAY = 24*60*60*1000;
    long millis = datetime.getTimeInMillis();
    long offset = datetime.getTimeZone().getOffset(millis);
    millis = millis - ((millis + offset) % LENGTH_OF_DAY);
    datetime.setTimeInMillis(millis);
    return datetime;
}
1
Brent Larsen

巨大なTimeZone Database of Javaをフルに活用した正しい方法です。

long currentTime = new Date().getTime();
long dateOnly = currentTime + TimeZone.getDefault().getOffset(currentTime);
1
TomWolk

あなたはヨーダ時間を使うことができます。

private Date dateWitoutTime(Date date){
 return new LocalDate(date).toDate()
}

そして、あなたはと呼びます:

Date date = new Date();
System.out.println("Without Time = " + dateWitoutTime(date) + "/n  With time = " + date);
0
Jesús Sánchez

私はちょうど私のアプリのためにこれを作りました:

public static Date getDatePart(Date dateTime) {
    TimeZone tz = TimeZone.getDefault();
    long rawOffset=tz.getRawOffset();
    long dst=(tz.inDaylightTime(dateTime)?tz.getDSTSavings():0);
    long dt=dateTime.getTime()+rawOffset+dst; // add offseet and dst to dateTime
    long modDt=dt % (60*60*24*1000) ;

    return new Date( dt
                    - modDt // substract the rest of the division by a day in milliseconds
                    - rawOffset // substract the time offset (Paris = GMT +1h for example)
                    - dst // If dayLight, substract hours (Paris = +1h in dayLight)
    );
}

Android APIレベル1、外部ライブラリなし。夏時間とデフォルトのtimeZoneを尊重します。文字列操作がないので、この方法はあなたよりもCPU効率が良いと思いますが、私はテストをしていません。

0
Elloco

できる限りサードパーティのライブラリを使用しないことをお勧めします。私はこの方法が前に言及されていることを知っています、しかしここでこれはニースのきれいな方法です:

  /*
    Return values:
    -1:    Date1 < Date2
     0:    Date1 == Date2
     1:    Date1 > Date2

    -2:    Error
*/
public int compareDates(Date date1, Date date2)
{
    SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");

    try
    {
        date1 = sdf.parse(sdf.format(date1));
        date2 = sdf.parse(sdf.format(date2));
    }
    catch (ParseException e) {
        e.printStackTrace();
        return -2;
    }

    Calendar cal1 = new GregorianCalendar();
    Calendar cal2 = new GregorianCalendar();

    cal1.setTime(date1);
    cal2.setTime(date2);

    if(cal1.equals(cal2))
    {
        return 0;
    }
    else if(cal1.after(cal2))
    {
        return 1;
    }
    else if(cal1.before(cal2))
    {
        return -1;
    }

    return -2;
}

そうですね、GregorianCalendarを使用しないことはおそらくオプションです。

0
hehe