Date.getTime() 不包括时间?

发布于 2024-07-04 17:44:12 字数 554 浏览 7 评论 0 原文

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

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?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

娇纵 2024-07-11 17:44:12
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);
    }
}
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);
    }
}
别理我 2024-07-11 17:44:12

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

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

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

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

惟欲睡 2024-07-11 17:44:12

Date 对象的 toString() 不会显示毫秒...但它们在那里

所以 new Date() 是一个具有毫秒分辨率的对象,如下所示:

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

但是,当您使用 SimpleDateFormat 构造日期时,没有毫秒传递给它

我在这里错过了这个问题吗?

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

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

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

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

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

Am I missing the question here?

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

随波逐流 2024-07-11 17:44:12

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

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

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.

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.

↙温凉少女 2024-07-11 17:44:12

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

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

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);
百变从容 2024-07-11 17:44:12

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

另一方面,当您为 Date 对象分配一个包含毫秒的值时(在本例中,使用 new Date()),Date 对象确实会保留毫秒。 因此,当您打印它们时,它也包含毫秒。

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.

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.

二货你真萌 2024-07-11 17:44:12

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

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

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.

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

萌无敌 2024-07-11 17:44:12

tl;dr

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

使用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

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

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

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

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

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

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

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

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

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

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

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

接下来,我们要查询自 UTC 1970 年第一个时刻以来的毫秒数。 有了 OffsetDateTimeZonedDateTime 对象,通过调用 toInstant 提取 Instant

Instant instant = odt.toInstant() ;

…或者…

Instant instant = zdt.toInstant() ;

现在获取毫秒数。

long millisecondsSinceEpoch = instant.toEpochMilli() ;

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


表格Java 中的日期时间类型(现代和传统)


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date, 日历, & SimpleDateFormat

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

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

您可以直接与数据库交换java.time对象。 使用符合 JDBC 驱动程序 /jeps/170" rel="nofollow noreferrer">JDBC 4.2 或更高版本。 不需要字符串,不需要 java.sql.* 类。 Hibernate 5 和 Hibernate 5 JPA 2.2 支持 java.time。

从哪里获取 java.time 类?

tl;dr

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

Use 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.time classes defined in JSR 310 that years ago supplanted the terrible classes you are using.

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

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

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

If your input was intended to represent a date and time in UTC, use OffsetDateTime with ZoneOffset.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.

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 OffsetDateTime or ZonedDateTime object in hand, extract a Instant by calling 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.


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


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as 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.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

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

Where to obtain the java.time classes?

混吃等死 2024-07-11 17:44:12

DategetTime() 方法返回自 1970 年 1 月 1 日以来的毫秒数(该日期称为“纪元”,因为所有计算机日期都基于该日期)。 它用于显示您的日期的人类可读版本。

请改用 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

The getTime() method of Date returns 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 not be used to display a human-readable version of your Date.

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文