Java 如何将日期转换为毫秒

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26637168/
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 02:59:26  来源:igfitidea点击:

How to convert a date to milliseconds

javadate

提问by anzure

I want to convert String myDate = "2014/10/29 18:10:45"to long ms (i.e. currentinmlilies)? I look for it on Google, but I can only find how to convert msto date.

我想转换String myDate = "2014/10/29 18:10:45"long ms (i.e. currentinmlilies)? 我在谷歌上寻找它,但我只能找到如何将ms转换为date

Note: To make it clear, I want to get the ms from the date in 1970/1/1 format.

注意:为了清楚起见,我想从 1970/1/1 格式的日期中获取毫秒。

采纳答案by Luiggi Mendoza

You don't have a Date, you have a Stringrepresentation of a date. You should convert the Stringinto a Dateand then obtain the milliseconds. To convert a Stringinto a Dateand vice versa you should use SimpleDateFormatclass.

你没有Date,你有String一个日期的表示。您应该将 the 转换String为 aDate然后获取毫秒。要将 a 转换String为 a Date,反之亦然,您应该使用SimpleDateFormatclass。

Here's an example of what you want/need to do (assuming time zone is not involved here):

这是您想要/需要做什么的示例(假设此处不涉及时区):

String myDate = "2014/10/29 18:10:45";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = sdf.parse(myDate);
long millis = date.getTime();

Still, be careful because in Java the milliseconds obtained are the milliseconds between the desired epoch and 1970-01-01 00:00:00.

不过,要小心,因为在 Java 中获得的毫秒数是所需纪元和 1970-01-01 00:00:00 之间的毫秒数。



Using the new Date/Time API available since Java 8:

使用自 Java 8 起可用的新日期/时间 API:

String myDate = "2014/10/29 18:10:45";
LocalDateTime localDateTime = LocalDateTime.parse(myDate,
    DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss") );
/*
  With this new Date/Time API, when using a date, you need to
  specify the Zone where the date/time will be used. For your case,
  seems that you want/need to use the default zone of your system.
  Check which zone you need to use for specific behaviour e.g.
  CET or America/Lima
*/
long millis = localDateTime
    .atZone(ZoneId.systemDefault())
    .toInstant().toEpochMilli();

回答by allTwentyQuestions

The SimpleDateFormatclass allows you to parse a Stringinto a java.util.Dateobject. Once you have the Date object, you can get the milliseconds since the epoch by calling Date.getTime().

SimpleDateFormat的类可以解析String到一个java.util.Date对象。一旦你有了 Date 对象,你就可以通过调用 获得自纪元以来的毫秒数Date.getTime()

The full example:

完整示例:

String myDate = "2014/10/29 18:10:45";
//creates a formatter that parses the date in the given format
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = sdf.parse(myDate);
long timeInMillis = date.getTime();

Note that this gives you a longand not a double, but I think that's probably what you intended. The documentation for the SimpleDateFormatclass has tons on information on how to set it up to parse different formats.

请注意,这为您提供了一个long而不是双倍,但我认为这可能是您的意图。SimpleDateFormat该类的文档有大量关于如何设置它以解析不同格式的信息。

回答by Basil Bourque

tl;dr

tl;博士

LocalDateTime.parse(           // Parse into an object representing a date with a time-of-day but without time zone and without offset-from-UTC.
    "2014/10/29 18:10:45"      // Convert input string to comply with standard ISO 8601 format.
    .replace( " " , "T" )      // Replace SPACE in the middle with a `T`.
    .replace( "/" , "-" )      // Replace SLASH in the middle with a `-`.
)
.atZone(                       // Apply a time zone to provide the context needed to determine an actual moment.
    ZoneId.of( "Europe/Oslo" ) // Specify the time zone you are certain was intended for that input.
)                              // Returns a `ZonedDateTime` object.
.toInstant()                   // Adjust into UTC.
.toEpochMilli()                // Get the number of milliseconds since first moment of 1970 in UTC, 1970-01-01T00:00Z.

1414602645000

1414602645000

Time Zone

时区

The accepted answer is correct, except that it ignores the crucial issue of time zone. Is your input string 6:10 PM in Paris or Montréal? Or UTC?

接受的答案是正确的,只是它忽略了time zone关键问题。您的输入字符串是在巴黎还是蒙特利尔下午 6:10?还是UTC

Use a proper time zone name. Usually a continent plus city/region. For example, "Europe/Oslo". Avoid the 3 or 4 letter codes which are neither standardized nor unique.

使用正确的时区名称。通常是一个大陆加城市/地区。例如,"Europe/Oslo"。避免使用既不标准化也不唯一的 3 或 4 个字母代码。

java.time

时间

The modern approach uses the java.timeclasses.

现代方法使用java.time类。

Alter your input to conform with the ISO 8601standard. Replace the SPACE in the middle with a T. And replace the slash characters with hyphens. The java.timeclasses use these standard formats by default when parsing/generating strings. So no need to specify a formatting pattern.

更改您的输入以符合ISO 8601标准。将中间的 SPACE 替换为T. 并用连字符替换斜线字符。所述java.time类解析/生成字符串时默认使用这些标准格式。所以不需要指定格式模式。

String input = "2014/10/29 18:10:45".replace( " " , "T" ).replace( "/" , "-" ) ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;

A LocalDateTime, like your input string, lacks any concept of time zone or offset-from-UTC. Without the context of a zone/offset, a LocalDateTimehas no real meaning. Is it 6:10 PM in India, Europe, or Canada? Each of those places experience 6:10 PM at different moments, at different points on the timeline. So you must specify which you have in mind if you want to determine a specific point on the timeline.

A LocalDateTime,就像您的输入字符串一样,缺少任何时区或UTC偏移量的概念。如果没有区域/偏移量的上下文,aLocalDateTime没有实际意义。印度、欧洲或加拿大是下午 6 点 10 分吗?这些地方中的每一个都会在不同时刻、时间线上的不同点经历下午 6:10。因此,如果您想确定时间线上的特定点,则必须指定您想到的是哪一个。

ZoneId z = ZoneId.of( "Europe/Oslo" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;  

Now we have a specific moment, in that ZonedDateTime. Convert to UTC by extracting a Instant. The Instantclass represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).

现在我们有一个特定的时刻,在那个ZonedDateTime. 通过提取Instant. 该Instant级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。

Instant instant = zdt.toInstant() ;

Now we can get your desired count of milliseconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z.

现在我们可以得到您想要的自 UTC 时间 1970 年第一时刻纪元参考以来的毫秒数,1970-01-01T00:00Z。

long millisSinceEpoch = instant.toEpochMilli() ; 

Be aware of possible data loss. The Instantobject is capable of carrying microseconds or nanoseconds, finer than milliseconds. That finer fractional part of a second will be ignored when getting a count of milliseconds.

请注意可能的数据丢失。该Instant物体能够携带微秒或纳秒,比毫秒更精细。在获取毫秒计数时,将忽略更精细的秒小数部分。



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

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

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

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

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.

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

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多



Joda-Time

乔达时间

Update:The Joda-Timeproject is now in maintenance mode, with the team advising migration to the java.timeclasses. I will leave this section intact for history.

更新:乔达时间的项目现在处于维护模式,与团队的建议迁移java.time类。我将保留这一部分完整的历史。

Below is the same kind of code but using the Joda-Time2.5 library and handling time zone.

下面是相同类型的代码,但使用Joda-Time2.5 库和处理时区。

The java.util.Date, .Calendar, and .SimpleDateFormat classes are notoriously troublesome, confusing, and flawed. Avoid them. Use either Joda-Time or the java.time package (inspired by Joda-Time) built into Java 8.

java.util.Date、.Calendar 和 .SimpleDateFormat 类是出了名的麻烦、混乱和有缺陷。避开它们。使用 Joda-Time 或 Java 8 中内置的 java.time 包(受 Joda-Time 启发)。

ISO 8601

ISO 8601

Your string is almost in ISO 8601 format. The slashes need to be hyphens and the SPACE in middle should be replaced with a T. If we tweak that, then the resulting string can be fed directly into constructor without bothering to specify a formatter. Joda-Time uses ISO 8701 formats as it's defaults for parsing and generating strings.

您的字符串几乎采用 ISO 8601 格式。斜线需要是连字符,中间的空格应该替换为T. 如果我们调整它,那么结果字符串可以直接输入构造函数,而无需指定格式化程序。Joda-Time 使用 ISO 8701 格式作为解析和生成字符串的默认格式。

Example Code

示例代码

String inputRaw = "2014/10/29 18:10:45";
String input = inputRaw.replace( "/", "-" ).replace( " ", "T" );
DateTimeZone zone = DateTimeZone.forID( "Europe/Oslo" ); // Or DateTimeZone.UTC
DateTime dateTime = new DateTime( input, zone );
long millisecondsSinceUnixEpoch = dateTime.getMillis();

回答by Ole V.V.

The 2017 answer is: Use the date and time classes introduced in Java 8 (and also backported to Java 6 and 7 in the ThreeTen Backport).

2017 年的答案是:使用 Java 8 中引入的日期和时间类(并且也在ThreeTen Backport 中向后移植到 Java 6 和 7 )。

If you want to interpret the date-time string in the computer's time zone:

如果要解释计算机时区中的日期时间字符串:

    long millisSinceEpoch = LocalDateTime.parse(myDate, DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"))
            .atZone(ZoneId.systemDefault())
            .toInstant()
            .toEpochMilli();

If another time zone, fill that zone in instead of ZoneId.systemDefault(). If UTC, use

如果是其他时区,请填写该时区而不是ZoneId.systemDefault()。如果是 UTC,请使用

    long millisSinceEpoch = LocalDateTime.parse(myDate, DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"))
            .atOffset(ZoneOffset.UTC)
            .toInstant()
            .toEpochMilli();