我需要今天的日期 - 零其他任何东西(“05/06/08 00:00:00”)
我试过
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR, 0);
Date date1 = calendar.getTime();
System.out.println(date1);
运行:(这严重搞砸了)
如果计算机上的小时数是<中午12点:太阳3月08日00:44:39 IST 2009
如果计算机上的小时是>中午12点:太阳3月08日12:46:53 IST 2009
所以我放弃了。
所有Date的setter都已弃用(纪元时间除外) - 所以我不想使用它们
我唯一能想到的是
Calendar calendar = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
String sDate = dateFormat.format(calendar.getTime());
Date today = dateFormat.parse(sDate);
但这是一个蹩脚的代码,我无法自己写出来。
还有其他选择吗?
谢谢!
答案 0 :(得分:25)
我用这个:
public static Date startOfDay(Date date) {
Calendar dCal = Calendar.getInstance();
dCal.setTime(date);
dCal.set(Calendar.HOUR_OF_DAY, 0);
dCal.set(Calendar.MINUTE, 0);
dCal.set(Calendar.SECOND, 0);
dCal.set(Calendar.MILLISECOND, 0);
return dCal.getTime();
}
答案 1 :(得分:18)
我对Java日期/时间问题的标准建议:不要使用java.util.{Calendar,Date}
。使用Joda Time。这样,您可以将日期表示为date(没有关联的时区),而不是日期/时间。或者您可以使用DateMidnight
,如果这是您想要表示的。 (注意时区和日期的组合 没有午夜但是......)
使用Date
需要什么?如果你可以随时改变使用Joda,那就太好了。否则,您可以使用Joda执行您想要的操作,然后在需要时转换为毫秒(然后转换为java.util.Date
)。
(迈克尔在使用Date
/ Calendar
时的解决方案很好,如果你真的想要坚持一个破碎的API ......但我不能夸大Joda是多么好......)< / p>
答案 2 :(得分:10)
您应该使用HOUR_OF_DAY代替HOUR,并将其与MINUTE和SECOND结合使用。
import java.util.Calendar;
import static java.util.Calendar.HOUR_OF_DAY;
import static java.util.Calendar.MINUTE;
import static java.util.Calendar.SECOND;
import static java.util.Calendar.MILLISECOND;
public class Today {
public static void main( String [] args ) {
Calendar cal = Calendar.getInstance();
cal.set( HOUR_OF_DAY, 0 );
cal.set( MINUTE, 0 );
cal.set( SECOND, 0 );
cal.set( MILLISECOND, 0 );
System.out.println( cal.getTime() );
}
}
您获得的结果是由于HOUR用于AM / PM而HOUR_OF_DAY为24小时。
<强> HOUR_OF_DAY:强>
获取和设置的字段编号,表示当天的小时。 HOUR_OF_DAY用于24小时制。例如,在下午10:04:15.250,HOUR_OF_DAY是22。
<强> HOUR:强>
获取和设置的字段编号,表示上午或下午的小时。小时用于12小时制(0 - 11)。中午和午夜由0表示,而不是12表示。例如,在10:04:15.250 PM,HOUR为10。
答案 3 :(得分:9)
时间组件不仅仅是几小时(正如您所注意到的那样,Calendar.HOUR是AM / PM)。 您需要将时间字段的所有设置为0:HOUR_OF_DAY,MINUTE,SECOND,MILLISECOND。
答案 4 :(得分:4)
请参阅Apache's commons-lang DateUtils.truncate()
答案 5 :(得分:2)
java.util
日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*。
另外,下面引用的是来自 home page of Joda-Time 的通知:
<块引用>请注意,从 Java SE 8 开始,要求用户迁移到 java.time (JSR-310) - JDK 的核心部分,取代了该项目。
使用 java.time
(现代日期时间 API)的解决方案:
现代日期时间 API 具有 many types,它真正代表特定时区中的日期或时间或日期时间。您可以根据自己的具体要求从以下选项中进行选择:
LocalDate.now
。好消息是它的变体 LocalDate#now(ZoneId)
从指定时区的系统时钟返回当前日期。LocalDate#atStartOfDay
。 Instant
,您可以使用 LocalDateTime#atZone
将此对象与 ZoneId.of("Etc/UTC")
附加获取 ZonedDateTime
并使用 ZonedDateTime#toInstant
将其转换为 Instant
。演示:
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
LocalDate todayInSystemTz = LocalDate.now();
System.out.println(todayInSystemTz);
LocalDate todayInIndia = LocalDate.now(ZoneId.of("Asia/Kolkata"));
System.out.println(todayInIndia);
LocalDateTime todayInSystemTzWithZeroTimeUnits = todayInSystemTz.atStartOfDay();
System.out.println(todayInSystemTzWithZeroTimeUnits);
ZonedDateTime todayInUtcWithZeroTimeUnits = todayInSystemTzWithZeroTimeUnits.atZone(ZoneId.of("Etc/UTC"));
System.out.println(todayInUtcWithZeroTimeUnits);
Instant instant = todayInUtcWithZeroTimeUnits.toInstant();
System.out.println(instant);
// Can I represent the obtained Instant in India?
System.out.println(instant.atZone(ZoneId.of("Asia/Kolkata")));
// Can I represent the obtained Instant in New York?
System.out.println(instant.atZone(ZoneId.of("America/New_York")));
}
}
输出:
2021-06-20
2021-06-20
2021-06-20T00:00
2021-06-20T00:00Z[Etc/UTC]
2021-06-20T00:00:00Z
2021-06-20T05:30+05:30[Asia/Kolkata]
2021-06-19T20:00-04:00[America/New_York]
输出中的 Z
是零时区偏移的 timezone designator。它代表祖鲁语并指定 Etc/UTC
时区(时区偏移为 +00:00
小时)。
出于任何原因,如果您需要将 Instant
的这个对象转换为 java.util.Date
** 的对象,您可以这样做:
Date date = Date.from(instant);
从 Trail: Date Time 了解有关现代 Date-Time API 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。
**
java.util.Date
对象仅表示自称为“纪元”的标准基准时间(即 1970 年 1 月 1 日 00:00:00)以来经过的毫秒数GMT(或UTC)。由于它不保存任何时区信息,它的 toString
函数应用 JVM 的时区返回一个 String
格式,EEE MMM dd HH:mm:ss zzz yyyy
,从这个 毫秒值。要以不同的格式和时区获取 String
对象的 java.util.Date
表示,您需要将 SimpleDateFormat
与所需格式和适用时区一起使用,例如
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String strDateNewYork = sdf.format(date);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDateUtc = sdf.format(date);
答案 6 :(得分:1)
如上所述,您应该使用
Calendar.HOUR_OF_DAY
与
相反Calendar.HOUR
此外,您需要清除其他字段(Calendar.MINUTE
,Calendar.SECOND
和Calendar.MILLISECOND
),方法是将其设置为零。
对不起,这里没有简单的方法。一个痛苦,这就是为什么他们正在为Java 7开发一个新的API我相信基于Joda Time。
答案 7 :(得分:1)
...或者你可以用黑客的方式做到:
long MS_PER_DAY = 86400000L;
Date dateTime=new Date();
long offset = TimeZone.getDefault().getOffset(dateTime.getTime());
Date date= new Date(((dateTime.getTime()+offset)/MS_PER_DAY)*MS_PER_DAY-offset);
答案 8 :(得分:1)
我知道这是一个非常古老的问题,不再活跃,但当我搜索谷歌时,它就成了最重要的问题。
虽然所有建议都非常好,但我不敢相信没有人回答:
Date date = new Date(System.currentTimeMillis());
System.out.println(date);
有效返回,今天的日期。
答案 9 :(得分:0)
为什么要操作字符串?
在使用getTime()转换为Date之前,你能不能只在Calendar对象上设置所需的值?
答案 10 :(得分:0)
JodaTime的另一次投票。
java.util.Date和Calendar非常糟糕,它们被破坏了。 (而SimpleDateFormat也是垃圾!)
对于它的价值,Java 7将包含一个基于JodaTime的新日期时间库。