Java Date.getTime() 不包括时间?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/74620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:58:47  来源:igfitidea点击:

Date.getTime() not including time?

javadatetimestampgettime

提问by Jake

Can't understand why the following takes place:

无法理解为什么会发生以下情况:

String date = "06-04-2007 07:05";
SimpleDateFormat fmt = new SimpleDateFormat("MM-dd-yyyy HH:mm");
Date myDate = fmt.parse(date); 

System.out.println(myDate);  //Mon Jun 04 07:05:00 EDT 2007
long timestamp = myDate.getTime();
System.out.println(timestamp); //1180955100000 -- where are the milliseconds?

// on the other hand...

myDate = new Date();
System.out.println(myDate);  //Tue Sep 16 13:02:44 EDT 2008
timestamp = myDate.getTime();
System.out.println(timestamp); //1221584564703 -- why, oh, why?

采纳答案by Vinko Vrsalovic

What milliseconds? You are providing only minutes information in the first example, whereas your second example grabs current date from the system with milliseconds, what is it you're looking for?

几毫秒?您在第一个示例中仅提供分钟信息,而您的第二个示例以毫秒为单位从系统中获取当前日期,您在寻找什么?

String date = "06-04-2007 07:05:00.999";
SimpleDateFormat fmt = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss.S");
Date myDate = fmt.parse(date);

System.out.println(myDate); 
long timestamp = myDate.getTime();
System.out.println(timestamp);

回答by Mostlyharmless

Because simple date format you specified discards the milliseconds. So the resulting Date object does not have that info. So when you print it out, its all 0s.

因为您指定的简单日期格式会丢弃毫秒。因此生成的 Date 对象没有该信息。所以当你打印出来时,它全是 0。

On the other hand, the Date object does retain the milliseconds when you assign it a value with milliseconds (in this case, using new Date()). So when you print them out, it contains the millisecs too.

另一方面,当您为 Date 对象分配一个毫秒值(在这种情况下,使用 new Date())时,它确实保留了毫秒。因此,当您打印它们时,它也包含毫秒。

回答by ScArcher2

When you parse a date it only uses the information you provide. In this case it only knows MM-dd-yyyy HH:mm.

当您解析日期时,它仅使用您提供的信息。在这种情况下,它只知道 MM-dd-yyyy HH:mm。

Creating a new date object returns the current system date/time (number of milliseconds since the epoch).

创建新的日期对象会返回当前系统日期/时间(自纪元以来的毫秒数)。

回答by tim_yates

toString() of a Date object does not show you the milliseconds... But they are there

Date 对象的 toString() 没有显示毫秒数......但它们在那里

So new Date() is an object with milisecond resolution, as can be seen by:

所以 new Date() 是一个具有毫秒分辨率的对象,可以通过以下方式看到:

  System.out.printf( "ms = %d\n", myDate.getTime() % 1000 ) ;

However, when you construct your date with SimpleDateFormat, no milliseconds are passed to it

但是,当您使用 SimpleDateFormat 构造日期时,不会传递任何毫秒数

Am I missing the question here?

我错过了这里的问题吗?

[edit] Hahaha...way too slow ;)

[编辑] 哈哈哈……太慢了;)

回答by laz

Date.getTime returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by the Date object. So "06-04-2007 07:05" - "01-01-1970 00:00" is equal to 1180955340000 milliseconds. Since the only concern of your question is about the time portion of the date, a rough way of thinking of this calculation is the number of milliseconds between 07:05 and 00:00 which is 25500000. This is evenly divisible by 1000 since neither time has any milliseconds.

Date.getTime 返回自 1970 年 1 月 1 日格林威治标准时间 00:00:00 以来由 Date 对象表示的毫秒数。所以 "06-04-2007 07:05" - "01-01-1970 00:00" 等于 1180955340000 毫秒。由于您的问题唯一关心的是日期的时间部分,因此粗略地考虑这个计算是 07:05 和 00:00 之间的毫秒数,即 25500000。这可以被 1000 整除,因为这两个时间都不是有任何毫秒。

In the second date it uses the current time when that line of code is executed. That will use whatever the current milliseconds past the current second are in the calculation. Therefore, Date.getTime will more than likely return a number that is not evenly divisible by 1000.

在第二个日期中,它使用该行代码执行时的当前时间。这将使用计算中超过当前秒的当前毫秒数。因此,Date.getTime 很可能会返回一个不能被 1000 整除的数字。

回答by Michael

The getTime()method of Datereturns the number of milliseconds since January 1, 1970 (this date is called the "epoch" because all computer dates are based off of this date). It should notbe used to display a human-readable version of your Date.

getTime()Date自1970年1月1日的毫秒数(这个日期被称为“划时代”,因为所有的计算机日期此日期基于关闭)。它应该用于显示您的日期的人类可读版本。

Use the SimpleDateFormat.format()method instead. Here is a revised version of part of your code that I think may solve your problem:

请改用该SimpleDateFormat.format()方法。这是您的部分代码的修订版本,我认为可以解决您的问题:

String date = "06-04-2007 07:05:23:123";
SimpleDateFormat fmt = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss:S");
Date myDate = fmt.parse(date); 

System.out.println(myDate);  //Mon Jun 04 07:05:23 EDT 2007
String formattedDate = fmt.format(myDate);
System.out.println(formattedDate); //06-04-2007 07:05:23:123

回答by Ryan Delucchi

Instead of using the Sun JDK Time/Date libraries (which leave much to be desired) I recommend taking a look at http://joda-time.sourceforge.net.

我建议不要使用 Sun JDK 时间/日期库(还有很多不足之处),我建议查看http://joda-time.sourceforge.net

This is a very mature and active sourceforge project and has a very elegant API.

这是一个非常成熟和活跃的 sourceforge 项目,并且拥有非常优雅的 API。

回答by Ryan Delucchi

import java.util.*;

public class Time {
    public static void main(String[] args) {
        Long l = 0L;
        Calendar c = Calendar.getInstance();
        //milli sec part of current time
        l = c.getTimeInMillis() % 1000;  
        //current time without millisec
        StringBuffer sb = new StringBuffer(c.getTime().toString());
        //millisec in string
        String s = ":" + l.toString();
        //insert at right place
        sb.insert(19, s);
        //ENJOY
        System.out.println(sb);
    }
}

回答by Basil Bourque

tl;dr

tl;博士

The accepted Answer by Vinko Vrsalovicis correct. Your input is whole minutes, so the milliseconds for fractional second should indeed be zero.

Vinko Vrsalovic接受的答案是正确的。您的输入是整分钟,因此小数秒的毫秒数确实应该为零。

Use java.time.

使用java.time

LocalDateTime.parse
( 
    "06-04-2007 07:05" , 
    DateTimeFormatter.ofPattern( "MM-dd-uuuu HH:mm" ) 
)
.atZone
(
    ZoneId.of( "Africa/Casablanca" ) 
)
.toInstant()
.getEpochMilli()

java.time

时间

The modern approach uses the java.timeclasses defined in JSR 310 that years ago supplanted the terrible classes you are using.

现代方法使用JSR 310 中定义的java.time类,该类多年前取代了您正在使用的糟糕类。

Define a formatting pattern to match your input. FYI: Learn to use standard ISO 8601 formats for exchanging date-time values as text.

定义格式模式以匹配您的输入。仅供参考:学习使用标准 ISO 8601 格式将日期时间值作为文本进行交换。

String input = "06-04-2007 07:05" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uuuu HH:mm" ) ;

Parse your input as a LocalDateTime, as it lacks an indicator of time zone or offset-from-UTC.

将您的输入解析为LocalDateTime,因为它缺少时区或UTC 偏移量的指示符。

LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

This represents a date and a time-of-day, but lacks the context of a time zone or offset. So we do not know if you meant 7 AM in Tokyo Japan, 7 AM in Toulouse France, or 7 AM in Toledo Ohio US. This issue of time zone is crucial, because your desired count of milliseconds is a count since the first moment of 1970 as seen in UTC (an offset of zero hours-minutes-seconds), 1970-01-01T00:00Z.

这表示日期和时间,但缺少时区或偏移量的上下文。所以我们不知道您是指日本东京早上 7 点、法国图卢兹早上 7 点还是美国俄亥俄州托莱多早上 7 点。这个时区问题至关重要,因为您想要的毫秒数是自 1970 年第一时刻以来的计数,如 UTC(零时分秒的偏移量),1970-01-01T00:00Z。

So we must place your input value, the LocalDateTimeobject, in the context of a time zone or offset.

因此,我们必须将您的输入值(LocalDateTime对象)置于时区或偏移量的上下文中。

If your input was intended to represent a date and time in UTC, use OffsetDateTimewith ZoneOffset.UTC.

如果您的输入旨在表示 UTC 中的日期和时间,请OffsetDateTimeZoneOffset.UTC.

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;  // Do this if your date and time represent a moment as seen in UTC. 

If your input was intended to represent a date and time as seen through the wall-clock time used by the people of a particular region, use ZonedDateTime.

如果您的输入旨在表示通过特定地区人民使用的挂钟时间看到的日期和时间,请使用ZonedDateTime.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

Next we want to interrogate for the count of milliseconds since the epoch of first moment of 1970 in UTC. With either a OffsetDateTimeor ZonedDateTimeobject in hand, extract a Instantby calling toInstant.

接下来,我们要询问自 UTC 时间 1970 年第一个时刻以来的毫秒数。手头有 aOffsetDateTimeZonedDateTimeobject 时,Instant通过调用提取 a toInstant

Instant instant = odt.toInstant() ;

…or…

…或者…

Instant instant = zdt.toInstant() ;

Now get count of milliseconds.

现在获取毫秒数。

long millisecondsSinceEpoch = instant.toEpochMilli() ;

By the way, I suggest you not track time by a count of milliseconds. Use ISO 8601 formatted text instead: easy to parse by machine, easy to read by humans across cultures. A count of milliseconds is neither.

顺便说一句,我建议您不要以毫秒为单位来跟踪时间。改用 ISO 8601 格式的文本:易于机器解析,易于跨文化的人类阅读。毫秒计数既不是。



Table of date-time types in Java, both modern and legacy

Java 中的日期时间类型表,现代和传统



About java.time

关于java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*classes. Hibernate 5 & JPA 2.2 support java.time.

您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。Hibernate 5 & JPA 2.2 支持java.timejava.sql.*

Where to obtain the java.time classes?

从哪里获得 java.time 类?