今天在Java中的日期 - 我已经尝试了常规方法

时间:2009-05-06 13:19:20

标签: java date

我需要今天的日期 - 零其他任何东西(“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);

但这是一个蹩脚的代码,我无法自己写出来。

还有其他选择吗?

谢谢!

11 个答案:

答案 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.time

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,它真正代表特定时区中的日期或时间或日期时间。您可以根据自己的具体要求从以下选项中进行选择:

  1. 如果您正在寻找表示 a date without a timezone 的类型,您可以使用 LocalDate.now。好消息是它的变体 LocalDate#now(ZoneId) 从指定时区的系统时钟返回当前日期。
  2. 如果您要查找的对象表示没有时区的日期,并且时间单位设置为零,您可以对使用 Option#1 获得的对象调用 LocalDate#atStartOfDay
  3. 如果您正在寻找表示使用 Option#2 获得的日期-时间对象的 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]

ONLINE DEMO

输出中的 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 desugaringHow 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.MINUTECalendar.SECONDCalendar.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的新日期时间库。