简体   繁体   English

将时间设置为 00:00:00

[英]Set time to 00:00:00

I have a problem resetting hours in Java.我在用 Java 重置小时数时遇到问题。 For a given date I want to set the hours to 00:00:00.对于给定的日期,我想将小时数设置为 00:00:00。

This is my code :这是我的代码:

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

The problem is that sometimes the time is 12:00:00 and sometimes it is 00:00:00 and when I query the database for an entity that was saved on 07.02.2013 00:00:00 and the actual entity time, that is stored, is 12:00:00 the query fails.问题是,有时时间是12:00:00 ,有时是00:00:00 ,当我查询数据库以查找保存在07.02.2013 00:00:00和实际实体时间的实体时,存储,是12:00:00查询失败。

I know that 12:00:00 == 00:00:00 !我知道12:00:00 == 00:00:00

I am using AppEngine.我正在使用 AppEngine。 Is this an appengine bug, problem or some other issue?这是 appengine 错误、问题还是其他问题? Or does it depend on something else?还是取决于其他什么?

Use another constant instead of Calendar.HOUR , use Calendar.HOUR_OF_DAY .使用另一个常量而不是Calendar.HOUR ,使用Calendar.HOUR_OF_DAY

calendar.set(Calendar.HOUR_OF_DAY, 0);

Calendar.HOUR uses 0-11 (for use with AM/PM), and Calendar.HOUR_OF_DAY uses 0-23. Calendar.HOUR使用 0-11(用于 AM/PM),而Calendar.HOUR_OF_DAY使用 0-23。

To quote the Javadocs:引用 Javadocs:

public static final int HOUR public static final int HOUR

Field number for get and set indicating the hour of the morning or afternoon. get 和 set 的字段编号,指示上午或下午的小时数。 HOUR is used for the 12-hour clock (0 - 11). HOUR 用于 12 小时制 (0 - 11)。 Noon and midnight are represented by 0, not by 12. Eg, at 10:04:15.250 PM the HOUR is 10.中午和午夜由 0 表示,而不是 12。例如,在 10:04:15.250 PM,HOUR 是 10。

and

public static final int HOUR_OF_DAY public static final int HOUR_OF_DAY

Field number for get and set indicating the hour of the day. get 和 set 的字段编号指示一天中的小时。 HOUR_OF_DAY is used for the 24-hour clock. HOUR_OF_DAY 用于 24 小时制。 Eg, at 10:04:15.250 PM the HOUR_OF_DAY is 22.例如,在晚上 10:04:15.250,HOUR_OF_DAY 是 22。

Testing ("now" is currently c. 14:55 on July 23, 2013 Pacific Daylight Time):测试(“现在”目前是太平洋夏令时间 2013 年 7 月 23 日 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()));
    }
}

Output:输出:

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

java.time时间

Using the java.time framework built into Java 8 and later.使用内置于 Java 8 及更高版本中的java.time框架。 See Tutorial .请参阅教程

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

If you do not need time-of-day (hour, minute, second etc. parts) consider using LocalDate class.如果您不需要时间(小时、分钟、秒等部分),请考虑使用LocalDate类。

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

Here are couple of utility functions I use to do just this.以下是我用来执行此操作的几个实用函数。

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

One more JAVA 8 way:另一种JAVA 8方式:

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

But it's a lot more useful to edit the date that already exists.但是编辑已经存在的日期要有用得多。

You would better to primarily set time zone to the DateFormat component like this:您最好将时区主要设置为 DateFormat 组件,如下所示:

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

Then you can get "00:00:00" time by passing 0 milliseconds to formatter:然后你可以通过将 0 毫秒传递给格式化程序来获得“00:00:00”时间:

String time = dateFormat.format(0);

or you can create Date object:或者您可以创建 Date 对象:

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

or you be able to have more possibilities using Calendar component but you should also set timezone as GMT to calendar instance:或者您可以使用 Calendar 组件获得更多可能性,但您还应该将时区设置为 GMT 到日历实例:

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

tl;dr tl;博士

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时间

You are using terrible old date-time classes that were supplanted years ago by the modern java.time classes defined in JSR 310.您正在使用多年前被 JSR 310 中定义的现代java.time类取代的糟糕的旧日期时间类。

DateInstant DateInstant

A java.util.Date represent a moment in UTC. java.util.Date代表 UTC java.util.Date一个时刻。 Its replacement is Instant .它的替代品是Instant Call the new conversion methods added to the old classes.调用添加到旧类的新转换方法。

Instant instant = myJavaUtilDate.toInstant() ;

Time zone时区

Specify the time zone in which you want your new time-of-day to make sense.指定您希望新的一天中的时间有意义的时区。

Specify a proper time zone name in the format of Continent/Region , such as America/Montreal , Africa/Casablanca , or Pacific/Auckland .Continent/Region格式指定正确的时区名称,例如America/MontrealAfrica/CasablancaPacific/Auckland Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).永远不要使用ESTIST等 2-4 个字母的缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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

ZonedDateTime

Apply the ZoneId to the Instant to get a ZonedDateTime .ZoneId应用于Instant以获取ZonedDateTime Same moment, same point on the timeline, but different wall-clock time.同一时刻,时间线上的同一点,但挂钟时间不同。

ZonedDateTime zdt = instant.atZone( z ) ;

Changing time-of-day更改时间

You asked to change the time-of-day.您要求更改一天中的时间。 Apply a LocalTime to change all the time-of-day parts: hour, minute, second, fractional second.应用LocalTime来更改所有时间部分:小时、分钟、秒、小数秒。 A new ZonedDateTime is instantiated, with values based on the original.一个新的ZonedDateTime被实例化,其值基于原始值。 The java.time classes use this immutable objects pattern to provide thread-safety . java.time类使用这种不可变对象模式来提供线程安全

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

First moment of day一天的第一刻

But you asked specifically for 00:00.但是您专门询问了 00:00。 So apparently you want the first moment of the day.所以显然你想要一天中的第一刻。 Beware: some days in some zones do not start at 00:00:00.注意:某些区域的某些日子不是从 00:00:00 开始的。 They may start at another time such as 01:00:00 because of anomalies such as Daylight Saving Time (DST).由于夏令时 (DST) 等异常情况,它们可能会在其他时间开始,例如 01:00:00。

Let java.time determine the first moment.java.time确定第一时刻。 Extract the date-only portion.提取仅日期部分。 Then pass the time zone to get first moment.然后通过时区以获得第一时刻。

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

Adjust to UTC调整为 UTC

If you need to go back to UTC, extract an Instant .如果您需要返回 UTC,请提取Instant

Instant instant = zdtFirstMomentOfDay.toInstant() ;

InstantDate InstantDate

If you need a java.util.Date to interoperate with old code not yet updated to java.time , convert.如果您需要java.util.Date与尚未更新为java.time 的旧代码进行互操作,请转换。

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

这样做可能更容易(在 Java 8 中)

LocalTime.ofNanoOfDay(0)

As Java8 add new Date functions, we can do this easily.由于 Java8 添加了新的 Date 函数,我们可以很容易地做到这一点。


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


Another simple way,另一个简单的方法,

final Calendar today = Calendar.getInstance();
        today.setTime(new Date());
        today.clear(Calendar.HOUR_OF_DAY);
        today.clear(Calendar.HOUR);
        today.clear(Calendar.MINUTE);
        today.clear(Calendar.SECOND);
        today.clear(Calendar.MILLISECOND);

See the below code:请参阅以下代码:

    String datePattern24Hrs = "yyyy-MM-dd HH:mm:ss";
    String datePattern12Hrs = "yyyy-MM-dd hh:mm:ss";

    SimpleDateFormat simpleDateFormat24Hrs = new SimpleDateFormat(datePattern24Hrs);
    SimpleDateFormat simpleDateFormat12Hrs = new SimpleDateFormat(datePattern12Hrs);

    Date dateNow = new Date();
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(dateNow);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    Date dateTime = calendar.getTime();

    String dateTimeIn24Hrs = simpleDateFormat24Hrs.format(dateTime);
    String dateTimeIn12Hrs = simpleDateFormat12Hrs.format(dateTime);

    System.out.println("DateTime in 24Hrs: ".concat(dateTimeIn24Hrs));
    System.out.println("DateTime in 12Hrs: ".concat(dateTimeIn12Hrs));

The expected output is as below:预期输出如下:

  • DateTime in 24Hrs: 2021-06-29 00:00:00 24 小时内的日期时间:2021-06-29 00:00:00
  • DateTime in 12Hrs: 2021-06-29 12:00:00 12 小时内的日期时间:2021-06-29 12:00:00

I hope it helps with the answer you are looking for.我希望它对您正在寻找的答案有所帮助。

Another way to do this would be to use a DateFormat without any seconds:另一种方法是使用没有任何秒数的 DateFormat:

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

You can either do this with the following:您可以使用以下方法执行此操作:

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

We can set java.util.Date time part to 00:00:00 By using LocalDate class of Java 8/Joda-datetime api :我们可以将java.util.Date时间部分设置为00:00:00通过使用Java 8/Joda-datetime api 的LocalDate 类:

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

If you need format 00:00:00 in string, you should use SimpleDateFormat as below.如果您需要在字符串中格式化 00:00:00,您应该使用 SimpleDateFormat,如下所示。 Using "H "instead "h".使用“H”代替“h”。

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

Before Java 8:在 Java 8 之前:

Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);

After Java 8:在 Java 8 之后:

LocalDateTime.now().with(LocalTime.of(0, 0, 0))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM