スタックオーバーフローの質問からの続き タイムスタンプなしで現在の日付を取得する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();
更新:
Joda-Time ;について知っていました私はそのような単純な(私が思うに)タスクのために追加のライブラリを避けようとしています。しかし、これまでの回答に基づいて、Joda-Timeは非常に人気があるように思えるので、検討するかもしれません。
efficientとは、method 1
で使用される一時オブジェクトString
の作成を避けたいことを意味します。一方、method 2
は、解決策。
あなたは絶対にJava.util.Date
を使うべきがありますか?私は徹底的に代わりに Joda Time またはJava 8のJava.time
パッケージを使用することをお勧めします。特に、DateとCalendarは常には特定の瞬間を表しますが、 "単なる日付"などの概念はありませんが、Joda Timeはこれを表す型を持っています(LocalDate
)。あなたが実際にやろうとしていることを表す型を使うことができれば、あなたのコードはずっと明確になるでしょう。
組み込みのJava.time
型の代わりにJoda TimeやJava.util
を使う理由は他にもたくさんあります - それらは一般的にはるかに優れたAPIです。必要ならば、あなた自身のコードの境界でいつでもJava.util.Date
に/から変換することができます。データベースインタラクション用。
今日の日付を00:00:00
に設定したものです。
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date today = new Date();
Date todayWithZeroTime = formatter.parse(formatter.format(today));
Apache Commonsライブラリの DateUtils.truncate を使用できます。
例:
DateUtils.truncate(new Date(), Java.util.Calendar.DAY_OF_MONTH)
この2つ以外の方法はありますか?
はいあります。
LocalDate.now(
ZoneId.of( "Pacific/Auckland" )
)
Java 8以降には、新しい Java.timeパッケージ が組み込まれています。 チュートリアル を参照してください。 Java.timeの機能の多くは、 ThreeTen-Backport でJava 6と7にバックポートされ、さらに ThreeTenABP でAndroidに適応されています。
Joda-Time と同様に、Java.timeは LocalDate
name__ クラスを提供して、時刻なしおよびタイムゾーンなしの日付のみの値を表します。
タイムゾーンは特定の日付を決定するのに重要です。たとえば、パリの真夜中になると、モントリオールの日付はまだ「昨日」です。
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 8以降に組み込まれています。これらのクラスは、 Java.util.Date
、 Calendar
name__ 、& SimpleDateFormat
name__ などの厄介な古い レガシー 日時クラスに代わるものです。
Joda-Time プロジェクトは メンテナンスモード になり、 Java.time クラスへの移行を推奨します。
詳細については、 Oracleチュートリアル を参照してください。そして多くの例と説明についてはStack Overflowを検索してください。指定は JSR 310 です。
Java.timeクラスはどこで入手できますか?
ThreeTen-Extra プロジェクトは、追加クラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明するものです。 Interval
name__ 、 YearWeek
name__ 、 YearQuarter
name__ 、 more など、便利なクラスがいくつかあります。
最も簡単な方法:
long millisInDay = 60 * 60 * 24 * 1000;
long currentTime = new Date().getTime();
long dateOnly = (currentTime / millisInDay) * millisInDay;
Date clearDate = new Date(dateOnly);
これらの質問に対する標準的な答えは、 Joda Time を使用することです。 APIが優れていて、フォーマッタやパーサを使用している場合は、SimpleDateFormat
のスレッドセーフ性の直感的でない欠如を回避できます。
Jodaを使うということは、単純にできることを意味します。
LocalDate d = new LocalDate();
Update ::Java 8を使うとこれを実現できます
LocalDate date = LocalDate.now();
これは簡単な方法です。
Calendar cal = Calendar.getInstance();
SimpleDateFormat dateOnly = new SimpleDateFormat("MM/dd/yyyy");
System.out.println(dateOnly.format(cal.getTime()));
標準の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はできなかったので、私は引き締めました。
あなたが望んでいるのが、他のすべての雑然とせずにそのように "YYYY-MM-DD"のような日付を見ることであるならば。 "Thu May 21 12:08:18 EDT 2015"そしてJava.sql.Date
を使うだけです。この例は現在の日付を取得します。
new Java.sql.Date(System.currentTimeMillis());
またJava.sql.Date
はJava.util.Date
のサブクラスです。
// 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
私が知っている限りでは、標準のJDKのみを使用する場合、これを達成する簡単な方法はありません。
もちろん、method2のロジックを、done here toBeginningOfTheDay-method のように、ヘルパークラスの静的関数に入れることができます。
次に、2番目の方法を次のように短縮できます。
Calendar cal = Calendar.getInstance();
Calendars.toBeginningOfTheDay(cal);
dateWithoutTime = cal.getTime();
または、この形式で現在の日付を本当に頻繁に必要とする場合は、別の静的ヘルパーメソッドでそれをまとめて、1日のライナーにすることができます。
時間なしで現在の日付だけが必要な場合は、別の選択肢があります。
DateTime.now().withTimeAtStartOfDay()
以下のようにLocalDate.now()
を使用してDate
に変換します。
Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
あなたが単にエコー目的のために日付部分を必要とするならば、そして
Date d = new Date();
String dateWithoutTime = d.toString().substring(0, 10);
Veyder-time を調べてください。これは、Java.utilとJoda-timeの両方に代わるシンプルで効率的な方法です。直感的なAPIと、タイムスタンプなしで日付のみを表すクラスがあります。
これはどうですか?
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();
}
これは、文字列への変換やその逆の変換を行わないクリーンな解決策です。また、時間の各要素をゼロにリセットしても数回は時間を再計算しません。二重演算を避けるために、除算とそれに続く乗算ではなく%
(係数)も使用します。
サードパーティの依存関係を必要とせず、渡された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;
}
巨大なTimeZone Database of Javaをフルに活用した正しい方法です。
long currentTime = new Date().getTime();
long dateOnly = currentTime + TimeZone.getDefault().getOffset(currentTime);
あなたはヨーダ時間を使うことができます。
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);
私はちょうど私のアプリのためにこれを作りました:
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効率が良いと思いますが、私はテストをしていません。
できる限りサードパーティのライブラリを使用しないことをお勧めします。私はこの方法が前に言及されていることを知っています、しかしここでこれはニースのきれいな方法です:
/*
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を使用しないことはおそらくオプションです。